diff options
author | Eric Anholt <[email protected]> | 2018-01-03 21:42:33 -0800 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2018-01-12 21:53:45 -0800 |
commit | dfee62eed3cacbf77ca3168143be6577849c998d (patch) | |
tree | aa86205704ae035d857f49201b48829c5408c5f7 /src/broadcom/qpu | |
parent | 81ec2ba22975595b4f07c3e8307a8f0a4ec18773 (diff) |
broadcom/vc5: Add support for V3Dv4 signal bits.
The WRTMUC replaces the implicit uniform loads in the first two texture
instructions. LDVPM disappears in favor of an ALU op. LDVARY, LDTMU,
LDTLB, and LDUNIF*RF now write to arbitrary registers, which required
passing the devinfo through to a few more functions.
Diffstat (limited to 'src/broadcom/qpu')
-rw-r--r-- | src/broadcom/qpu/qpu_disasm.c | 53 | ||||
-rw-r--r-- | src/broadcom/qpu/qpu_instr.c | 42 | ||||
-rw-r--r-- | src/broadcom/qpu/qpu_instr.h | 16 | ||||
-rw-r--r-- | src/broadcom/qpu/qpu_pack.c | 126 | ||||
-rw-r--r-- | src/broadcom/qpu/tests/qpu_disasm.c | 7 |
5 files changed, 220 insertions, 24 deletions
diff --git a/src/broadcom/qpu/qpu_disasm.c b/src/broadcom/qpu/qpu_disasm.c index 5ee834852bd..73b43f8c3d6 100644 --- a/src/broadcom/qpu/qpu_disasm.c +++ b/src/broadcom/qpu/qpu_disasm.c @@ -91,7 +91,8 @@ v3d_qpu_disasm_add(struct disasm_state *disasm, int num_src = v3d_qpu_add_op_num_src(instr->alu.add.op); append(disasm, "%s", v3d_qpu_add_op_name(instr->alu.add.op)); - append(disasm, "%s", v3d_qpu_cond_name(instr->flags.ac)); + if (!v3d_qpu_sig_writes_address(disasm->devinfo, &instr->sig)) + append(disasm, "%s", v3d_qpu_cond_name(instr->flags.ac)); append(disasm, "%s", v3d_qpu_pf_name(instr->flags.apf)); append(disasm, "%s", v3d_qpu_uf_name(instr->flags.auf)); @@ -130,7 +131,8 @@ v3d_qpu_disasm_mul(struct disasm_state *disasm, append(disasm, "; "); append(disasm, "%s", v3d_qpu_mul_op_name(instr->alu.mul.op)); - append(disasm, "%s", v3d_qpu_cond_name(instr->flags.mc)); + if (!v3d_qpu_sig_writes_address(disasm->devinfo, &instr->sig)) + append(disasm, "%s", v3d_qpu_cond_name(instr->flags.mc)); append(disasm, "%s", v3d_qpu_pf_name(instr->flags.mpf)); append(disasm, "%s", v3d_qpu_uf_name(instr->flags.muf)); @@ -162,6 +164,24 @@ v3d_qpu_disasm_mul(struct disasm_state *disasm, } static void +v3d_qpu_disasm_sig_addr(struct disasm_state *disasm, + const struct v3d_qpu_instr *instr) +{ + if (disasm->devinfo->ver < 41) + return; + + if (!instr->sig_magic) + append(disasm, ".rf%d", instr->sig_addr); + else { + const char *name = v3d_qpu_magic_waddr_name(instr->sig_addr); + if (name) + append(disasm, ".%s", name); + else + append(disasm, ".UNKNOWN%d", instr->sig_addr); + } +} + +static void v3d_qpu_disasm_sig(struct disasm_state *disasm, const struct v3d_qpu_instr *instr) { @@ -172,6 +192,9 @@ v3d_qpu_disasm_sig(struct disasm_state *disasm, !sig->ldvpm && !sig->ldtmu && !sig->ldunif && + !sig->ldunifrf && + !sig->ldunifa && + !sig->ldunifarf && !sig->wrtmuc) { return; } @@ -180,14 +203,36 @@ v3d_qpu_disasm_sig(struct disasm_state *disasm, if (sig->thrsw) append(disasm, "; thrsw"); - if (sig->ldvary) + if (sig->ldvary) { append(disasm, "; ldvary"); + v3d_qpu_disasm_sig_addr(disasm, instr); + } if (sig->ldvpm) append(disasm, "; ldvpm"); - if (sig->ldtmu) + if (sig->ldtmu) { append(disasm, "; ldtmu"); + v3d_qpu_disasm_sig_addr(disasm, instr); + } + if (sig->ldtlb) { + append(disasm, "; ldtlb"); + v3d_qpu_disasm_sig_addr(disasm, instr); + } + if (sig->ldtlbu) { + append(disasm, "; ldtlbu"); + v3d_qpu_disasm_sig_addr(disasm, instr); + } if (sig->ldunif) append(disasm, "; ldunif"); + if (sig->ldunifrf) { + append(disasm, "; ldunifrf"); + v3d_qpu_disasm_sig_addr(disasm, instr); + } + if (sig->ldunifa) + append(disasm, "; ldunifa"); + if (sig->ldunifarf) { + append(disasm, "; ldunifarf"); + v3d_qpu_disasm_sig_addr(disasm, instr); + } if (sig->wrtmuc) append(disasm, "; wrtmuc"); } diff --git a/src/broadcom/qpu/qpu_instr.c b/src/broadcom/qpu/qpu_instr.c index 7695e0b9358..c07f3802fd4 100644 --- a/src/broadcom/qpu/qpu_instr.c +++ b/src/broadcom/qpu/qpu_instr.c @@ -23,6 +23,7 @@ #include <stdlib.h> #include "util/macros.h" +#include "broadcom/common/v3d_device_info.h" #include "qpu_instr.h" #ifndef QPU_MASK @@ -600,7 +601,8 @@ v3d_qpu_magic_waddr_is_tsy(enum v3d_qpu_waddr waddr) } bool -v3d_qpu_writes_r3(const struct v3d_qpu_instr *inst) +v3d_qpu_writes_r3(const struct v3d_device_info *devinfo, + const struct v3d_qpu_instr *inst) { if (inst->type == V3D_QPU_INSTR_TYPE_ALU) { if (inst->alu.add.magic_write && @@ -614,11 +616,17 @@ v3d_qpu_writes_r3(const struct v3d_qpu_instr *inst) } } + if (v3d_qpu_sig_writes_address(devinfo, &inst->sig) && + inst->sig_magic && inst->sig_addr == V3D_QPU_WADDR_R3) { + return true; + } + return inst->sig.ldvary || inst->sig.ldvpm; } bool -v3d_qpu_writes_r4(const struct v3d_qpu_instr *inst) +v3d_qpu_writes_r4(const struct v3d_device_info *devinfo, + const struct v3d_qpu_instr *inst) { if (inst->sig.ldtmu) return true; @@ -637,11 +645,17 @@ v3d_qpu_writes_r4(const struct v3d_qpu_instr *inst) } } + if (v3d_qpu_sig_writes_address(devinfo, &inst->sig) && + inst->sig_magic && inst->sig_addr == V3D_QPU_WADDR_R4) { + return true; + } + return false; } bool -v3d_qpu_writes_r5(const struct v3d_qpu_instr *inst) +v3d_qpu_writes_r5(const struct v3d_device_info *devinfo, + const struct v3d_qpu_instr *inst) { if (inst->type == V3D_QPU_INSTR_TYPE_ALU) { if (inst->alu.add.magic_write && @@ -655,7 +669,12 @@ v3d_qpu_writes_r5(const struct v3d_qpu_instr *inst) } } - return inst->sig.ldvary || inst->sig.ldunif; + if (v3d_qpu_sig_writes_address(devinfo, &inst->sig) && + inst->sig_magic && inst->sig_addr == V3D_QPU_WADDR_R5) { + return true; + } + + return inst->sig.ldvary || inst->sig.ldunif || inst->sig.ldunifa; } bool @@ -669,3 +688,18 @@ v3d_qpu_uses_mux(const struct v3d_qpu_instr *inst, enum v3d_qpu_mux mux) (mul_nsrc > 0 && inst->alu.mul.a == mux) || (mul_nsrc > 1 && inst->alu.mul.b == mux)); } + +bool +v3d_qpu_sig_writes_address(const struct v3d_device_info *devinfo, + const struct v3d_qpu_sig *sig) +{ + if (devinfo->ver < 41) + return false; + + return (sig->ldunifrf || + sig->ldunifarf || + sig->ldvary || + sig->ldtmu || + sig->ldtlb || + sig->ldtlbu); +} diff --git a/src/broadcom/qpu/qpu_instr.h b/src/broadcom/qpu/qpu_instr.h index a425fae8b25..cab1885acc4 100644 --- a/src/broadcom/qpu/qpu_instr.h +++ b/src/broadcom/qpu/qpu_instr.h @@ -42,6 +42,9 @@ struct v3d_device_info; struct v3d_qpu_sig { bool thrsw:1; bool ldunif:1; + bool ldunifa:1; + bool ldunifrf:1; + bool ldunifarf:1; bool ldtmu:1; bool ldvary:1; bool ldvpm:1; @@ -347,6 +350,8 @@ struct v3d_qpu_instr { enum v3d_qpu_instr_type type; struct v3d_qpu_sig sig; + uint8_t sig_addr; + bool sig_magic; /* If the signal writes to a magic address */ uint8_t raddr_a; uint8_t raddr_b; struct v3d_qpu_flags flags; @@ -403,9 +408,14 @@ bool v3d_qpu_magic_waddr_is_tmu(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST; bool v3d_qpu_magic_waddr_is_tlb(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST; bool v3d_qpu_magic_waddr_is_vpm(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST; bool v3d_qpu_magic_waddr_is_tsy(enum v3d_qpu_waddr waddr) ATTRIBUTE_CONST; -bool v3d_qpu_writes_r3(const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST; -bool v3d_qpu_writes_r4(const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST; -bool v3d_qpu_writes_r5(const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST; +bool v3d_qpu_writes_r3(const struct v3d_device_info *devinfo, + const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST; +bool v3d_qpu_writes_r4(const struct v3d_device_info *devinfo, + const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST; +bool v3d_qpu_writes_r5(const struct v3d_device_info *devinfo, + const struct v3d_qpu_instr *instr) ATTRIBUTE_CONST; bool v3d_qpu_uses_mux(const struct v3d_qpu_instr *inst, enum v3d_qpu_mux mux); +bool v3d_qpu_sig_writes_address(const struct v3d_device_info *devinfo, + const struct v3d_qpu_sig *sig) ATTRIBUTE_CONST; #endif diff --git a/src/broadcom/qpu/qpu_pack.c b/src/broadcom/qpu/qpu_pack.c index 02aa1b86aa4..f9fb016f610 100644 --- a/src/broadcom/qpu/qpu_pack.c +++ b/src/broadcom/qpu/qpu_pack.c @@ -55,11 +55,7 @@ #define VC5_QPU_COND_SHIFT 46 #define VC5_QPU_COND_MASK QPU_MASK(52, 46) - -#define VC5_QPU_COND_IFA 0 -#define VC5_QPU_COND_IFB 1 -#define VC5_QPU_COND_IFNA 2 -#define VC5_QPU_COND_IFNB 3 +#define VC5_QPU_COND_SIG_MAGIC_ADDR (1 << 6) #define VC5_QPU_MM QPU_MASK(45, 45) #define VC5_QPU_MA QPU_MASK(44, 44) @@ -113,6 +109,9 @@ #define THRSW .thrsw = true #define LDUNIF .ldunif = true +#define LDUNIFRF .ldunifrf = true +#define LDUNIFA .ldunifa = true +#define LDUNIFARF .ldunifarf = true #define LDTMU .ldtmu = true #define LDVARY .ldvary = true #define LDVPM .ldvpm = true @@ -156,6 +155,67 @@ static const struct v3d_qpu_sig v33_sig_map[] = { [31] = { SMIMM, }, }; +static const struct v3d_qpu_sig v40_sig_map[] = { + /* MISC R3 R4 R5 */ + [0] = { }, + [1] = { THRSW, }, + [2] = { LDUNIF }, + [3] = { THRSW, LDUNIF }, + [4] = { LDTMU, }, + [5] = { THRSW, LDTMU, }, + [6] = { LDTMU, LDUNIF }, + [7] = { THRSW, LDTMU, LDUNIF }, + [8] = { LDVARY, }, + [9] = { THRSW, LDVARY, }, + [10] = { LDVARY, LDUNIF }, + [11] = { THRSW, LDVARY, LDUNIF }, + /* 12-13 reserved */ + [14] = { SMIMM, LDVARY, }, + [15] = { SMIMM, }, + [16] = { LDTLB, }, + [17] = { LDTLBU, }, + [18] = { WRTMUC }, + [19] = { THRSW, WRTMUC }, + [20] = { LDVARY, WRTMUC }, + [21] = { THRSW, LDVARY, WRTMUC }, + [22] = { UCB, }, + [23] = { ROT, }, + /* 24-30 reserved */ + [31] = { SMIMM, LDTMU, }, +}; + +static const struct v3d_qpu_sig v41_sig_map[] = { + /* MISC phys R5 */ + [0] = { }, + [1] = { THRSW, }, + [2] = { LDUNIF }, + [3] = { THRSW, LDUNIF }, + [4] = { LDTMU, }, + [5] = { THRSW, LDTMU, }, + [6] = { LDTMU, LDUNIF }, + [7] = { THRSW, LDTMU, LDUNIF }, + [8] = { LDVARY, }, + [9] = { THRSW, LDVARY, }, + [10] = { LDVARY, LDUNIF }, + [11] = { THRSW, LDVARY, LDUNIF }, + [12] = { LDUNIFRF }, + [13] = { THRSW, LDUNIFRF }, + [14] = { SMIMM, LDVARY, }, + [15] = { SMIMM, }, + [16] = { LDTLB, }, + [17] = { LDTLBU, }, + [18] = { WRTMUC }, + [19] = { THRSW, WRTMUC }, + [20] = { LDVARY, WRTMUC }, + [21] = { THRSW, LDVARY, WRTMUC }, + [22] = { UCB, }, + [23] = { ROT, }, + /* 24-30 reserved */ + [24] = { LDUNIFA}, + [25] = { LDUNIFARF }, + [31] = { SMIMM, LDTMU, }, +}; + bool v3d_qpu_sig_unpack(const struct v3d_device_info *devinfo, uint32_t packed_sig, @@ -164,7 +224,12 @@ v3d_qpu_sig_unpack(const struct v3d_device_info *devinfo, if (packed_sig >= ARRAY_SIZE(v33_sig_map)) return false; - *sig = v33_sig_map[packed_sig]; + if (devinfo->ver >= 41) + *sig = v41_sig_map[packed_sig]; + else if (devinfo->ver == 40) + *sig = v40_sig_map[packed_sig]; + else + *sig = v33_sig_map[packed_sig]; /* Signals with zeroed unpacked contents after element 0 are reserved. */ return (packed_sig == 0 || @@ -178,7 +243,12 @@ v3d_qpu_sig_pack(const struct v3d_device_info *devinfo, { static const struct v3d_qpu_sig *map; - map = v33_sig_map; + if (devinfo->ver >= 41) + map = v41_sig_map; + else if (devinfo->ver == 40) + map = v40_sig_map; + else + map = v33_sig_map; for (int i = 0; i < ARRAY_SIZE(v33_sig_map); i++) { if (memcmp(&map[i], sig, sizeof(*sig)) == 0) { @@ -1063,10 +1133,21 @@ v3d_qpu_instr_unpack_alu(const struct v3d_device_info *devinfo, &instr->sig)) return false; - if (!v3d_qpu_flags_unpack(devinfo, - QPU_GET_FIELD(packed_instr, VC5_QPU_COND), - &instr->flags)) - return false; + uint32_t packed_cond = QPU_GET_FIELD(packed_instr, VC5_QPU_COND); + if (v3d_qpu_sig_writes_address(devinfo, &instr->sig)) { + instr->sig_addr = packed_cond & ~VC5_QPU_COND_SIG_MAGIC_ADDR; + instr->sig_magic = packed_cond & VC5_QPU_COND_SIG_MAGIC_ADDR; + + instr->flags.ac = V3D_QPU_COND_NONE; + instr->flags.mc = V3D_QPU_COND_NONE; + instr->flags.apf = V3D_QPU_PF_NONE; + instr->flags.mpf = V3D_QPU_PF_NONE; + instr->flags.auf = V3D_QPU_UF_NONE; + instr->flags.muf = V3D_QPU_UF_NONE; + } else { + if (!v3d_qpu_flags_unpack(devinfo, packed_cond, &instr->flags)) + return false; + } instr->raddr_a = QPU_GET_FIELD(packed_instr, VC5_QPU_RADDR_A); instr->raddr_b = QPU_GET_FIELD(packed_instr, VC5_QPU_RADDR_B); @@ -1164,9 +1245,28 @@ v3d_qpu_instr_pack_alu(const struct v3d_device_info *devinfo, return false; uint32_t flags; - if (!v3d_qpu_flags_pack(devinfo, &instr->flags, &flags)) - return false; + if (v3d_qpu_sig_writes_address(devinfo, &instr->sig)) { + if (instr->flags.ac != V3D_QPU_COND_NONE || + instr->flags.mc != V3D_QPU_COND_NONE || + instr->flags.apf != V3D_QPU_PF_NONE || + instr->flags.mpf != V3D_QPU_PF_NONE || + instr->flags.auf != V3D_QPU_UF_NONE || + instr->flags.muf != V3D_QPU_UF_NONE) { + return false; + } + + flags = instr->sig_addr; + if (instr->sig_magic) + flags |= VC5_QPU_COND_SIG_MAGIC_ADDR; + } else { + if (!v3d_qpu_flags_pack(devinfo, &instr->flags, &flags)) + return false; + } + *packed_instr |= QPU_SET_FIELD(flags, VC5_QPU_COND); + } else { + if (v3d_qpu_sig_writes_address(devinfo, &instr->sig)) + return false; } return true; diff --git a/src/broadcom/qpu/tests/qpu_disasm.c b/src/broadcom/qpu/tests/qpu_disasm.c index 59668a86ecc..4f6ded73d48 100644 --- a/src/broadcom/qpu/tests/qpu_disasm.c +++ b/src/broadcom/qpu/tests/qpu_disasm.c @@ -63,6 +63,13 @@ static const struct { { 33, 0x041618d57c453000ull, "shl.andn exp, r3, r2; add.ifb rf35, r1, r2" }, { 33, 0x7048e5da49272800ull, "fsub.ifa rf26, r2.l, rf32; fmul.pushc sin, r1.h, r1.abs; ldunif" }, + /* v4.1 signals */ + { 41, 0x1f010520cf60a000ull, "fcmp.andz rf32, r2.h, r1.h; vfmul rf20, r0.hh, r3; ldunifa" }, + { 41, 0x932045e6c16ea000ull, "fcmp rf38, r2.abs, r5; fmul rf23.l, r3, r3.abs; ldunifarf.rf1" }, + { 41, 0xd72f0434e43ae5c0ull, "fcmp rf52.h, rf23, r5.abs; fmul rf16.h, rf23, r1; ldunifarf.rf60" }, + { 41, 0xdb3048eb9d533780ull, "fmax rf43.l, r3.h, rf30; fmul rf35.h, r4, r2.l; ldunifarf.r1" }, + { 41, 0x733620471e6ce700ull, "faddnf rf7.l, rf28.h, r1.l; fmul r1, r3.h, r3.abs; ldunifarf.rsqrt2" }, + { 41, 0x9c094adef634b000ull, "ffloor.ifb rf30.l, r3; fmul.pushz rf43.l, r5, r1.h" }, }; static void |