1#define NV_MME_PRED_MODE_UUUU                0
2#define NV_MME_PRED_MODE_TTTT                1
3#define NV_MME_PRED_MODE_FFFF                2
4#define NV_MME_PRED_MODE_TTUU                3
5#define NV_MME_PRED_MODE_FFUU                4
6#define NV_MME_PRED_MODE_TFUU                5
7#define NV_MME_PRED_MODE_TUUU                6
8#define NV_MME_PRED_MODE_FUUU                7
9#define NV_MME_PRED_MODE_UUTT                8
10#define NV_MME_PRED_MODE_UUTF                9
11#define NV_MME_PRED_MODE_UUTU                10
12#define NV_MME_PRED_MODE_UUFT                11
13#define NV_MME_PRED_MODE_UUFF                12
14#define NV_MME_PRED_MODE_UUFU                13
15#define NV_MME_PRED_MODE_UUUT                14
16#define NV_MME_PRED_MODE_UUUF                15
17
18#define NV_MME_REG_R0                       0
19#define NV_MME_REG_R1                       1
20#define NV_MME_REG_R2                       2
21#define NV_MME_REG_R3                       3
22#define NV_MME_REG_R4                       4
23#define NV_MME_REG_R5                       5
24#define NV_MME_REG_R6                       6
25#define NV_MME_REG_R7                       7
26#define NV_MME_REG_R8                       8
27#define NV_MME_REG_R9                       9
28#define NV_MME_REG_R10                      10
29#define NV_MME_REG_R11                      11
30#define NV_MME_REG_R12                      12
31#define NV_MME_REG_R13                      13
32#define NV_MME_REG_R14                      14
33#define NV_MME_REG_R15                      15
34#define NV_MME_REG_R16                      16
35#define NV_MME_REG_R17                      17
36#define NV_MME_REG_R18                      18
37#define NV_MME_REG_R19                      19
38#define NV_MME_REG_R20                      20
39#define NV_MME_REG_R21                      21
40#define NV_MME_REG_R22                      22
41#define NV_MME_REG_R23                      23
42#define NV_MME_REG_ZERO                     24
43#define NV_MME_REG_IMMED                    25
44#define NV_MME_REG_IMMEDPAIR                26
45#define NV_MME_REG_IMMED32                  27
46#define NV_MME_REG_LOAD0                    28
47#define NV_MME_REG_LOAD1                    29
48
49#define NV_MME_ALU_ADD                    0
50#define NV_MME_ALU_ADDC                   1
51#define NV_MME_ALU_SUB                    2
52#define NV_MME_ALU_SUBB                   3
53#define NV_MME_ALU_MUL                    4
54#define NV_MME_ALU_MULH                   5
55#define NV_MME_ALU_MULU                   6
56#define NV_MME_ALU_EXTENDED               7
57#define NV_MME_ALU_CLZ                    8
58#define NV_MME_ALU_SLL                    9
59#define NV_MME_ALU_SRL                    10
60#define NV_MME_ALU_SRA                    11
61#define NV_MME_ALU_AND                    12
62#define NV_MME_ALU_NAND                   13
63#define NV_MME_ALU_OR                     14
64#define NV_MME_ALU_XOR                    15
65#define NV_MME_ALU_MERGE                  16
66#define NV_MME_ALU_SLT                    17
67#define NV_MME_ALU_SLTU                   18
68#define NV_MME_ALU_SLE                    19
69#define NV_MME_ALU_SLEU                   20
70#define NV_MME_ALU_SEQ                    21
71#define NV_MME_ALU_STATE                  22
72#define NV_MME_ALU_LOOP                   23
73#define NV_MME_ALU_JAL                    24
74#define NV_MME_ALU_BLT                    25
75#define NV_MME_ALU_BLTU                   26
76#define NV_MME_ALU_BLE                    27
77#define NV_MME_ALU_BLEU                   28
78#define NV_MME_ALU_BEQ                    29
79#define NV_MME_ALU_DREAD                  30
80#define NV_MME_ALU_DWRITE                 31
81
82#define NV_MME_OUT_NONE                 0
83#define NV_MME_OUT_ALU0                 1
84#define NV_MME_OUT_ALU1                 2
85#define NV_MME_OUT_LOAD0                3
86#define NV_MME_OUT_LOAD1                4
87#define NV_MME_OUT_IMMED0               5
88#define NV_MME_OUT_IMMED1               6
89#define NV_MME_OUT_RESERVED             7
90#define NV_MME_OUT_IMMEDHIGH0           8
91#define NV_MME_OUT_IMMEDHIGH1           9
92#define NV_MME_OUT_IMMED32_0            10
93
94#define MME_BITS(en,pm,pr,o0,d0,a0,b0,i0,o1,d1,a1,b1,i1,m0,e0,m1,e1)           \
95   ((e1) << (92 - 64) | (m1) << (89 - 64) |                                    \
96    (e0) << (85 - 64) | (m0) << (82 - 64) |                                    \
97    (i1) << (66 - 64) | (b1) >> (64 - 61)),                                    \
98   (((b1) & 7)  << (61 - 32) | (a1) << (56 - 32) |                             \
99    (d1) << (51 - 32) | (o1) << (46 - 32) |                                    \
100    (i0) >> (32 - 30)),                                                        \
101   (((i0) & 3) << 30 | (b0) << 25 | (a0) << 20 | (d0) << 15 | (o0) << 10 |     \
102    (pr) << 5 | (pm) << 1 | (en))
103
104#define MME_INSN(en,o0,d0,a0,b0,i0,m0,e0,o1,d1,a1,b1,i1,m1,e1)                 \
105   MME_BITS((en), NV_MME_PRED_MODE_UUUU, NV_MME_REG_ZERO,                      \
106            NV_MME_ALU_##o0, NV_MME_REG_##d0,                               \
107            NV_MME_REG_##a0, NV_MME_REG_##b0, (i0),                            \
108            NV_MME_ALU_##o1, NV_MME_REG_##d1,                               \
109            NV_MME_REG_##a1, NV_MME_REG_##b1, (i1),                            \
110            NV_MME_OUT_##m0, NV_MME_OUT_##e0,                                  \
111            NV_MME_OUT_##m1, NV_MME_OUT_##e1)
112
113uint32_t mmec597_per_instance_bf[] = {
114// r1 = load();      // count
115// r3 = load();      // mask
116// mthd(0x1880, 1);  // VERTEX_ARRAY_PER_INSTANCE[0]
117   MME_INSN(0,   ADD,   R1, LOAD0,  ZERO,  (1<<12)|0x1880/4, IMMED0,   NONE,
118                 ADD,   R3, LOAD1,  ZERO,                 0,   NONE,   NONE),
119// while (HW_LOOP_COUNT < r1) {
120//    send(r3 & 1);
121//    r3 >>= 1;
122// }
123   MME_INSN(0,  LOOP, ZERO,    R1,  ZERO,            0x0003,   NONE,   NONE,
124                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
125   MME_INSN(0,   AND, ZERO,    R3, IMMED,                 1,   NONE,   ALU0,
126                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
127   MME_INSN(0,   SRL,   R3,    R3, IMMED,                 1,   NONE,   NONE,
128                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
129   MME_INSN(1,   ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE,
130                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
131   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE,
132                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
133};
134
135uint32_t mmec597_vertex_array_select[] = {
136// r1 = load();            // array
137// r2 = load();            // limit hi
138// r3 = load();            // limit lo
139// r4 = load();            // start hi
140// r5 = load();            // start lo
141// r6 = (r1 & 0x1f) << 2;
142// r7 = (r1 & 0x1f) << 1;
143// mthd(0x1c04 + r6, 1);   // VERTEX_ARRAY_START_HIGH[]
144// send(r4);
145// send(r5);
146// mthd(0x0600 + r7, 1);   // VERTEX_ARRAY_LIMIT_HIGH[]
147// send(r2);
148// send(r3);
149   MME_INSN(0,   ADD,   R1, LOAD0,  ZERO,                 0,   NONE,   NONE,
150                 ADD,   R2, LOAD1,  ZERO,                 0,   NONE,   NONE),
151   MME_INSN(0,   ADD,   R3, LOAD0,  ZERO,                 0,   NONE,   NONE,
152                 ADD,   R4, LOAD1,  ZERO,                 0,   NONE,   NONE),
153   MME_INSN(0,   ADD,   R5, LOAD0,  ZERO,                 0,   NONE,   NONE,
154               MERGE,   R6,  ZERO,    R1,  (2<<10)|(5<<5)|0,   NONE,   NONE),
155   MME_INSN(0, MERGE,   R7,  ZERO,    R1,  (1<<10)|(5<<5)|0,   ALU1,   NONE,
156                 ADD, ZERO,    R6, IMMED,  (1<<12)|0x1c04/4,   NONE,   NONE),
157   MME_INSN(0,   ADD, ZERO,    R4,  ZERO,                 0,   NONE,   ALU0,
158                 ADD, ZERO,    R5,  ZERO,                 0,   NONE,   ALU1),
159   MME_INSN(1,   ADD, ZERO,    R7, IMMED,  (1<<12)|0x0600/4,   ALU0,   ALU1,
160                 ADD, ZERO,    R2,  ZERO,                 0,   NONE,   NONE),
161   MME_INSN(0,   ADD, ZERO,    R3,  ZERO,                 0,   NONE,   ALU0,
162                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
163};
164
165uint32_t mmec597_blend_enables[] = {
166// r1 = load();         // enable mask
167// mthd(0x1360, 1);     // NVC0_3D_BLEND_ENABLE[]
168// send((r1 >> 0) & 1);
169// send((r1 >> 1) & 1);
170// send((r1 >> 2) & 1);
171// send((r1 >> 3) & 1);
172// send((r1 >> 4) & 1);
173// send((r1 >> 5) & 1);
174// send((r1 >> 6) & 1);
175// send((r1 >> 7) & 1);
176   MME_INSN(0,   ADD,   R1, LOAD0,  ZERO,                 0, IMMED1,   NONE,
177                 ADD, ZERO,  ZERO,  ZERO,  (1<<12)|0x1360/4,   NONE,   NONE),
178   MME_INSN(0, MERGE, ZERO,  ZERO,    R1,  (0<<10)|(1<<5)|0,   NONE,   ALU0,
179               MERGE, ZERO,  ZERO,    R1,  (0<<10)|(1<<5)|1,   NONE,   ALU1),
180   MME_INSN(0, MERGE, ZERO,  ZERO,    R1,  (0<<10)|(1<<5)|2,   NONE,   ALU0,
181               MERGE, ZERO,  ZERO,    R1,  (0<<10)|(1<<5)|3,   NONE,   ALU1),
182   MME_INSN(1, MERGE, ZERO,  ZERO,    R1,  (0<<10)|(1<<5)|4,   NONE,   ALU0,
183               MERGE, ZERO,  ZERO,    R1,  (0<<10)|(1<<5)|5,   NONE,   ALU1),
184   MME_INSN(0, MERGE, ZERO,  ZERO,    R1,  (0<<10)|(1<<5)|6,   NONE,   ALU0,
185               MERGE, ZERO,  ZERO,    R1,  (0<<10)|(1<<5)|7,   NONE,   ALU1),
186};
187
188uint32_t mmec597_poly_mode_front[] = {
189// r1 = load();
190// mthd(0x0dac,0);      // POLYGON_MODE_FRONT
191// send(r1);
192// r2 = read(0x0db0);   // POLYGON_MODE_BACK
193// r3 = read(0x20c0);   // SP_SELECT[3]
194// r7 = r1 | r2;
195// r4 = read(0x2100);   // SP_SELECT[4]
196// r6 = 0x60;
197// r7 = r7 & 1;
198// if (r7 != 0)
199   MME_INSN(0,   ADD,   R1, LOAD0,  ZERO,  (0<<12)|0x0dac/4, IMMED0,   ALU0,
200               STATE,   R2, IMMED,  ZERO,          0x0db0/4,   NONE,   NONE),
201   MME_INSN(0, STATE,   R3, IMMED,  ZERO,          0x20c0/4,   NONE,   NONE,
202                  OR,   R7,    R1,    R2,                 0,   NONE,   NONE),
203   MME_INSN(0, STATE,   R4, IMMED,  ZERO,          0x2100/4,   NONE,   NONE,
204                 ADD,   R6, IMMED,  ZERO,              0x60,   NONE,   NONE),
205   MME_INSN(0,   AND,   R7,    R7, IMMED,                 1,   NONE,   NONE,
206                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
207   MME_INSN(0,   BEQ, ZERO,    R7,  ZERO,    (2<<14)|0x0002,   NONE,   NONE,
208                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
209//    r6 = 0x200;
210   MME_INSN(0,   ADD,   R6, IMMED,  ZERO,             0x200,   NONE,   NONE,
211                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
212// r7 = r3 | r4;
213// r7 = r7 & 1;
214// if (r7 != 0)
215   MME_INSN(0,    OR,   R7,    R3,    R4,                 0,   NONE,   NONE,
216                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
217   MME_INSN(0,   AND,   R7,    R7, IMMED,                 1,   NONE,   NONE,
218                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
219   MME_INSN(0,   BEQ, ZERO,    R7,  ZERO,    (2<<14)|0x0002,   NONE,   NONE,
220                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
221//    r6 = 0;
222   MME_INSN(0,   ADD,   R6,  ZERO,  ZERO,                 0,   NONE,   NONE,
223                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
224// mthd(0x02ec, 0);
225// send(r6);
226   MME_INSN(1,   ADD, ZERO,  ZERO,  ZERO,  (0<<12)|0x02ec/4, IMMED0,   NONE,
227                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
228   MME_INSN(0,   ADD, ZERO,    R6,  ZERO,                 0,   NONE,   ALU0,
229                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
230};
231
232uint32_t mmec597_poly_mode_back[] = {
233// r1 = load();
234// mthd(0x0db0,0);      // POLYGON_MODE_BACK
235// send(r1);
236// r2 = read(0x0dac);   // POLYGON_MODE_FRONT
237// r3 = read(0x20c0);   // SP_SELECT[3]
238// r7 = r1 | r2;
239// r4 = read(0x2100);   // SP_SELECT[4]
240// r6 = 0x60;
241// r7 = r7 & 1;
242// if (r7 != 0)
243   MME_INSN(0,   ADD,   R1, LOAD0,  ZERO,  (0<<12)|0x0db0/4, IMMED0,   ALU0,
244               STATE,   R2, IMMED,  ZERO,          0x0dac/4,   NONE,   NONE),
245   MME_INSN(0, STATE,   R3, IMMED,  ZERO,          0x20c0/4,   NONE,   NONE,
246                  OR,   R7,    R1,    R2,                 0,   NONE,   NONE),
247   MME_INSN(0, STATE,   R4, IMMED,  ZERO,          0x2100/4,   NONE,   NONE,
248                 ADD,   R6, IMMED,  ZERO,              0x60,   NONE,   NONE),
249   MME_INSN(0,   AND,   R7,    R7, IMMED,                 1,   NONE,   NONE,
250                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
251   MME_INSN(0,   BEQ, ZERO,    R7,  ZERO,    (2<<14)|0x0002,   NONE,   NONE,
252                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
253//    r6 = 0x200;
254   MME_INSN(0,   ADD,   R6, IMMED,  ZERO,             0x200,   NONE,   NONE,
255                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
256// r7 = r3 | r4;
257// r7 = r7 & 1;
258// if (r7 != 0)
259   MME_INSN(0,    OR,   R7,    R3,    R4,                 0,   NONE,   NONE,
260                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
261   MME_INSN(0,   AND,   R7,    R7, IMMED,                 1,   NONE,   NONE,
262                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
263   MME_INSN(0,   BEQ, ZERO,    R7,  ZERO,    (2<<14)|0x0002,   NONE,   NONE,
264                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
265//    r6 = 0;
266   MME_INSN(0,   ADD,   R6,  ZERO,  ZERO,                 0,   NONE,   NONE,
267                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
268// mthd(0x02ec, 0);
269// send(r6);
270   MME_INSN(1,   ADD, ZERO,  ZERO,  ZERO,  (0<<12)|0x02ec/4, IMMED0,   NONE,
271                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
272   MME_INSN(0,   ADD, ZERO,    R6,  ZERO,                 0,   NONE,   ALU0,
273                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
274};
275
276uint32_t mmec597_gp_select[] = {
277// r1 = load();
278// mthd(0x2100,0);      // SP_SELECT[4]
279// send(r1);
280// r2 = read(0x0dac);   // POLYGON_MODE_FRONT
281// r3 = read(0x0db0);   // POLYGON_MODE_BACK
282// r7 = r2 | r3;
283// r4 = read(0x20c0);   // SP_SELECT[3]
284// r6 = 0x60;
285// r7 = r7 & 1;
286// if (r7 != 0)
287   MME_INSN(0,   ADD,   R1, LOAD0,  ZERO,  (0<<12)|0x2100/4, IMMED0,   ALU0,
288               STATE,   R2, IMMED,  ZERO,          0x0dac/4,   NONE,   NONE),
289   MME_INSN(0, STATE,   R3, IMMED,  ZERO,          0x0db0/4,   NONE,   NONE,
290                  OR,   R7,    R2,    R3,                 0,   NONE,   NONE),
291   MME_INSN(0, STATE,   R4, IMMED,  ZERO,          0x20c0/4,   NONE,   NONE,
292                 ADD,   R6, IMMED,  ZERO,              0x60,   NONE,   NONE),
293   MME_INSN(0,   AND,   R7,    R7, IMMED,                 1,   NONE,   NONE,
294                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
295   MME_INSN(0,   BEQ, ZERO,    R7,  ZERO,    (2<<14)|0x0002,   NONE,   NONE,
296                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
297//    r6 = 0x200;
298   MME_INSN(0,   ADD,   R6, IMMED,  ZERO,             0x200,   NONE,   NONE,
299                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
300// r7 = r1 | r4;
301// r7 = r7 & 1;
302// if (r7 != 0)
303   MME_INSN(0,    OR,   R7,    R1,    R4,                 0,   NONE,   NONE,
304                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
305   MME_INSN(0,   AND,   R7,    R7, IMMED,                 1,   NONE,   NONE,
306                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
307   MME_INSN(0,   BEQ, ZERO,    R7,  ZERO,    (2<<14)|0x0002,   NONE,   NONE,
308                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
309//    r6 = 0;
310   MME_INSN(0,   ADD,   R6,  ZERO,  ZERO,                 0,   NONE,   NONE,
311                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
312// mthd(0x02ec, 0);
313// send(r6);
314   MME_INSN(1,   ADD, ZERO,  ZERO,  ZERO,  (0<<12)|0x02ec/4, IMMED0,   NONE,
315                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
316   MME_INSN(0,   ADD, ZERO,    R6,  ZERO,                 0,   NONE,   ALU0,
317                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
318};
319
320uint32_t mmec597_tep_select[] = {
321// r1 = load();
322// mthd(0x20c0,0);      // SP_SELECT[3]
323// send(r1);
324// r2 = read(0x0dac);   // POLYGON_MODE_FRONT
325// r3 = read(0x0db0);   // POLYGON_MODE_BACK
326// r7 = r2 | r3;
327// r4 = read(0x2100);   // SP_SELECT[4]
328// r6 = 0x60;
329// r7 = r7 & 1;
330// if (r7 != 0)
331   MME_INSN(0,   ADD,   R1, LOAD0,  ZERO,  (0<<12)|0x20c0/4, IMMED0,   ALU0,
332               STATE,   R2, IMMED,  ZERO,          0x0dac/4,   NONE,   NONE),
333   MME_INSN(0, STATE,   R3, IMMED,  ZERO,          0x0db0/4,   NONE,   NONE,
334                  OR,   R7,    R2,    R3,                 0,   NONE,   NONE),
335   MME_INSN(0, STATE,   R4, IMMED,  ZERO,          0x2100/4,   NONE,   NONE,
336                 ADD,   R6, IMMED,  ZERO,              0x60,   NONE,   NONE),
337   MME_INSN(0,   AND,   R7,    R7, IMMED,                 1,   NONE,   NONE,
338                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
339   MME_INSN(0,   BEQ, ZERO,    R7,  ZERO,    (2<<14)|0x0002,   NONE,   NONE,
340                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
341//    r6 = 0x200;
342   MME_INSN(0,   ADD,   R6, IMMED,  ZERO,             0x200,   NONE,   NONE,
343                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
344// r7 = r1 | r4;
345// r7 = r7 & 1;
346// if (r7 != 0)
347   MME_INSN(0,    OR,   R7,    R1,    R4,                 0,   NONE,   NONE,
348                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
349   MME_INSN(0,   AND,   R7,    R7, IMMED,                 1,   NONE,   NONE,
350                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
351   MME_INSN(0,   BEQ, ZERO,    R7,  ZERO,    (2<<14)|0x0002,   NONE,   NONE,
352                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
353//    r6 = 0;
354   MME_INSN(0,   ADD,   R6,  ZERO,  ZERO,                 0,   NONE,   NONE,
355                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
356// mthd(0x02ec, 0);
357// send(r6);
358   MME_INSN(1,   ADD, ZERO,  ZERO,  ZERO,  (0<<12)|0x02ec/4, IMMED0,   NONE,
359                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
360   MME_INSN(0,   ADD, ZERO,    R6,  ZERO,                 0,   NONE,   ALU0,
361                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
362};
363
364uint32_t mmec597_draw_arrays_indirect[] = {
365// r1 = load();         // mode
366// r5 = read(0x1438);   // VB_INSTANCE_BASE
367// r6 = load();         // start_drawid
368// r7 = load();         // numparams
369   MME_INSN(0,   ADD,   R1, LOAD0,  ZERO,                0,   NONE,   NONE,
370                 ADD,   R6, LOAD1,  ZERO,                0,   NONE,   NONE),
371   MME_INSN(0,   ADD,   R7, LOAD0,  ZERO,                0,   NONE,   NONE,
372               STATE,   R5, IMMED,  ZERO,         0x1438/4,   NONE,   NONE),
373// while (HW_LOOP_COUNT < r7) {
374//    r2 = load();      // count
375//    r3 = load();      // instance_count
376//    mthd(0x0d74, 0);  // VERTEX_BUFFER_FIRST
377//    send(load());     // start
378//    r4 = load();      // start_instance
379//    if (r3) {
380   MME_INSN(0,  LOOP, ZERO,    R7,  ZERO,            0x000c,   NONE,   NONE,
381                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
382   MME_INSN(0,   ADD,   R2, LOAD0,  ZERO,          0x0d74/4, IMMED0,   NONE,
383                 ADD,   R3, LOAD1,  ZERO,                 0,   NONE,   NONE),
384   MME_INSN(0,   ADD, ZERO, LOAD0,  ZERO,                 0,   NONE,   ALU0,
385                 ADD,   R4, LOAD1,  ZERO,                 0,   NONE,   NONE),
386   MME_INSN(0,   BEQ, ZERO,    R3,  ZERO,    (2<<14)|0x0008,   NONE,   NONE,
387                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
388//       mthd(0x238c, 1);     // CB_POS
389//       send(256 + 160);
390//       send(0);             // base_vertex
391//       send(r4);            // start_instance
392//       send(r6);            // draw id
393//       mthd(0x1438, 0);     // VB_INSTANCE_BASE
394//       send(r4);
395//       r1 = r1 & ~(1<<26);  // clear INSTANCE_NEXT
396   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,  (1<<12)|0x238c/4, IMMED0, IMMED1,
397                 ADD, ZERO,  ZERO,  ZERO,         256 + 160,   NONE,   ALU0),
398   MME_INSN(0,   ADD, ZERO,    R4,  ZERO,                 0,   NONE,   ALU0,
399                 ADD, ZERO,    R6,  ZERO,                 0,   NONE,   ALU1),
400   MME_INSN(0,   ADD, ZERO,    R4,  ZERO,          0x1438/4, IMMED0,   ALU0,
401               MERGE,   R1,    R1,  ZERO, (26<<10)|(1<<5)|0,   NONE,   NONE),
402//       do {
403//          mthd(0x1618, 0);  // VERTEX_BEGIN_GL
404//          send(r1);         // mode
405//          mthd(0x0d78, 0);  // VERTEX_BUFFER_COUNT
406//          send(r2);         // count
407//          mthd(0x1614, 0);  // VERTEX_END_GL
408//          send(0);
409//          r1 |= (1<<26);    // set INSTANCE_NEXT
410//       } while(--r3);
411//    }
412   MME_INSN(0,   ADD, ZERO,    R1,  ZERO,          0x1618/4, IMMED0,   ALU0,
413                 ADD, ZERO,    R2,  ZERO,          0x0d78/4, IMMED1,   ALU1),
414   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,          0x1614/4, IMMED0,   ALU0,
415                 ADD,   R4, IMMED,  ZERO,                 1,   NONE,   NONE),
416   MME_INSN(0, MERGE,   R1,    R1,    R4, (26<<10)|(1<<5)|0,   NONE,   NONE,
417                 SUB,   R3,    R3, IMMED,                 1,   NONE,   NONE),
418   MME_INSN(0,   BEQ, ZERO,    R3,  ZERO,    (1<<14)|0x3ffd,   NONE,   NONE,
419                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
420//    r6 = r6 + 1;
421// };
422   MME_INSN(0,   ADD,   R6,    R6, IMMED,                 1,   NONE,   NONE,
423                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
424// mthd(0x1438, 0);  // restore VB_INSTANCE_BASE
425// send(r5);
426   MME_INSN(1,   ADD, ZERO,  ZERO,  ZERO,          0x1438/4, IMMED0,   NONE,
427                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
428   MME_INSN(0,   ADD, ZERO,    R5,  ZERO,                 0,   NONE,      ALU0,
429                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
430};
431
432uint32_t mmec597_draw_elts_indirect[] = {
433// r1 = load();         // mode
434// r8 = read(0x1434);   // VB_ELEMENT_BASE
435// r9 = read(0x1438);   // VB_INSTANCE_BASE
436// r6 = load();         // start_drawid
437// r7 = load();         // numparams
438   MME_INSN(0,   ADD,   R1, LOAD0,  ZERO,                 0,   NONE,   NONE,
439               STATE,   R8, IMMED,  ZERO,          0x1434/4,   NONE,   NONE),
440   MME_INSN(0, STATE,   R9, IMMED,  ZERO,          0x1438/4,   NONE,   NONE,
441                 ADD,   R6, LOAD0,  ZERO,                 0,   NONE,   NONE),
442   MME_INSN(0,   ADD,   R7, LOAD0,  ZERO,                 0,   NONE,   NONE,
443                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
444// while (HW_LOOP_COUNT < r7) {
445//    r3 = load();      // count
446//    r2 = load();      // instance_count
447//    mthd(0x17dc, 0);  // INDEX_BATCH_FIRST
448//    send(load());     // start
449//    r4 = load();      // index_bias
450//    mthd(0x238c, 1);  // CB_POS
451//    send(256 + 160);
452//    send(r4);         // index_bias
453//    r5 = load();      // start_instance
454//    if (r2) {
455   MME_INSN(0,  LOOP, ZERO,    R7,  ZERO,            0x000d,   NONE,   NONE,
456                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
457   MME_INSN(0,   ADD,   R3, LOAD0,  ZERO,          0x17dc/4, IMMED0,   NONE,
458                 ADD,   R2, LOAD1,  ZERO,                 0,   NONE,   NONE),
459   MME_INSN(0,   ADD, ZERO, LOAD0,  ZERO,                 0,   NONE,   ALU0,
460                 ADD,   R4, LOAD1,  ZERO,                 0,   NONE,   NONE),
461   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,  (1<<12)|0x238c/4, IMMED0, IMMED1,
462                 ADD, ZERO,    R4,  ZERO,         256 + 160,   NONE,   ALU1),
463   MME_INSN(0,   BEQ, ZERO,    R2,  ZERO,    (2<<14)|0x0008,   NONE,   NONE,
464                 ADD,   R5, LOAD0,  ZERO,                 0,   NONE,   NONE),
465//       send(r5);         // start_instance
466//       send(r6);         // draw_id
467//       mthd(0x1434, 1);  // VB_ELEMENT_BASE
468//       send(r4);         // index_bias
469//       send(r5);         // start_instance
470//       mthd(0x1118, 0);  // VERTEX_ID_BASE
471//       send(r4);         // index_bias
472//       r1 &= ~(1 << 26); // clear INSTANCE_NEXT
473   MME_INSN(0,   ADD, ZERO,    R5,  ZERO,                 0,   NONE,   ALU0,
474                 ADD, ZERO,    R6,  ZERO,                 0,   NONE,   ALU1),
475   MME_INSN(0,   ADD, ZERO,    R4,  ZERO,  (1<<12)|0x1434/4, IMMED0,   ALU0,
476                 ADD, ZERO,    R5,  ZERO,                 0,   NONE,   ALU1),
477   MME_INSN(0,   ADD, ZERO,    R4,  ZERO,          0x1118/4, IMMED0,   ALU0,
478               MERGE,   R1,    R1,  ZERO, (26<<10)|(1<<5)|0,   NONE,   NONE),
479//       do {
480//          mthd(0x1618, 0);  // VERTEX_BEGIN_GL
481//          send(r1);         // mode
482//          mthd(0x17e0, 0);  // INDEX_BATCH_COUNT
483//          send(r3);         // count
484//          mthd(0x1614, 0);  // VERTEX_END_GL
485//          send(0);
486//          r1 |= (1 << 26);  // set INSTANCE_NEXT
487//       } while (--r2);
488//    }
489   MME_INSN(0,   ADD, ZERO,    R1,  ZERO,          0x1618/4, IMMED0,   ALU0,
490                 ADD, ZERO,    R3,  ZERO,          0x17e0/4, IMMED1,   ALU1),
491   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,          0x1614/4, IMMED0,   ALU0,
492                 ADD,   R4, IMMED,  ZERO,                 1,   NONE,   NONE),
493   MME_INSN(0, MERGE,   R1,    R1,    R4, (26<<10)|(1<<5)|0,   NONE,   NONE,
494                 SUB,   R2,    R2, IMMED,                 1,   NONE,   NONE),
495   MME_INSN(0,   BEQ, ZERO,    R2,  ZERO,    (1<<14)|0x3ffd,   NONE,   NONE,
496                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
497//   r6 = r6 + 1;
498// };
499   MME_INSN(0,   ADD,   R6,    R6, IMMED,                 1,   NONE,   NONE,
500                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
501// mthd(0x1434, 1);
502// send(r8);         // restore VB_ELEMENT_BASE
503// send(r9);         // restore VB_INSTANCE_BASE
504// mthd(0x1118, 0);
505// send(r8);         // restore VERTEX_ID_BASE
506   MME_INSN(1,   ADD, ZERO,    R8,  ZERO,  (1<<12)|0x1434/4, IMMED0,   ALU0,
507                 ADD, ZERO,    R9,  ZERO,                 0,   NONE,   ALU1),
508   MME_INSN(0,   ADD, ZERO,    R8,  ZERO,          0x1118/4, IMMED0,   ALU0,
509                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
510};
511
512uint32_t mmec597_draw_arrays_indirect_count[] = {
513// r1 = load();         // mode
514// r6 = load();         // start_drawid
515// r7 = load();         // numparams
516// r5 = load();         // totaldraws
517// r8 = read(0x1438);   // VB_INSTANCE_BASE
518// r5 = r5 - r6;        // remaining draws
519// if (r5 > r7)
520   MME_INSN(0,   ADD,   R1, LOAD0,  ZERO,                 0,   NONE,   NONE,
521                 ADD,   R6, LOAD1,  ZERO,                 0,   NONE,   NONE),
522   MME_INSN(0,   ADD,   R7, LOAD0,  ZERO,                 0,   NONE,   NONE,
523                 ADD,   R5, LOAD1,  ZERO,                 0,   NONE,   NONE),
524   MME_INSN(0, STATE,   R8, IMMED,  ZERO,          0x1438/4,   NONE,   NONE,
525                 SUB,   R5,    R5,    R6,                 0,   NONE,   NONE),
526   MME_INSN(0,   BLE, ZERO,    R5,    R7,    (2<<14)|0x0002,   NONE,   NONE,
527                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
528//    r5 = r7;
529   MME_INSN(0,   ADD,   R5,    R7,  ZERO,                 0,   NONE,   NONE,
530                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
531// if (r5 >= 0) {
532   MME_INSN(0,   BLT, ZERO,    R5,  ZERO,    (2<<14)|0x000e,   NONE,   NONE,
533                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
534//    while (HW_LOOP_COUNT < r5) {
535//       r2 = load();      // count
536//       r3 = load();      // instance_count
537//       mthd(0x0d74, 0);  // VERTEX_BUFFER_FIRST
538//       send(load());     // start
539//       r4 = load();      // start_instance
540//       if (r3) {
541   MME_INSN(0,  LOOP, ZERO,    R5,  ZERO,            0x000c,   NONE,   NONE,
542                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
543   MME_INSN(0,   ADD,   R2, LOAD0,  ZERO,          0x0d74/4, IMMED0,   NONE,
544                 ADD,   R3, LOAD1,  ZERO,                 0,   NONE,   NONE),
545   MME_INSN(0,   ADD, ZERO, LOAD0,  ZERO,                 0,   NONE,   ALU0,
546                 ADD,   R4, LOAD1,  ZERO,                 0,   NONE,   NONE),
547   MME_INSN(0,   BEQ, ZERO,    R3,  ZERO,    (2<<14)|0x0008,   NONE,   NONE,
548                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
549//          mthd(0x238c, 1);  // CB_POS
550//          send(256 + 160);
551//          send(0);          // base_vertex
552//          send(r4);         // start_instance
553//          send(r6);         // draw_id
554//          mthd(0x1438, 0);  // VB_INSTANCE_BASE
555//          send(r4);
556//          r1 &= ~(1 << 26); // clear INSTANCE_NEXT
557   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,  (1<<12)|0x238c/4, IMMED0, IMMED1,
558                 ADD, ZERO,  ZERO,  ZERO,           256+160,   NONE,   ALU0),
559   MME_INSN(0,   ADD, ZERO,    R4,  ZERO,                 0,   NONE,   ALU0,
560                 ADD, ZERO,    R6,  ZERO,                 0,   NONE,   ALU1),
561   MME_INSN(0,   ADD, ZERO,    R4,  ZERO,          0x1438/4, IMMED0,   ALU0,
562               MERGE,   R1,    R1,  ZERO, (26<<10)|(1<<5)|0,   NONE,   NONE),
563//          do {
564//             mthd(0x1618, 0);  // VERTEX_BEGIN_GL
565//             send(r1);         // mode
566//             mthd(0x0d78, 0);  // VERTEX_BUFFER_COUNT
567//             send(r2);
568//             mthd(0x1614, 0);  // VERTEX_END_GL
569//             send(0);
570//             r1 |= (1 << 26);  // set INSTANCE_NEXT
571//          } while (--r3);
572//       }
573   MME_INSN(0,   ADD, ZERO,    R1,  ZERO,          0x1618/4, IMMED0,   ALU0,
574                 ADD, ZERO,    R2,  ZERO,          0x0d78/4, IMMED1,   ALU1),
575   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,          0x1614/4, IMMED0,   ALU0,
576                 ADD,   R4, IMMED,  ZERO,                 1,   NONE,   NONE),
577   MME_INSN(0, MERGE,   R1,    R1,    R4, (26<<10)|(1<<5)|0,   NONE,   NONE,
578                 SUB,   R3,    R3, IMMED,                 1,   NONE,   NONE),
579   MME_INSN(0,   BEQ, ZERO,    R3,  ZERO,    (1<<14)|0x3ffd,   NONE,   NONE,
580                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
581//       r6 = r6 + 1;   // draw_id++
582//    }
583   MME_INSN(0,   ADD,   R6,    R6, IMMED,                 1,   NONE,   NONE,
584                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
585//    r7 = r7 - r5;  // unneeded params
586// }
587   MME_INSN(0,   SUB,   R7,    R7,    R5,                 0,   NONE,   NONE,
588                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
589// while (HW_LOOP_COUNT < r7) {
590//    load();
591//    load();
592//    load();
593//    load();
594// }
595   MME_INSN(0,  LOOP, ZERO,    R7,  ZERO,            0x0003,   NONE,   NONE,
596                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
597   MME_INSN(0,   ADD, ZERO, LOAD0,  ZERO,                 0,   NONE,   NONE,
598                 ADD, ZERO, LOAD1,  ZERO,                 0,   NONE,   NONE),
599   MME_INSN(0,   ADD, ZERO, LOAD0,  ZERO,                 0,   NONE,   NONE,
600                 ADD, ZERO, LOAD1,  ZERO,                 0,   NONE,   NONE),
601// exit mthd(0x1438, 0);   // VB_INSTANCE_BASE
602// send(r8);
603   MME_INSN(1,   ADD, ZERO,  ZERO,  ZERO,          0x1438/4, IMMED0,   NONE,
604                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
605   MME_INSN(0,   ADD, ZERO,    R8,  ZERO,                 0,   NONE,   ALU0,
606                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
607};
608
609uint32_t mmec597_draw_elts_indirect_count[] = {
610// r8 = read(0x1434);
611// r1 = load();
612// r9 = read(0x1438);
613// r6 = load();
614// r7 = load();
615// r5 = load();
616// r5 = r5 - r6;
617// if (r5 > r7)
618   MME_INSN(0, STATE,   R8, IMMED,  ZERO,          0x1434/4,   NONE,   NONE,
619                 ADD,   R1, LOAD0,  ZERO,                 0,   NONE,   NONE),
620   MME_INSN(0, STATE,   R9, IMMED,  ZERO,          0x1438/4,   NONE,   NONE,
621                 ADD,   R6, LOAD0,  ZERO,                 0,   NONE,   NONE),
622   MME_INSN(0,   ADD,   R7, LOAD0,  ZERO,                 0,   NONE,   NONE,
623                 ADD,   R5, LOAD1,  ZERO,                 0,   NONE,   NONE),
624   MME_INSN(0,   SUB,   R5,    R5,    R6,                 0,   NONE,   NONE,
625                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
626   MME_INSN(0,   BLE, ZERO,    R5,    R7,    (2<<14)|0x0002,   NONE,   NONE,
627                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
628//    r5 = r7;
629   MME_INSN(0,   ADD,   R5,    R7,  ZERO,                 0,   NONE,   NONE,
630                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
631// if (r5 >= 0) {
632   MME_INSN(0,   BLT, ZERO,    R5,  ZERO,    (2<<14)|0x000f,   NONE,   NONE,
633                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
634//    while (HW_LOOP_COUNT < r5) {
635//       r3 = load();
636//       r2 = load();
637//       mthd(0x17dc, 0);
638//       send(load());
639//       r4 = load();
640//       mthd(0x238c, 1);
641//       send(256 + 160);
642//       send(r4);
643//       r10 = load();
644//       if (r2) {
645   MME_INSN(0,  LOOP, ZERO,    R5,  ZERO,            0x000d,   NONE,   NONE,
646                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
647   MME_INSN(0,   ADD,   R3, LOAD0,  ZERO,  (0<<12)|0x17dc/4, IMMED0,   NONE,
648                 ADD,   R2, LOAD1,  ZERO,                 0,   NONE,   NONE),
649   MME_INSN(0,   ADD, ZERO, LOAD0,  ZERO,  (1<<12)|0x238c/4,   NONE,   ALU0,
650                 ADD,   R4, LOAD1,  ZERO,         256 + 160, IMMED0, IMMED1),
651   MME_INSN(0,   ADD, ZERO,    R4,  ZERO,                 0,   NONE,   ALU0,
652                 ADD,  R10, LOAD0,  ZERO,                 0,   NONE,   NONE),
653   MME_INSN(0,   BEQ, ZERO,    R2,  ZERO,    (2<<14)|0x0008,   NONE,   NONE,
654                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
655//          send(r10);
656//          send(r6);
657//          mthd(0x1434, 1);
658//          send(r4);
659//          send(r10);
660//          mthd(0x1118, 0);
661//          send(r4);
662//          r1 &= ~(1 << 26);
663   MME_INSN(0,   ADD, ZERO,   R10,  ZERO,                 0,   NONE,   ALU0,
664                 ADD, ZERO,    R6,  ZERO,                 0,   NONE,   ALU1),
665   MME_INSN(0,   ADD, ZERO,    R4,  ZERO,  (1<<12)|0x1434/4, IMMED0,   ALU0,
666                 ADD, ZERO,   R10,  ZERO,                 0,   NONE,   ALU1),
667   MME_INSN(0,   ADD, ZERO,    R4,  ZERO,  (0<<12)|0x1118/4, IMMED0,   ALU0,
668               MERGE,   R1,    R1,  ZERO, (26<<10)|(1<<5)|0,   NONE,   NONE),
669//          do {
670//             mthd(0x1618, 0);
671//             send(r1);
672//             mthd(0x17e0, 0);
673//             send(r3);
674//             mthd(0x1614, 0);
675//             send(0);
676//             r1 |= (1 << 26);
677//          } while (--r2);
678//       }
679   MME_INSN(0,   ADD, ZERO,    R1,  ZERO,          0x1618/4, IMMED0,   ALU0,
680                 ADD, ZERO,    R3,  ZERO,          0x17e0/4, IMMED1,   ALU1),
681   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,          0x1614/4, IMMED0,   ALU0,
682                 ADD,   R4, IMMED,  ZERO,                 1,   NONE,   NONE),
683   MME_INSN(0, MERGE,   R1,    R1,    R4, (26<<10)|(1<<5)|0,   NONE,   NONE,
684                 SUB,   R2,    R2, IMMED,                 1,   NONE,   NONE),
685   MME_INSN(0,   BEQ, ZERO,    R2,  ZERO,    (1<<14)|0x3ffd,   NONE,   NONE,
686                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
687//       r6 = r6 + 1;
688//    }
689   MME_INSN(0,   ADD,   R6,    R6, IMMED,                 1,   NONE,   NONE,
690                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
691//    r7 = r7 - r5; // unneeded params
692// }
693   MME_INSN(0,   SUB,   R7,    R7,    R5,                 0,   NONE,   NONE,
694                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
695// while (HW_LOOP_COUNT < r7) {
696//    r2 = load();
697//    r2 = load();
698//    r2 = load();
699//    r2 = load();
700//    r2 = load();
701// }
702   MME_INSN(0,  LOOP, ZERO,    R7,  ZERO,            0x0004,   NONE,   NONE,
703                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
704   MME_INSN(0,   ADD, ZERO, LOAD0,  ZERO,                 0,   NONE,   NONE,
705                 ADD, ZERO, LOAD1,  ZERO,                 0,   NONE,   NONE),
706   MME_INSN(0,   ADD, ZERO, LOAD0,  ZERO,                 0,   NONE,   NONE,
707                 ADD, ZERO, LOAD1,  ZERO,                 0,   NONE,   NONE),
708   MME_INSN(0,   ADD, ZERO, LOAD0,  ZERO,                 0,   NONE,   NONE,
709                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
710// mthd(0x1434, 1);
711// send(r8);
712// send(r9);
713// exit mthd(0x1118, 0);
714// send(r8);
715   MME_INSN(1,   ADD, ZERO,    R8,  ZERO,  (1<<12)|0x1434/4, IMMED0,   ALU0,
716                 ADD, ZERO,    R9,  ZERO,                 0,   NONE,   ALU1),
717   MME_INSN(0,   ADD, ZERO,    R8,  ZERO,  (0<<12)|0x1118/4, IMMED0,   ALU0,
718                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,   NONE),
719};
720
721uint32_t mmec597_query_buffer_write[] = {
722// r1 = load();   // clamp value
723// r2 = load();   // end value (lo)
724// r3 = load();   // end value (hi)
725// r4 = load();   // start value (lo)
726// r5 = load();   // start value (hi)
727// r8 = load();   // desired sequence
728// r9 = load();   // actual sequence
729// r7 = load();   // query address (hi)
730// r6 = load();   // query address (lo)
731// if (r9 >= r8) {
732   MME_INSN(0,   ADD,   R1, LOAD0,  ZERO,                 0,   NONE,      NONE,
733                 ADD,   R2, LOAD1,  ZERO,                 0,   NONE,      NONE),
734   MME_INSN(0,   ADD,   R3, LOAD0,  ZERO,                 0,   NONE,      NONE,
735                 ADD,   R4, LOAD1,  ZERO,                 0,   NONE,      NONE),
736   MME_INSN(0,   ADD,   R5, LOAD0,  ZERO,                 0,   NONE,      NONE,
737                 ADD,   R8, LOAD1,  ZERO,                 0,   NONE,      NONE),
738   MME_INSN(0,   ADD,   R9, LOAD0,  ZERO,                 0,   NONE,      NONE,
739                 ADD,   R7, LOAD1,  ZERO,                 0,   NONE,      NONE),
740   MME_INSN(0,   ADD,   R6, LOAD0,  ZERO,                 0,   NONE,      NONE,
741                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
742   MME_INSN(0,   BLT, ZERO,    R9,    R8,    (2<<14)|0x000e,   NONE,      NONE,
743                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
744//    [r3,r2] = [r3,r2] - [r5,r4];
745//    if (r1) {
746   MME_INSN(0,   SUB,   R2,    R2,    R4,                 0,   NONE,      NONE,
747                SUBB,   R3,    R3,    R5,                 0,   NONE,      NONE),
748   MME_INSN(0,   BEQ, ZERO,    R1,  ZERO,    (2<<14)|0x0004,   NONE,      NONE,
749                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
750//       if (r3 != 0 || r1 < r2)
751//          r2 = r1;
752//    }
753   MME_INSN(0,   BEQ, ZERO,    R3,  ZERO,    (1<<14)|0x0002,   NONE,      NONE,
754                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
755   MME_INSN(0,  BLTU, ZERO,    R1,    R2,    (1<<14)|0x0002,   NONE,      NONE,
756                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
757   MME_INSN(0,   ADD,   R2,    R1,  ZERO,                 0,   NONE,      NONE,
758                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
759//    mthd(0x1b00, 1);
760//    send(r7);
761//    send(r6);
762//    send(r2)
763//    send(0x10000000);
764//    if (!r1) {
765   MME_INSN(0,   ADD, ZERO,    R7,  ZERO,  (1<<12)|0x1b00/4, IMMED0,      ALU0,
766                 ADD, ZERO,    R6,  ZERO,                 0,   NONE,      ALU1),
767   MME_INSN(0,   ADD, ZERO,    R2,  ZERO,                 0,   NONE,      ALU0,
768                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
769   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,            0x1000,   NONE, IMMED32_0,
770                 ADD, ZERO,  ZERO,  ZERO,            0x0000,   NONE,      NONE),
771   MME_INSN(0,   BEQ, ZERO,    R1,  ZERO,    (1<<14)|0x0004,   NONE,      NONE,
772                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
773//       [r7,r6] = [r7,r6] + 4;
774//       mthd(0x1b00, 1);
775//       send(r7);
776//       send(r6);
777//       send(r3);
778//       send(0x10000000);
779//    }
780   MME_INSN(0,   ADD, ZERO,    R6, IMMED,                 4, IMMED1,      ALU1,
781                ADDC, ZERO,    R7,  ZERO,  (1<<12)|0x1b00/4,   NONE,      ALU0),
782   MME_INSN(0,   ADD, ZERO,    R3,  ZERO,                 0,   NONE,      ALU0,
783                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
784   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,            0x1000,   NONE, IMMED32_0,
785                 ADD, ZERO,  ZERO,  ZERO,            0x0000,   NONE,      NONE),
786//    mthd(0x0110, 0);
787//    send(0);
788   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,  (0<<12)|0x0110/4, IMMED0,      ALU0,
789                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
790// }
791   MME_INSN(1,   ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE,
792                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
793   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE,
794                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
795};
796
797uint32_t mmec597_conservative_raster_state[] = {
798// r1 = load();
799// mthd(0x3400, 1);
800// send(0);
801// send(((r1 >> 8) & 7) << 23);
802// send(0x03800000);
803// mthd(0x2310, 1);
804// send(0x00418800);
805// r2 = r1 & 0xf;
806// r3 = 16;
807// r2 = r2 | (((r1 >> 4) & 0xf) << 8);
808// mthd(0x0a1c, 8);
809   MME_INSN(0,   ADD,   R1, LOAD0,  ZERO,  (1<<12)|0x3400/4, IMMED0,    IMMED1,
810                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
811   MME_INSN(0, MERGE, ZERO,  ZERO,    R1, (23<<10)|(3<<5)|8,   NONE,      ALU0,
812                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
813   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,            0x0380,   NONE, IMMED32_0,
814                 ADD, ZERO,  ZERO,  ZERO,            0x0000,   NONE,      NONE),
815   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,  (1<<12)|0x2310/4, IMMED0,      NONE,
816                 ADD, ZERO,  ZERO,  ZERO,            0x0000,   NONE,      NONE),
817   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,            0x0041,   NONE, IMMED32_0,
818                 ADD, ZERO,  ZERO,  ZERO,            0x8800,   NONE,      NONE),
819   MME_INSN(0,   AND,   R2,    R1, IMMED,               0xf,   NONE,      NONE,
820                 ADD,   R3,  ZERO, IMMED,                16,   NONE,      NONE),
821   MME_INSN(0, MERGE,   R2,    R2,    R1,  (8<<10)|(4<<5)|4, IMMED1,      NONE,
822                 ADD, ZERO,  ZERO,  ZERO,  (8<<12)|0x0a1c/4,   NONE,      NONE),
823// while (HW_LOOP_COUNT < r3)
824//    send(r2);
825   MME_INSN(0,  LOOP, ZERO,    R3,  ZERO,            0x0002,   NONE,      NONE,
826                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
827   MME_INSN(0,   ADD, ZERO,    R2,  ZERO,                 0,   NONE,      ALU0,
828                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
829// mthd(0x1148, 0);
830// send(1);
831   MME_INSN(1,   ADD, ZERO,  ZERO,  ZERO,  (0<<12)|0x1148/4, IMMED0,      NONE,
832                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
833   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,                 1,   NONE,    IMMED1,
834                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
835};
836
837uint32_t mmec597_compute_counter[] = {
838// r0 = load();
839// r1 = 1;
840// r2 = 0;
841// while (HW_LOOP_COUNT < r2) {
842   MME_INSN(0,   ADD,   R0, LOAD0,  ZERO,                 0,   NONE,      NONE,
843                 ADD,   R1, IMMED,  ZERO,                 1,   NONE,      NONE),
844   MME_INSN(0,  LOOP, ZERO,    R0,  ZERO,            0x0003,   NONE,      NONE,
845                 ADD,   R2,  ZERO,  ZERO,                 0,   NONE,      NONE),
846//    r3 = load();
847//    [r1,r0] *= r3;
848// }
849   MME_INSN(0,   ADD,   R3, LOAD0,  ZERO,                 0,   NONE,      NONE,
850                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
851   MME_INSN(0,  MULU,   R1,    R1,    R3,                 0,   NONE,      NONE,
852                MULH,   R2,  ZERO,  ZERO,                 0,   NONE,      NONE),
853// r3 = read(0x3410);
854// r4 = read(0x3414);
855// [r4,r3] += [r2,r1];
856// mthd(0x3410, 1);
857// send(r3);
858// send(r4);
859   MME_INSN(0, STATE, ZERO,  ZERO,  ZERO,          0x3410/4,   NONE,      NONE,
860                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
861   MME_INSN(1, STATE, ZERO,  ZERO,  ZERO,          0x3414/4,   NONE,      NONE,
862                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
863   MME_INSN(0,   ADD,   R3,    R3,    R1,  (1<<12)|0x3410/4, IMMED0,      ALU0,
864                ADDC,   R4,    R4,    R2,                 0,   NONE,      ALU1),
865};
866
867uint32_t mmec597_compute_counter_to_query[] = {
868// r1 = load();
869// r3 = read(0x3410);
870// r2 = load();
871// r4 = read(0x3414);
872// [r2,r1] = [r2,r1] + [r4,r3];
873// mthd(0x1b00, 1);
874// r3 = load();
875// send(r3);
876// r4 = load();
877// send(r4);
878// send(r1);
879// send(0x10000000);
880   MME_INSN(0,   ADD,   R1, LOAD0,  ZERO,                 0,   NONE,      NONE,
881               STATE,   R3, IMMED,  ZERO,          0x3410/4,   NONE,      NONE),
882   MME_INSN(0,   ADD,   R2, LOAD0,  ZERO,                 0,   NONE,      NONE,
883               STATE,   R4, IMMED,  ZERO,          0x3414/4,   NONE,      NONE),
884   MME_INSN(0,   ADD,   R1,    R1,    R3,  (1<<12)|0x1b00/4, IMMED0,      NONE,
885                ADDC,   R2,    R2,    R4,                 0,   NONE,      NONE),
886   MME_INSN(0,   ADD,   R3, LOAD0,  ZERO,                 0,   NONE,      ALU0,
887                 ADD,   R4, LOAD1,  ZERO,                 0,   NONE,      ALU1),
888   MME_INSN(0,   ADD, ZERO,    R1,  ZERO,                 0,   NONE,      ALU0,
889                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
890   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,            0x1000,   NONE, IMMED32_0,
891                 ADD, ZERO,  ZERO,  ZERO,            0x0000,   NONE,      NONE),
892// [r3,r4] = [r3,r4] + 4;
893// mthd(0x1b00, 1);
894// send(r3);
895// send(r4);
896// send(r2);
897// send(0x10000000);
898   MME_INSN(0,   ADD, ZERO,    R4, IMMED,                 4, IMMED1,      ALU1,
899                ADDC, ZERO,    R3,  ZERO,  (1<<12)|0x1b00/4,   NONE,      ALU0),
900   MME_INSN(1,   ADD, ZERO,    R2,  ZERO,                 0,   NONE,      ALU0,
901                 ADD, ZERO,  ZERO,  ZERO,                 0,   NONE,      NONE),
902   MME_INSN(0,   ADD, ZERO,  ZERO,  ZERO,            0x1000,   NONE, IMMED32_0,
903                 ADD, ZERO,  ZERO,  ZERO,            0x0000,   NONE,      NONE),
904};
905