diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y
index f16fe903432..7b69bf530d4 100644
--- a/src/freedreno/ir3/ir3_parser.y
+++ b/src/freedreno/ir3/ir3_parser.y
@@ -901,8 +901,8 @@ cat0_instr: T_OP_NOP { new_instr(OPC_NOP); }
| T_OP_DBG { new_instr(OPC_DBG); }
| T_OP_SHPS { new_instr(OPC_SHPS); } cat0_immed
| T_OP_SHPE { new_instr(OPC_SHPE); }
-| T_OP_PREDT { new_instr(OPC_PREDT); } cat0_src1
-| T_OP_PREDF { new_instr(OPC_PREDF); } cat0_src1
+| T_OP_PREDT { new_instr(OPC_PREDT); }
+| T_OP_PREDF { new_instr(OPC_PREDF); }
| T_OP_PREDE { new_instr(OPC_PREDE); }
| T_OP_GETLAST '.' T_W { new_instr(OPC_GETLAST); } cat0_immed
diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c
index 63eec55e9d6..0a8ed52d401 100644
--- a/src/freedreno/ir3/tests/disasm.c
+++ b/src/freedreno/ir3/tests/disasm.c
@@ -78,8 +78,8 @@ static const struct test {
INSTR_6XX(00804040_00000003, "braa p0.x, p0.y, #3"),
INSTR_6XX(07820000_00000000, "prede"),
INSTR_6XX(00800063_0000001e, "brac.3 #30"),
- INSTR_6XX(06820000_00000000, "predt p0.x"),
- INSTR_6XX(07020000_00000000, "predf p0.x"),
+ INSTR_6XX(06820000_00000000, "predt"),
+ INSTR_6XX(07020000_00000000, "predf"),
INSTR_6XX(07820000_00000000, "prede"),
/* cat1 */
diff --git a/src/freedreno/isa/ir3-cat0.xml b/src/freedreno/isa/ir3-cat0.xml
index 03bf7f37759..a5e778650db 100644
--- a/src/freedreno/isa/ir3-cat0.xml
+++ b/src/freedreno/isa/ir3-cat0.xml
@@ -110,6 +110,44 @@ SOFTWARE.
1000
+
+
+ The predt, predf, and prede instructions are used to enable
+ "predicated execution" for a region of code. During predicated
+ execution, the execution mask is combined with the "predication
+ mask" to determine the active fibers. So this is similar to
+ branching with the exception that inactive fibers keep executing
+ instead of being parked; the instructions they execute simply
+ have no effect. Since no branch stack is necessary to support
+ predication, it is more performant for divergent branches.
+
+ More concretely, the hardware seems to keep track of a
+ predication mask and a predication mode. The mode can be "none"
+ (no predication, the default, and set by prede), "true" (set by
+ predt), or "false" (set by predf). The final execution mask is
+ determined by and'ing with ~0 (none mode), the predication mask
+ (true mode), or its negation (false mode).
+
+ Predication is enabled by predt or predf which take the value of
+ p0.x of all fibers (not only the active ones) and store them in
+ the predication mask. Then the mode is set to true or false.
+ Executing prede disables predication by setting the mode to
+ none.
+
+ One peculiarity, and the reason the execution mode state is
+ necessary, is that any instruction marked with (jp) will also
+ update the execution mask. The current mode will be kept in that
+ case.
+
+ xx1
+ 1101
+
+
+
+ xx1
+ 1110
+
+
xx1
1111
@@ -136,16 +174,6 @@ SOFTWARE.
0101
-
- xx1
- 1101
-
-
-
- xx1
- 1110
-
-