1 #include "nouveau_shader.h"
2 #include "nv40_shader.h"
5 unsigned int NVFP_TX_BOP_COUNT
= 5;
6 struct _op_xlat NVFP_TX_BOP
[64];
9 /*****************************************************************************
11 * - These extend the NV30 routines, which are almost identical. NV40
12 * just has branching hacked into the instruction set.
15 NV40FPSetBranchTarget(nvsFunc
*shader
, int addr
)
17 shader
->inst
[2] &= ~NV40_FP_OP_IADDR_MASK
;
18 shader
->inst
[2] |= (addr
<< NV40_FP_OP_IADDR_SHIFT
);
22 NV40FPSetBranchElse(nvsFunc
*shader
, int addr
)
24 shader
->inst
[2] &= ~NV40_FP_OP_ELSE_ID_MASK
;
25 shader
->inst
[2] |= (addr
<< NV40_FP_OP_ELSE_ID_SHIFT
);
29 NV40FPSetBranchEnd(nvsFunc
*shader
, int addr
)
31 shader
->inst
[3] &= ~NV40_FP_OP_END_ID_MASK
;
32 shader
->inst
[3] |= (addr
<< NV40_FP_OP_END_ID_SHIFT
);
36 NV40FPSetLoopParams(nvsFunc
*shader
, int count
, int initial
, int increment
)
38 shader
->inst
[2] &= ~(NV40_FP_OP_LOOP_COUNT_MASK
|
39 NV40_FP_OP_LOOP_INDEX_MASK
|
40 NV40_FP_OP_LOOP_INCR_MASK
);
41 shader
->inst
[2] |= ((count
<< NV40_FP_OP_LOOP_COUNT_SHIFT
) |
42 (initial
<< NV40_FP_OP_LOOP_INDEX_SHIFT
) |
43 (increment
<< NV40_FP_OP_LOOP_INCR_SHIFT
));
46 /*****************************************************************************
47 * Disassembly routines
49 static struct _op_xlat
*
50 NV40FPGetOPTXRec(nvsFunc
* shader
, int merged
)
55 op
= shader
->GetOpcodeHW(shader
, 0);
56 if (shader
->inst
[2] & NV40_FP_OP_OPCODE_IS_BRANCH
) {
58 op
&= ~NV40_FP_OP_OPCODE_IS_BRANCH
;
59 if (op
> NVFP_TX_BOP_COUNT
)
64 if (op
> NVFP_TX_AOP_COUNT
)
68 if (opr
[op
].SOP
== NVS_OP_UNKNOWN
)
74 NV40FPGetSourceID(nvsFunc
* shader
, int merged
, int pos
)
76 switch (shader
->GetSourceFile(shader
, merged
, pos
)) {
78 switch ((shader
->inst
[0] & NV40_FP_OP_INPUT_SRC_MASK
)
79 >> NV40_FP_OP_INPUT_SRC_SHIFT
) {
80 case NV40_FP_OP_INPUT_SRC_POSITION
: return NVS_FR_POSITION
;
81 case NV40_FP_OP_INPUT_SRC_COL0
: return NVS_FR_COL0
;
82 case NV40_FP_OP_INPUT_SRC_COL1
: return NVS_FR_COL1
;
83 case NV40_FP_OP_INPUT_SRC_FOGC
: return NVS_FR_FOGCOORD
;
84 case NV40_FP_OP_INPUT_SRC_TC(0) : return NVS_FR_TEXCOORD0
;
85 case NV40_FP_OP_INPUT_SRC_TC(1) : return NVS_FR_TEXCOORD1
;
86 case NV40_FP_OP_INPUT_SRC_TC(2) : return NVS_FR_TEXCOORD2
;
87 case NV40_FP_OP_INPUT_SRC_TC(3) : return NVS_FR_TEXCOORD3
;
88 case NV40_FP_OP_INPUT_SRC_TC(4) : return NVS_FR_TEXCOORD4
;
89 case NV40_FP_OP_INPUT_SRC_TC(5) : return NVS_FR_TEXCOORD5
;
90 case NV40_FP_OP_INPUT_SRC_TC(6) : return NVS_FR_TEXCOORD6
;
91 case NV40_FP_OP_INPUT_SRC_TC(7) : return NVS_FR_TEXCOORD7
;
92 case NV40_FP_OP_INPUT_SRC_FACING
: return NVS_FR_FACING
;
101 src
= shader
->GetSourceHW(shader
, merged
, pos
);
102 return ((src
& NV40_FP_REG_SRC_MASK
) >> NV40_FP_REG_SRC_SHIFT
);
104 case NVS_FILE_CONST
: /* inlined into fragprog */
111 NV40FPGetBranch(nvsFunc
* shader
)
113 return ((shader
->inst
[2] & NV40_FP_OP_IADDR_MASK
)
114 >> NV40_FP_OP_IADDR_SHIFT
);;
118 NV40FPGetBranchElse(nvsFunc
* shader
)
120 return ((shader
->inst
[2] & NV40_FP_OP_ELSE_ID_MASK
)
121 >> NV40_FP_OP_ELSE_ID_SHIFT
);
125 NV40FPGetBranchEnd(nvsFunc
* shader
)
127 return ((shader
->inst
[3] & NV40_FP_OP_END_ID_MASK
)
128 >> NV40_FP_OP_END_ID_SHIFT
);
132 NV40FPGetLoopCount(nvsFunc
* shader
)
134 return ((shader
->inst
[2] & NV40_FP_OP_LOOP_COUNT_MASK
)
135 >> NV40_FP_OP_LOOP_COUNT_SHIFT
);
139 NV40FPGetLoopInitial(nvsFunc
* shader
)
141 return ((shader
->inst
[2] & NV40_FP_OP_LOOP_INDEX_MASK
)
142 >> NV40_FP_OP_LOOP_INDEX_SHIFT
);
146 NV40FPGetLoopIncrement(nvsFunc
* shader
)
148 return ((shader
->inst
[2] & NV40_FP_OP_LOOP_INCR_MASK
)
149 >> NV40_FP_OP_LOOP_INCR_SHIFT
);
153 NV40FPInitShaderFuncs(nvsFunc
* shader
)
155 /* Inherit NV30 FP code, it's mostly the same */
156 NV30FPInitShaderFuncs(shader
);
158 /* Kill off opcodes seen on NV30, but not seen on NV40 - need to find
159 * out if these actually work or not.
161 * update: either LIT/RSQ don't work on nv40, or I generate bad code for
162 * them. haven't tested the others yet
164 MOD_OPCODE(NVFP_TX_AOP
, 0x1B, NVS_OP_UNKNOWN
, -1, -1, -1); /* NV30 RSQ */
165 MOD_OPCODE(NVFP_TX_AOP
, 0x1E, NVS_OP_UNKNOWN
, -1, -1, -1); /* NV30 LIT */
166 MOD_OPCODE(NVFP_TX_AOP
, 0x1F, NVS_OP_UNKNOWN
, -1, -1, -1); /* NV30 LRP */
167 MOD_OPCODE(NVFP_TX_AOP
, 0x26, NVS_OP_UNKNOWN
, -1, -1, -1); /* NV30 POW */
168 MOD_OPCODE(NVFP_TX_AOP
, 0x36, NVS_OP_UNKNOWN
, -1, -1, -1); /* NV30 RFL */
170 /* Extra opcodes supported on NV40 */
171 MOD_OPCODE(NVFP_TX_AOP
, NV40_FP_OP_OPCODE_DIV
, NVS_OP_DIV
, 0, 1, -1);
172 MOD_OPCODE(NVFP_TX_AOP
, NV40_FP_OP_OPCODE_DP2A
, NVS_OP_DP2A
, 0, 1, 2);
173 MOD_OPCODE(NVFP_TX_AOP
, NV40_FP_OP_OPCODE_TXL
, NVS_OP_TXL
, 0, -1, -1);
175 MOD_OPCODE(NVFP_TX_BOP
, NV40_FP_OP_BRA_OPCODE_BRK
, NVS_OP_BRK
, -1, -1, -1);
176 MOD_OPCODE(NVFP_TX_BOP
, NV40_FP_OP_BRA_OPCODE_CAL
, NVS_OP_CAL
, -1, -1, -1);
177 MOD_OPCODE(NVFP_TX_BOP
, NV40_FP_OP_BRA_OPCODE_IF
, NVS_OP_IF
, -1, -1, -1);
178 MOD_OPCODE(NVFP_TX_BOP
, NV40_FP_OP_BRA_OPCODE_LOOP
, NVS_OP_LOOP
, -1, -1, -1);
179 MOD_OPCODE(NVFP_TX_BOP
, NV40_FP_OP_BRA_OPCODE_REP
, NVS_OP_REP
, -1, -1, -1);
180 MOD_OPCODE(NVFP_TX_BOP
, NV40_FP_OP_BRA_OPCODE_RET
, NVS_OP_RET
, -1, -1, -1);
182 /* fragment.facing */
183 shader
->GetSourceID
= NV40FPGetSourceID
;
186 shader
->GetOPTXRec
= NV40FPGetOPTXRec
;
187 shader
->GetBranch
= NV40FPGetBranch
;
188 shader
->GetBranchElse
= NV40FPGetBranchElse
;
189 shader
->GetBranchEnd
= NV40FPGetBranchEnd
;
190 shader
->GetLoopCount
= NV40FPGetLoopCount
;
191 shader
->GetLoopInitial
= NV40FPGetLoopInitial
;
192 shader
->GetLoopIncrement
= NV40FPGetLoopIncrement
;
193 shader
->SetBranchTarget
= NV40FPSetBranchTarget
;
194 shader
->SetBranchElse
= NV40FPSetBranchElse
;
195 shader
->SetBranchEnd
= NV40FPSetBranchEnd
;
196 shader
->SetLoopParams
= NV40FPSetLoopParams
;