Commit 0a95642d authored by Connor Abbott's avatar Connor Abbott
Browse files

bifrost: Swap ports 2 and 3

See commit 8f0e6bf in the ShaderProgramDisassembler.
parent 82b3e143
......@@ -436,8 +436,8 @@ The format of the register part of the instruction word is as follows:
|===============================
| Field | Bits
| Uniform/const | 8
| Port 2 (write) | 6
| Port 3 (read/write FMA) | 6
| Port 3 (write) | 6
| Port 2 (read/write FMA) | 6
| Port 0 (read) | 5
| Port 1 (read) | 6
| Control | 4
......@@ -447,24 +447,24 @@ Control is what ARM calls the "register access descriptor." To save bits, if the
ARM has one additional trick to save a bit. Port 0 only has 5 bits, so it would seem that when Port 0 and Port 1 are in use, then both can't load a register greater than 31 at the same time. But it turns out that this isn't the case. The hardware compares the register numbers being loaded, and if Port 0 is greater than Port 1, it subtracts 63 from both numbers to get the real register. This lets software encode every possible combination of registers loaded in Port 0 and Port 1, possibly requiring it to swap Port 0 and Port 1.
Additionally, if the register control field writes to Port 2 but doesn't read or write from Port 3, the compiler appers to copy the value in Port 2 over to Port 3. The reason for this is unknown.
Additionally, if the register control field writes to Port 3 but doesn't read or write from Port 2, the compiler appers to copy the value in Port 3 over to Port 2. The reason for this is unknown.
Before we get to the actual format of the Control field, though, we need to describe one more subtlety. Each instruction's register field contains the writes for the previous instruction, but what about the writes of the last instruction in the clause? Clauses should be entirely self-contained, so we can't look at the first instruction in the next clause. The answer turns out to be that the first instruction in the clause contains the writes for the last instruction. There are a few extra values for the control field, marked "first instruction," which are only used for the first instruction of a clause. The reads are processed normally, but the writes are delayed until the very end of the clause, after the last instruction. The list of values for the control field is below:
[options="header"]
|============================
| Value | Meaning
| 1 | Write FMA with Port 2
| 3 | Write FMA with Port 2, read with Port 3
| 4 | Read with Port 3
| 5 | Write ADD with Port 2
| 6 | Write ADD with Port 2, read with Port 3
| 1 | Write FMA with Port 3
| 3 | Write FMA with Port 3, read with Port 2
| 4 | Read with Port 2
| 5 | Write ADD with Port 3
| 6 | Write ADD with Port 3, read with Port 2
| 8 | Nothing, first instruction
| 9 | Write FMA with Port 2, first instruction
| 9 | Write FMA with Port 3, first instruction
| 11 | Nothing
| 12 | Read with Port 3, first instruction
| 13 | Write ADD with Port 2, first instruction
| 15 | Write ADD with Port 2, write FMA with Port 3
| 12 | Read with Port 2, first instruction
| 13 | Write ADD with Port 3, first instruction
| 15 | Write ADD with Port 3, write FMA with Port 2
|============================
Unlike the other ports, the uniform/const port always loads 64 bits at a time. If an FMA or ADD instruction only needs 32 bits of data, the high 32 bits or low 32 bits are selected later in the source field, described below.
......@@ -506,7 +506,7 @@ When the FMA and ADD stages want to use the result of the register stage, they d
| Field value | Meaning
| 0 | Port 0
| 1 | Port 1
| 2 | Port 3
| 2 | Port 2
.2+| 3 | FMA: always 0
| ADD: result of FMA unit from same instruction
| 4 | Low 32 bits of uniform/const
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment