summaryrefslogtreecommitdiffstats
path: root/src/broadcom/qpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/broadcom/qpu')
-rw-r--r--src/broadcom/qpu/qpu_instr.c61
-rw-r--r--src/broadcom/qpu/qpu_instr.h10
-rw-r--r--src/broadcom/qpu/qpu_pack.c47
-rw-r--r--src/broadcom/qpu/tests/qpu_disasm.c4
4 files changed, 110 insertions, 12 deletions
diff --git a/src/broadcom/qpu/qpu_instr.c b/src/broadcom/qpu/qpu_instr.c
index 682fee740a0..85d6cf75d81 100644
--- a/src/broadcom/qpu/qpu_instr.c
+++ b/src/broadcom/qpu/qpu_instr.c
@@ -113,10 +113,13 @@ v3d_qpu_add_op_name(enum v3d_qpu_add_op op)
[V3D_QPU_A_TMUWT] = "tmuwt",
[V3D_QPU_A_VPMSETUP] = "vpmsetup",
[V3D_QPU_A_VPMWT] = "vpmwt",
- [V3D_QPU_A_LDVPMV] = "ldvpmv",
- [V3D_QPU_A_LDVPMD] = "ldvpmd",
+ [V3D_QPU_A_LDVPMV_IN] = "ldvpmv_in",
+ [V3D_QPU_A_LDVPMV_OUT] = "ldvpmv_out",
+ [V3D_QPU_A_LDVPMD_IN] = "ldvpmd_in",
+ [V3D_QPU_A_LDVPMD_OUT] = "ldvpmd_out",
[V3D_QPU_A_LDVPMP] = "ldvpmp",
- [V3D_QPU_A_LDVPMG] = "ldvpmg",
+ [V3D_QPU_A_LDVPMG_IN] = "ldvpmg_in",
+ [V3D_QPU_A_LDVPMG_OUT] = "ldvpmg_out",
[V3D_QPU_A_FCMP] = "fcmp",
[V3D_QPU_A_VFMAX] = "vfmax",
[V3D_QPU_A_FROUND] = "fround",
@@ -376,10 +379,13 @@ static const uint8_t add_op_args[] = {
[V3D_QPU_A_VPMSETUP] = D | A,
- [V3D_QPU_A_LDVPMV] = D | A,
- [V3D_QPU_A_LDVPMD] = D | A,
+ [V3D_QPU_A_LDVPMV_IN] = D | A,
+ [V3D_QPU_A_LDVPMV_OUT] = D | A,
+ [V3D_QPU_A_LDVPMD_IN] = D | A,
+ [V3D_QPU_A_LDVPMD_OUT] = D | A,
[V3D_QPU_A_LDVPMP] = D | A,
- [V3D_QPU_A_LDVPMG] = D | A | B,
+ [V3D_QPU_A_LDVPMG_IN] = D | A | B,
+ [V3D_QPU_A_LDVPMG_OUT] = D | A | B,
/* FIXME: MOVABSNEG */
@@ -516,6 +522,49 @@ v3d_qpu_magic_waddr_is_tsy(enum v3d_qpu_waddr waddr)
waddr == V3D_QPU_WADDR_SYNCU);
}
+static bool
+v3d_qpu_add_op_uses_vpm(enum v3d_qpu_add_op op)
+{
+ switch (op) {
+ case V3D_QPU_A_VPMSETUP:
+ case V3D_QPU_A_VPMWT:
+ case V3D_QPU_A_LDVPMV_IN:
+ case V3D_QPU_A_LDVPMV_OUT:
+ case V3D_QPU_A_LDVPMD_IN:
+ case V3D_QPU_A_LDVPMD_OUT:
+ case V3D_QPU_A_LDVPMP:
+ case V3D_QPU_A_LDVPMG_IN:
+ case V3D_QPU_A_LDVPMG_OUT:
+ case V3D_QPU_A_STVPMV:
+ case V3D_QPU_A_STVPMD:
+ case V3D_QPU_A_STVPMP:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool
+v3d_qpu_uses_vpm(const struct v3d_qpu_instr *inst)
+{
+ if (inst->type == V3D_QPU_INSTR_TYPE_ALU) {
+ if (v3d_qpu_add_op_uses_vpm(inst->alu.add.op))
+ return true;
+
+ if (inst->alu.add.magic_write &&
+ v3d_qpu_magic_waddr_is_vpm(inst->alu.add.waddr)) {
+ return true;
+ }
+
+ if (inst->alu.mul.magic_write &&
+ v3d_qpu_magic_waddr_is_vpm(inst->alu.mul.waddr)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
bool
v3d_qpu_writes_r3(const struct v3d_device_info *devinfo,
const struct v3d_qpu_instr *inst)
diff --git a/src/broadcom/qpu/qpu_instr.h b/src/broadcom/qpu/qpu_instr.h
index 468fe89facd..0bd79ca68da 100644
--- a/src/broadcom/qpu/qpu_instr.h
+++ b/src/broadcom/qpu/qpu_instr.h
@@ -173,10 +173,13 @@ enum v3d_qpu_add_op {
V3D_QPU_A_TMUWT,
V3D_QPU_A_VPMSETUP,
V3D_QPU_A_VPMWT,
- V3D_QPU_A_LDVPMV,
- V3D_QPU_A_LDVPMD,
+ V3D_QPU_A_LDVPMV_IN,
+ V3D_QPU_A_LDVPMV_OUT,
+ V3D_QPU_A_LDVPMD_IN,
+ V3D_QPU_A_LDVPMD_OUT,
V3D_QPU_A_LDVPMP,
- V3D_QPU_A_LDVPMG,
+ V3D_QPU_A_LDVPMG_IN,
+ V3D_QPU_A_LDVPMG_OUT,
V3D_QPU_A_FCMP,
V3D_QPU_A_VFMAX,
V3D_QPU_A_FROUND,
@@ -425,6 +428,7 @@ bool v3d_qpu_writes_r4(const struct v3d_device_info *devinfo,
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_uses_vpm(const struct v3d_qpu_instr *inst);
bool v3d_qpu_sig_writes_address(const struct v3d_device_info *devinfo,
const struct v3d_qpu_sig *sig) ATTRIBUTE_CONST;
diff --git a/src/broadcom/qpu/qpu_pack.c b/src/broadcom/qpu/qpu_pack.c
index 161e24f0300..ffabc9a969d 100644
--- a/src/broadcom/qpu/qpu_pack.c
+++ b/src/broadcom/qpu/qpu_pack.c
@@ -515,7 +515,11 @@ static const struct opcode_desc add_ops[] = {
{ 187, 187, 1 << 2, 1 << 5, V3D_QPU_A_TMUWT },
{ 187, 187, 1 << 2, 1 << 6, V3D_QPU_A_VPMWT },
- { 187, 187, 1 << 3, ANYMUX, V3D_QPU_A_VPMSETUP },
+ { 187, 187, 1 << 3, ANYMUX, V3D_QPU_A_VPMSETUP, 33 },
+ { 188, 188, 1 << 0, ANYMUX, V3D_QPU_A_LDVPMV_IN, 40 },
+ { 188, 188, 1 << 1, ANYMUX, V3D_QPU_A_LDVPMD_IN, 40 },
+ { 188, 188, 1 << 2, ANYMUX, V3D_QPU_A_LDVPMP, 40 },
+ { 189, 189, ANYMUX, ANYMUX, V3D_QPU_A_LDVPMG_IN, 40 },
/* FIXME: MORE COMPLICATED */
/* { 190, 191, ANYMUX, ANYMUX, V3D_QPU_A_VFMOVABSNEGNAB }, */
@@ -823,7 +827,24 @@ v3d_qpu_add_unpack(const struct v3d_device_info *devinfo, uint64_t packed_inst,
instr->alu.add.a = mux_a;
instr->alu.add.b = mux_b;
instr->alu.add.waddr = QPU_GET_FIELD(packed_inst, V3D_QPU_WADDR_A);
- instr->alu.add.magic_write = packed_inst & VC5_QPU_MA;
+
+ instr->alu.add.magic_write = false;
+ if (packed_inst & VC5_QPU_MA) {
+ switch (instr->alu.add.op) {
+ case V3D_QPU_A_LDVPMV_IN:
+ instr->alu.add.op = V3D_QPU_A_LDVPMV_OUT;
+ break;
+ case V3D_QPU_A_LDVPMD_IN:
+ instr->alu.add.op = V3D_QPU_A_LDVPMD_OUT;
+ break;
+ case V3D_QPU_A_LDVPMG_IN:
+ instr->alu.add.op = V3D_QPU_A_LDVPMG_OUT;
+ break;
+ default:
+ instr->alu.add.magic_write = true;
+ break;
+ }
+ }
return true;
}
@@ -930,16 +951,36 @@ v3d_qpu_add_pack(const struct v3d_device_info *devinfo,
if (nsrc < 1)
mux_a = ffs(desc->mux_a_mask) - 1;
+ bool no_magic_write = false;
+
switch (instr->alu.add.op) {
case V3D_QPU_A_STVPMV:
waddr = 0;
+ no_magic_write = true;
break;
case V3D_QPU_A_STVPMD:
waddr = 1;
+ no_magic_write = true;
break;
case V3D_QPU_A_STVPMP:
waddr = 2;
+ no_magic_write = true;
+ break;
+
+ case V3D_QPU_A_LDVPMV_IN:
+ case V3D_QPU_A_LDVPMD_IN:
+ case V3D_QPU_A_LDVPMP:
+ case V3D_QPU_A_LDVPMG_IN:
+ assert(!instr->alu.add.magic_write);
break;
+
+ case V3D_QPU_A_LDVPMV_OUT:
+ case V3D_QPU_A_LDVPMD_OUT:
+ case V3D_QPU_A_LDVPMG_OUT:
+ assert(!instr->alu.add.magic_write);
+ *packed_instr |= VC5_QPU_MA;
+ break;
+
default:
break;
}
@@ -1065,7 +1106,7 @@ v3d_qpu_add_pack(const struct v3d_device_info *devinfo,
*packed_instr |= QPU_SET_FIELD(mux_b, VC5_QPU_ADD_B);
*packed_instr |= QPU_SET_FIELD(opcode, VC5_QPU_OP_ADD);
*packed_instr |= QPU_SET_FIELD(waddr, V3D_QPU_WADDR_A);
- if (instr->alu.add.magic_write)
+ if (instr->alu.add.magic_write && !no_magic_write)
*packed_instr |= VC5_QPU_MA;
return true;
diff --git a/src/broadcom/qpu/tests/qpu_disasm.c b/src/broadcom/qpu/tests/qpu_disasm.c
index 27dc184f76e..8d77740edce 100644
--- a/src/broadcom/qpu/tests/qpu_disasm.c
+++ b/src/broadcom/qpu/tests/qpu_disasm.c
@@ -76,6 +76,10 @@ static const struct {
{ 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" },
+
+ /* v4.1 opcodes */
+ { 41, 0x3de020c7bdfd200dull, "ldvpmg_in rf7, r2, r2; mov r3, 13" },
+ { 41, 0x3de02040f8ff7201ull, "stvpmv 1, rf8 ; mov r1, 1" },
};
static void