broadcom/vc5: Use the new LDVPM/STVPM opcodes on V3D 4.1.
Now, instead of a magic write register for VPM stores we have an instruction to do them (which means no packing of other ALU ops into it), with the ability to reorder the VPM stores due to the offset being baked into the instruction. VPM loads also gain the ability to be reordered by packing the row into the A argument. They also no longer write to the r3 accumulator, and instead must be stored to a physical register.
This commit is contained in:
@@ -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)
|
||||
|
Reference in New Issue
Block a user