xref: /aosp_15_r20/external/mesa3d/src/imagination/rogue/rogue_encode.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2022 Imagination Technologies Ltd.
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
5*61046927SAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to deal
6*61046927SAndroid Build Coastguard Worker  * in the Software without restriction, including without limitation the rights
7*61046927SAndroid Build Coastguard Worker  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8*61046927SAndroid Build Coastguard Worker  * copies of the Software, and to permit persons to whom the Software is
9*61046927SAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18*61046927SAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20*61046927SAndroid Build Coastguard Worker  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21*61046927SAndroid Build Coastguard Worker  * SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #include "rogue.h"
25*61046927SAndroid Build Coastguard Worker #include "rogue_isa.h"
26*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
27*61046927SAndroid Build Coastguard Worker #include "util/u_dynarray.h"
28*61046927SAndroid Build Coastguard Worker 
29*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
30*61046927SAndroid Build Coastguard Worker 
31*61046927SAndroid Build Coastguard Worker /**
32*61046927SAndroid Build Coastguard Worker  * \file rogue_encode.c
33*61046927SAndroid Build Coastguard Worker  *
34*61046927SAndroid Build Coastguard Worker  * \brief Contains hardware encoding functions.
35*61046927SAndroid Build Coastguard Worker  */
36*61046927SAndroid Build Coastguard Worker 
37*61046927SAndroid Build Coastguard Worker #define util_dynarray_append_mem(buf, size, mem) \
38*61046927SAndroid Build Coastguard Worker    memcpy(util_dynarray_grow_bytes((buf), 1, size), mem, size)
39*61046927SAndroid Build Coastguard Worker 
rogue_calc_da(const rogue_instr_group * group)40*61046927SAndroid Build Coastguard Worker static unsigned rogue_calc_da(const rogue_instr_group *group)
41*61046927SAndroid Build Coastguard Worker {
42*61046927SAndroid Build Coastguard Worker    unsigned da = group->size.header;
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker    if (group->header.alu == ROGUE_ALU_MAIN) {
45*61046927SAndroid Build Coastguard Worker       for (unsigned u = ROGUE_INSTR_PHASE_COUNT; u > 0; --u) {
46*61046927SAndroid Build Coastguard Worker          enum rogue_instr_phase p = u - 1;
47*61046927SAndroid Build Coastguard Worker          if (p > ROGUE_INSTR_PHASE_1)
48*61046927SAndroid Build Coastguard Worker             da += group->size.instrs[p];
49*61046927SAndroid Build Coastguard Worker       }
50*61046927SAndroid Build Coastguard Worker    } else if (group->header.alu == ROGUE_ALU_BITWISE) {
51*61046927SAndroid Build Coastguard Worker       for (unsigned u = ROGUE_INSTR_PHASE_COUNT; u > 0; --u) {
52*61046927SAndroid Build Coastguard Worker          enum rogue_instr_phase p = u - 1;
53*61046927SAndroid Build Coastguard Worker          da += group->size.instrs[p];
54*61046927SAndroid Build Coastguard Worker       }
55*61046927SAndroid Build Coastguard Worker    } else if (group->header.alu == ROGUE_ALU_CONTROL) {
56*61046927SAndroid Build Coastguard Worker       const rogue_instr *instr = group->instrs[ROGUE_INSTR_PHASE_CTRL];
57*61046927SAndroid Build Coastguard Worker       const rogue_ctrl_instr *ctrl = rogue_instr_as_ctrl(instr);
58*61046927SAndroid Build Coastguard Worker 
59*61046927SAndroid Build Coastguard Worker       if (!rogue_ctrl_op_has_srcs(ctrl->op) &&
60*61046927SAndroid Build Coastguard Worker           !rogue_ctrl_op_has_dsts(ctrl->op)) {
61*61046927SAndroid Build Coastguard Worker          da = 0;
62*61046927SAndroid Build Coastguard Worker       } else {
63*61046927SAndroid Build Coastguard Worker          da += group->size.instrs[ROGUE_INSTR_PHASE_CTRL];
64*61046927SAndroid Build Coastguard Worker       }
65*61046927SAndroid Build Coastguard Worker 
66*61046927SAndroid Build Coastguard Worker    } else {
67*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported instruction group ALU.");
68*61046927SAndroid Build Coastguard Worker    }
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker    return da;
71*61046927SAndroid Build Coastguard Worker }
72*61046927SAndroid Build Coastguard Worker 
73*61046927SAndroid Build Coastguard Worker #define P(type) BITFIELD64_BIT(ROGUE_INSTR_PHASE_##type)
rogue_calc_oporg(uint64_t alu_phases)74*61046927SAndroid Build Coastguard Worker static enum oporg rogue_calc_oporg(uint64_t alu_phases)
75*61046927SAndroid Build Coastguard Worker {
76*61046927SAndroid Build Coastguard Worker    bool P0 = !!(alu_phases & P(0));
77*61046927SAndroid Build Coastguard Worker    bool P1 = !!(alu_phases & P(1));
78*61046927SAndroid Build Coastguard Worker    bool P2 = !!(alu_phases & (P(2_PCK) | P(2_TST) | P(2_MOV)));
79*61046927SAndroid Build Coastguard Worker    bool PBE = !!(alu_phases & P(BACKEND));
80*61046927SAndroid Build Coastguard Worker 
81*61046927SAndroid Build Coastguard Worker    if (P0 && P1 && P2 && PBE)
82*61046927SAndroid Build Coastguard Worker       return OPORG_P0_P1_P2_BE;
83*61046927SAndroid Build Coastguard Worker    else if (P0 && !P1 && P2 && PBE)
84*61046927SAndroid Build Coastguard Worker       return OPORG_P0_P2_BE;
85*61046927SAndroid Build Coastguard Worker    else if (P0 && P1 && P2 && !PBE)
86*61046927SAndroid Build Coastguard Worker       return OPORG_P0_P1_P2;
87*61046927SAndroid Build Coastguard Worker    else if (P0 && !P1 && P2 && !PBE)
88*61046927SAndroid Build Coastguard Worker       return OPORG_P0_P2;
89*61046927SAndroid Build Coastguard Worker    else if (P0 && P1 && !P2 && !PBE)
90*61046927SAndroid Build Coastguard Worker       return OPORG_P0_P1;
91*61046927SAndroid Build Coastguard Worker    else if (!P0 && !P1 && !P2 && PBE)
92*61046927SAndroid Build Coastguard Worker       return OPORG_BE;
93*61046927SAndroid Build Coastguard Worker    else if (!P0 && !P1 && P2 && !PBE)
94*61046927SAndroid Build Coastguard Worker       return OPORG_P2;
95*61046927SAndroid Build Coastguard Worker    else if (P0 && !P1 && !P2 && !PBE)
96*61046927SAndroid Build Coastguard Worker       return OPORG_P0;
97*61046927SAndroid Build Coastguard Worker 
98*61046927SAndroid Build Coastguard Worker    unreachable("Invalid ALU phase combination.");
99*61046927SAndroid Build Coastguard Worker }
100*61046927SAndroid Build Coastguard Worker 
rogue_calc_opcnt(uint64_t bitwise_phases)101*61046927SAndroid Build Coastguard Worker static enum opcnt rogue_calc_opcnt(uint64_t bitwise_phases)
102*61046927SAndroid Build Coastguard Worker {
103*61046927SAndroid Build Coastguard Worker    enum opcnt opcnt = 0;
104*61046927SAndroid Build Coastguard Worker 
105*61046927SAndroid Build Coastguard Worker    if (bitwise_phases & P(0_BITMASK) || bitwise_phases & P(0_SHIFT1) ||
106*61046927SAndroid Build Coastguard Worker        bitwise_phases & P(0_COUNT)) {
107*61046927SAndroid Build Coastguard Worker       opcnt |= OPCNT_P0;
108*61046927SAndroid Build Coastguard Worker    }
109*61046927SAndroid Build Coastguard Worker 
110*61046927SAndroid Build Coastguard Worker    if (bitwise_phases & P(1_LOGICAL))
111*61046927SAndroid Build Coastguard Worker       opcnt |= OPCNT_P1;
112*61046927SAndroid Build Coastguard Worker 
113*61046927SAndroid Build Coastguard Worker    if (bitwise_phases & P(2_SHIFT2) || bitwise_phases & P(2_TEST))
114*61046927SAndroid Build Coastguard Worker       opcnt |= OPCNT_P2;
115*61046927SAndroid Build Coastguard Worker 
116*61046927SAndroid Build Coastguard Worker    return opcnt;
117*61046927SAndroid Build Coastguard Worker }
118*61046927SAndroid Build Coastguard Worker 
rogue_encode_instr_group_header(rogue_instr_group * group,struct util_dynarray * binary)119*61046927SAndroid Build Coastguard Worker static void rogue_encode_instr_group_header(rogue_instr_group *group,
120*61046927SAndroid Build Coastguard Worker                                             struct util_dynarray *binary)
121*61046927SAndroid Build Coastguard Worker {
122*61046927SAndroid Build Coastguard Worker    rogue_instr_group_header_encoding h = { 0 };
123*61046927SAndroid Build Coastguard Worker 
124*61046927SAndroid Build Coastguard Worker    h.da = rogue_calc_da(group);
125*61046927SAndroid Build Coastguard Worker    h.length = (group->size.total / 2) % 16;
126*61046927SAndroid Build Coastguard Worker    h.ext = (group->size.header == 3);
127*61046927SAndroid Build Coastguard Worker 
128*61046927SAndroid Build Coastguard Worker    rogue_ref *w0ref = rogue_instr_group_io_sel_ref(&group->io_sel, ROGUE_IO_W0);
129*61046927SAndroid Build Coastguard Worker    rogue_ref *w1ref = rogue_instr_group_io_sel_ref(&group->io_sel, ROGUE_IO_W1);
130*61046927SAndroid Build Coastguard Worker 
131*61046927SAndroid Build Coastguard Worker    /* TODO: Update this - needs to be set for MOVMSK, and if instruction group
132*61046927SAndroid Build Coastguard Worker     * READS OR WRITES to/from pixout regs. */
133*61046927SAndroid Build Coastguard Worker    h.olchk = rogue_ref_is_pixout(w0ref) || rogue_ref_is_pixout(w1ref);
134*61046927SAndroid Build Coastguard Worker    h.w1p = !rogue_ref_is_null(w1ref);
135*61046927SAndroid Build Coastguard Worker    h.w0p = !rogue_ref_is_null(w0ref);
136*61046927SAndroid Build Coastguard Worker 
137*61046927SAndroid Build Coastguard Worker    rogue_cc cc = { 0 };
138*61046927SAndroid Build Coastguard Worker    switch (group->header.exec_cond) {
139*61046927SAndroid Build Coastguard Worker    case ROGUE_EXEC_COND_PE_TRUE:
140*61046927SAndroid Build Coastguard Worker       cc._ = CC_PE_TRUE;
141*61046927SAndroid Build Coastguard Worker       break;
142*61046927SAndroid Build Coastguard Worker 
143*61046927SAndroid Build Coastguard Worker    case ROGUE_EXEC_COND_P0_TRUE:
144*61046927SAndroid Build Coastguard Worker       cc._ = CC_P0_TRUE;
145*61046927SAndroid Build Coastguard Worker       break;
146*61046927SAndroid Build Coastguard Worker 
147*61046927SAndroid Build Coastguard Worker    case ROGUE_EXEC_COND_PE_ANY:
148*61046927SAndroid Build Coastguard Worker       cc._ = CC_PE_ANY;
149*61046927SAndroid Build Coastguard Worker       break;
150*61046927SAndroid Build Coastguard Worker 
151*61046927SAndroid Build Coastguard Worker    case ROGUE_EXEC_COND_P0_FALSE:
152*61046927SAndroid Build Coastguard Worker       cc._ = CC_P0_FALSE;
153*61046927SAndroid Build Coastguard Worker       break;
154*61046927SAndroid Build Coastguard Worker 
155*61046927SAndroid Build Coastguard Worker    default:
156*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported condition code.");
157*61046927SAndroid Build Coastguard Worker    }
158*61046927SAndroid Build Coastguard Worker 
159*61046927SAndroid Build Coastguard Worker    h.cc = cc.cc;
160*61046927SAndroid Build Coastguard Worker    h.ccext = cc.ccext;
161*61046927SAndroid Build Coastguard Worker 
162*61046927SAndroid Build Coastguard Worker    switch (group->header.alu) {
163*61046927SAndroid Build Coastguard Worker    case ROGUE_ALU_MAIN:
164*61046927SAndroid Build Coastguard Worker       h.alutype = ALUTYPE_MAIN;
165*61046927SAndroid Build Coastguard Worker       h.oporg = rogue_calc_oporg(group->header.phases);
166*61046927SAndroid Build Coastguard Worker       break;
167*61046927SAndroid Build Coastguard Worker 
168*61046927SAndroid Build Coastguard Worker    case ROGUE_ALU_BITWISE:
169*61046927SAndroid Build Coastguard Worker       h.alutype = ALUTYPE_BITWISE;
170*61046927SAndroid Build Coastguard Worker       h.opcnt = rogue_calc_opcnt(group->header.phases);
171*61046927SAndroid Build Coastguard Worker       break;
172*61046927SAndroid Build Coastguard Worker 
173*61046927SAndroid Build Coastguard Worker    case ROGUE_ALU_CONTROL:
174*61046927SAndroid Build Coastguard Worker       h.alutype = ALUTYPE_CONTROL;
175*61046927SAndroid Build Coastguard Worker #define OM(op_mod) ROGUE_CTRL_OP_MOD_##op_mod
176*61046927SAndroid Build Coastguard Worker       const rogue_instr *instr = group->instrs[ROGUE_INSTR_PHASE_CTRL];
177*61046927SAndroid Build Coastguard Worker       const rogue_ctrl_instr *ctrl = rogue_instr_as_ctrl(instr);
178*61046927SAndroid Build Coastguard Worker       switch (ctrl->op) {
179*61046927SAndroid Build Coastguard Worker       case ROGUE_CTRL_OP_NOP:
180*61046927SAndroid Build Coastguard Worker          h.ctrlop = CTRLOP_NOP;
181*61046927SAndroid Build Coastguard Worker          h.miscctl = rogue_ctrl_op_mod_is_set(ctrl, OM(END));
182*61046927SAndroid Build Coastguard Worker          break;
183*61046927SAndroid Build Coastguard Worker 
184*61046927SAndroid Build Coastguard Worker       case ROGUE_CTRL_OP_WOP:
185*61046927SAndroid Build Coastguard Worker          h.ctrlop = CTRLOP_WOP;
186*61046927SAndroid Build Coastguard Worker          break;
187*61046927SAndroid Build Coastguard Worker 
188*61046927SAndroid Build Coastguard Worker       case ROGUE_CTRL_OP_BR:
189*61046927SAndroid Build Coastguard Worker       case ROGUE_CTRL_OP_BA:
190*61046927SAndroid Build Coastguard Worker          h.ctrlop = CTRLOP_BA;
191*61046927SAndroid Build Coastguard Worker          break;
192*61046927SAndroid Build Coastguard Worker 
193*61046927SAndroid Build Coastguard Worker       case ROGUE_CTRL_OP_WDF:
194*61046927SAndroid Build Coastguard Worker          h.ctrlop = CTRLOP_WDF;
195*61046927SAndroid Build Coastguard Worker          h.miscctl = rogue_ref_get_drc_index(&ctrl->src[0].ref);
196*61046927SAndroid Build Coastguard Worker          break;
197*61046927SAndroid Build Coastguard Worker 
198*61046927SAndroid Build Coastguard Worker       default:
199*61046927SAndroid Build Coastguard Worker          unreachable("Unsupported ctrl op.");
200*61046927SAndroid Build Coastguard Worker       }
201*61046927SAndroid Build Coastguard Worker #undef OM
202*61046927SAndroid Build Coastguard Worker       break;
203*61046927SAndroid Build Coastguard Worker 
204*61046927SAndroid Build Coastguard Worker    default:
205*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported instruction group ALU.");
206*61046927SAndroid Build Coastguard Worker    }
207*61046927SAndroid Build Coastguard Worker 
208*61046927SAndroid Build Coastguard Worker    if (group->header.alu != ROGUE_ALU_CONTROL) {
209*61046927SAndroid Build Coastguard Worker       h.end = group->header.end;
210*61046927SAndroid Build Coastguard Worker       /* h.atom = ; */ /* Unused for now */
211*61046927SAndroid Build Coastguard Worker       h.rpt = group->header.repeat - 1;
212*61046927SAndroid Build Coastguard Worker    }
213*61046927SAndroid Build Coastguard Worker 
214*61046927SAndroid Build Coastguard Worker    util_dynarray_append_mem(binary, group->size.header, &h);
215*61046927SAndroid Build Coastguard Worker }
216*61046927SAndroid Build Coastguard Worker #undef P
217*61046927SAndroid Build Coastguard Worker 
218*61046927SAndroid Build Coastguard Worker typedef union rogue_instr_encoding {
219*61046927SAndroid Build Coastguard Worker    rogue_alu_instr_encoding alu;
220*61046927SAndroid Build Coastguard Worker    rogue_backend_instr_encoding backend;
221*61046927SAndroid Build Coastguard Worker    rogue_ctrl_instr_encoding ctrl;
222*61046927SAndroid Build Coastguard Worker    rogue_bitwise_instr_encoding bitwise;
223*61046927SAndroid Build Coastguard Worker } PACKED rogue_instr_encoding;
224*61046927SAndroid Build Coastguard Worker 
rogue_alu_movc_ft(const rogue_ref * ref)225*61046927SAndroid Build Coastguard Worker static unsigned rogue_alu_movc_ft(const rogue_ref *ref)
226*61046927SAndroid Build Coastguard Worker {
227*61046927SAndroid Build Coastguard Worker    switch (rogue_ref_get_io(ref)) {
228*61046927SAndroid Build Coastguard Worker    case ROGUE_IO_NONE:
229*61046927SAndroid Build Coastguard Worker    case ROGUE_IO_FT0:
230*61046927SAndroid Build Coastguard Worker       return MOVW_FT0;
231*61046927SAndroid Build Coastguard Worker 
232*61046927SAndroid Build Coastguard Worker    case ROGUE_IO_FT1:
233*61046927SAndroid Build Coastguard Worker       return MOVW_FT1;
234*61046927SAndroid Build Coastguard Worker 
235*61046927SAndroid Build Coastguard Worker    case ROGUE_IO_FT2:
236*61046927SAndroid Build Coastguard Worker       return MOVW_FT2;
237*61046927SAndroid Build Coastguard Worker 
238*61046927SAndroid Build Coastguard Worker    case ROGUE_IO_FTE:
239*61046927SAndroid Build Coastguard Worker       return MOVW_FTE;
240*61046927SAndroid Build Coastguard Worker 
241*61046927SAndroid Build Coastguard Worker    default:
242*61046927SAndroid Build Coastguard Worker       break;
243*61046927SAndroid Build Coastguard Worker    }
244*61046927SAndroid Build Coastguard Worker 
245*61046927SAndroid Build Coastguard Worker    unreachable("Invalid source.");
246*61046927SAndroid Build Coastguard Worker }
247*61046927SAndroid Build Coastguard Worker 
248*61046927SAndroid Build Coastguard Worker #define SM(src_mod) ROGUE_ALU_SRC_MOD_##src_mod
249*61046927SAndroid Build Coastguard Worker #define DM(dst_mod) ROGUE_ALU_DST_MOD_##dst_mod
250*61046927SAndroid Build Coastguard Worker #define OM(op_mod) ROGUE_ALU_OP_MOD_##op_mod
rogue_encode_alu_instr(const rogue_alu_instr * alu,unsigned instr_size,rogue_instr_encoding * instr_encoding)251*61046927SAndroid Build Coastguard Worker static void rogue_encode_alu_instr(const rogue_alu_instr *alu,
252*61046927SAndroid Build Coastguard Worker                                    unsigned instr_size,
253*61046927SAndroid Build Coastguard Worker                                    rogue_instr_encoding *instr_encoding)
254*61046927SAndroid Build Coastguard Worker {
255*61046927SAndroid Build Coastguard Worker    switch (alu->op) {
256*61046927SAndroid Build Coastguard Worker    case ROGUE_ALU_OP_MBYP:
257*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.op = ALUOP_SNGL;
258*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.sngl.snglop = SNGLOP_BYP;
259*61046927SAndroid Build Coastguard Worker 
260*61046927SAndroid Build Coastguard Worker       if (instr_size == 2) {
261*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.sngl.ext0 = 1;
262*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.sngl.mbyp.s0neg =
263*61046927SAndroid Build Coastguard Worker             rogue_alu_src_mod_is_set(alu, 0, SM(NEG));
264*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.sngl.mbyp.s0abs =
265*61046927SAndroid Build Coastguard Worker             rogue_alu_src_mod_is_set(alu, 0, SM(ABS));
266*61046927SAndroid Build Coastguard Worker       }
267*61046927SAndroid Build Coastguard Worker       break;
268*61046927SAndroid Build Coastguard Worker 
269*61046927SAndroid Build Coastguard Worker    case ROGUE_ALU_OP_FMUL:
270*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.op = ALUOP_FMUL;
271*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.fmul.lp = rogue_alu_op_mod_is_set(alu, OM(LP));
272*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.fmul.sat = rogue_alu_op_mod_is_set(alu, OM(SAT));
273*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.fmul.s0neg =
274*61046927SAndroid Build Coastguard Worker          rogue_alu_src_mod_is_set(alu, 0, SM(NEG));
275*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.fmul.s0abs =
276*61046927SAndroid Build Coastguard Worker          rogue_alu_src_mod_is_set(alu, 0, SM(ABS));
277*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.fmul.s1abs =
278*61046927SAndroid Build Coastguard Worker          rogue_alu_src_mod_is_set(alu, 1, SM(ABS));
279*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.fmul.s0flr =
280*61046927SAndroid Build Coastguard Worker          rogue_alu_src_mod_is_set(alu, 0, SM(FLR));
281*61046927SAndroid Build Coastguard Worker       break;
282*61046927SAndroid Build Coastguard Worker 
283*61046927SAndroid Build Coastguard Worker    case ROGUE_ALU_OP_FMAD:
284*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.op = ALUOP_FMAD;
285*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.fmad.s0neg =
286*61046927SAndroid Build Coastguard Worker          rogue_alu_src_mod_is_set(alu, 0, SM(NEG));
287*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.fmad.s0abs =
288*61046927SAndroid Build Coastguard Worker          rogue_alu_src_mod_is_set(alu, 0, SM(ABS));
289*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.fmad.s2neg =
290*61046927SAndroid Build Coastguard Worker          rogue_alu_src_mod_is_set(alu, 2, SM(NEG));
291*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.fmad.sat = rogue_alu_op_mod_is_set(alu, OM(SAT));
292*61046927SAndroid Build Coastguard Worker 
293*61046927SAndroid Build Coastguard Worker       if (instr_size == 2) {
294*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.fmad.ext = 1;
295*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.fmad.lp = rogue_alu_op_mod_is_set(alu, OM(LP));
296*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.fmad.s1abs =
297*61046927SAndroid Build Coastguard Worker             rogue_alu_src_mod_is_set(alu, 1, SM(ABS));
298*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.fmad.s1neg =
299*61046927SAndroid Build Coastguard Worker             rogue_alu_src_mod_is_set(alu, 1, SM(NEG));
300*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.fmad.s2flr =
301*61046927SAndroid Build Coastguard Worker             rogue_alu_src_mod_is_set(alu, 2, SM(FLR));
302*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.fmad.s2abs =
303*61046927SAndroid Build Coastguard Worker             rogue_alu_src_mod_is_set(alu, 2, SM(ABS));
304*61046927SAndroid Build Coastguard Worker       }
305*61046927SAndroid Build Coastguard Worker       break;
306*61046927SAndroid Build Coastguard Worker 
307*61046927SAndroid Build Coastguard Worker    case ROGUE_ALU_OP_TST: {
308*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.op = ALUOP_TST;
309*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.tst.pwen = rogue_ref_is_io_p0(&alu->dst[1].ref);
310*61046927SAndroid Build Coastguard Worker 
311*61046927SAndroid Build Coastguard Worker       rogue_tstop tstop = { 0 };
312*61046927SAndroid Build Coastguard Worker       if (rogue_alu_op_mod_is_set(alu, OM(Z)))
313*61046927SAndroid Build Coastguard Worker          tstop._ = TSTOP_Z;
314*61046927SAndroid Build Coastguard Worker       else if (rogue_alu_op_mod_is_set(alu, OM(GZ)))
315*61046927SAndroid Build Coastguard Worker          tstop._ = TSTOP_GZ;
316*61046927SAndroid Build Coastguard Worker       else if (rogue_alu_op_mod_is_set(alu, OM(GEZ)))
317*61046927SAndroid Build Coastguard Worker          tstop._ = TSTOP_GEZ;
318*61046927SAndroid Build Coastguard Worker       else if (rogue_alu_op_mod_is_set(alu, OM(C)))
319*61046927SAndroid Build Coastguard Worker          tstop._ = TSTOP_C;
320*61046927SAndroid Build Coastguard Worker       else if (rogue_alu_op_mod_is_set(alu, OM(E)))
321*61046927SAndroid Build Coastguard Worker          tstop._ = TSTOP_E;
322*61046927SAndroid Build Coastguard Worker       else if (rogue_alu_op_mod_is_set(alu, OM(G)))
323*61046927SAndroid Build Coastguard Worker          tstop._ = TSTOP_G;
324*61046927SAndroid Build Coastguard Worker       else if (rogue_alu_op_mod_is_set(alu, OM(GE)))
325*61046927SAndroid Build Coastguard Worker          tstop._ = TSTOP_GE;
326*61046927SAndroid Build Coastguard Worker       else if (rogue_alu_op_mod_is_set(alu, OM(NE)))
327*61046927SAndroid Build Coastguard Worker          tstop._ = TSTOP_NE;
328*61046927SAndroid Build Coastguard Worker       else if (rogue_alu_op_mod_is_set(alu, OM(L)))
329*61046927SAndroid Build Coastguard Worker          tstop._ = TSTOP_L;
330*61046927SAndroid Build Coastguard Worker       else if (rogue_alu_op_mod_is_set(alu, OM(LE)))
331*61046927SAndroid Build Coastguard Worker          tstop._ = TSTOP_LE;
332*61046927SAndroid Build Coastguard Worker       else
333*61046927SAndroid Build Coastguard Worker          unreachable("Invalid comparison test.");
334*61046927SAndroid Build Coastguard Worker 
335*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.tst.tstop_2_0 = tstop._2_0;
336*61046927SAndroid Build Coastguard Worker 
337*61046927SAndroid Build Coastguard Worker       if (instr_size == 2) {
338*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.tst.ext = 1;
339*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.tst.tstop_3 = tstop._3;
340*61046927SAndroid Build Coastguard Worker 
341*61046927SAndroid Build Coastguard Worker          if (rogue_alu_src_mod_is_set(alu, 0, SM(E0)))
342*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.tst.elem = TST_E0;
343*61046927SAndroid Build Coastguard Worker          else if (rogue_alu_src_mod_is_set(alu, 0, SM(E1)))
344*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.tst.elem = TST_E1;
345*61046927SAndroid Build Coastguard Worker          else if (rogue_alu_src_mod_is_set(alu, 0, SM(E2)))
346*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.tst.elem = TST_E2;
347*61046927SAndroid Build Coastguard Worker          else if (rogue_alu_src_mod_is_set(alu, 0, SM(E3)))
348*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.tst.elem = TST_E3;
349*61046927SAndroid Build Coastguard Worker 
350*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.tst.p2end =
351*61046927SAndroid Build Coastguard Worker             !rogue_phase_occupied(ROGUE_INSTR_PHASE_2_PCK,
352*61046927SAndroid Build Coastguard Worker                                   alu->instr.group->header.phases);
353*61046927SAndroid Build Coastguard Worker 
354*61046927SAndroid Build Coastguard Worker          if (rogue_alu_op_mod_is_set(alu, OM(F32)))
355*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.tst.type = TSTTYPE_F32;
356*61046927SAndroid Build Coastguard Worker          else if (rogue_alu_op_mod_is_set(alu, OM(U16)))
357*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.tst.type = TSTTYPE_U16;
358*61046927SAndroid Build Coastguard Worker          else if (rogue_alu_op_mod_is_set(alu, OM(S16)))
359*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.tst.type = TSTTYPE_S16;
360*61046927SAndroid Build Coastguard Worker          else if (rogue_alu_op_mod_is_set(alu, OM(U8)))
361*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.tst.type = TSTTYPE_U8;
362*61046927SAndroid Build Coastguard Worker          else if (rogue_alu_op_mod_is_set(alu, OM(S8)))
363*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.tst.type = TSTTYPE_S8;
364*61046927SAndroid Build Coastguard Worker          else if (rogue_alu_op_mod_is_set(alu, OM(U32)))
365*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.tst.type = TSTTYPE_U32;
366*61046927SAndroid Build Coastguard Worker          else if (rogue_alu_op_mod_is_set(alu, OM(S32)))
367*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.tst.type = TSTTYPE_S32;
368*61046927SAndroid Build Coastguard Worker          else
369*61046927SAndroid Build Coastguard Worker             unreachable("Invalid comparison type.");
370*61046927SAndroid Build Coastguard Worker       }
371*61046927SAndroid Build Coastguard Worker       break;
372*61046927SAndroid Build Coastguard Worker    }
373*61046927SAndroid Build Coastguard Worker 
374*61046927SAndroid Build Coastguard Worker    case ROGUE_ALU_OP_MOVC: {
375*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.op = ALUOP_MOVC;
376*61046927SAndroid Build Coastguard Worker 
377*61046927SAndroid Build Coastguard Worker       bool e0 = rogue_alu_dst_mod_is_set(alu, 0, DM(E0));
378*61046927SAndroid Build Coastguard Worker       bool e1 = rogue_alu_dst_mod_is_set(alu, 0, DM(E1));
379*61046927SAndroid Build Coastguard Worker       bool e2 = rogue_alu_dst_mod_is_set(alu, 0, DM(E2));
380*61046927SAndroid Build Coastguard Worker       bool e3 = rogue_alu_dst_mod_is_set(alu, 0, DM(E3));
381*61046927SAndroid Build Coastguard Worker       bool e_none = !e0 && !e1 && !e2 && !e3;
382*61046927SAndroid Build Coastguard Worker 
383*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.movc.movw0 = rogue_alu_movc_ft(&alu->src[1].ref);
384*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.movc.movw1 = rogue_alu_movc_ft(&alu->src[2].ref);
385*61046927SAndroid Build Coastguard Worker 
386*61046927SAndroid Build Coastguard Worker       if (instr_size == 2) {
387*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.movc.ext = 1;
388*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.movc.p2end =
389*61046927SAndroid Build Coastguard Worker             !rogue_phase_occupied(ROGUE_INSTR_PHASE_2_TST,
390*61046927SAndroid Build Coastguard Worker                                   alu->instr.group->header.phases) &&
391*61046927SAndroid Build Coastguard Worker             !rogue_phase_occupied(ROGUE_INSTR_PHASE_2_PCK,
392*61046927SAndroid Build Coastguard Worker                                   alu->instr.group->header.phases);
393*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.movc.aw = !rogue_ref_is_io_ftt(&alu->src[0].ref);
394*61046927SAndroid Build Coastguard Worker 
395*61046927SAndroid Build Coastguard Worker          if (e_none) {
396*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.movc.maskw0 = MASKW0_EALL;
397*61046927SAndroid Build Coastguard Worker          } else {
398*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.movc.maskw0 |= e0 ? MASKW0_E0 : 0;
399*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.movc.maskw0 |= e1 ? MASKW0_E1 : 0;
400*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.movc.maskw0 |= e2 ? MASKW0_E2 : 0;
401*61046927SAndroid Build Coastguard Worker             instr_encoding->alu.movc.maskw0 |= e3 ? MASKW0_E3 : 0;
402*61046927SAndroid Build Coastguard Worker          }
403*61046927SAndroid Build Coastguard Worker       }
404*61046927SAndroid Build Coastguard Worker       break;
405*61046927SAndroid Build Coastguard Worker    }
406*61046927SAndroid Build Coastguard Worker 
407*61046927SAndroid Build Coastguard Worker    case ROGUE_ALU_OP_PCK_U8888:
408*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.op = ALUOP_SNGL;
409*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.sngl.snglop = SNGLOP_PCK;
410*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.sngl.ext0 = 1;
411*61046927SAndroid Build Coastguard Worker 
412*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.sngl.pck.pck.prog = 0;
413*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.sngl.pck.pck.rtz =
414*61046927SAndroid Build Coastguard Worker          rogue_alu_op_mod_is_set(alu, OM(ROUNDZERO));
415*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.sngl.pck.pck.scale =
416*61046927SAndroid Build Coastguard Worker          rogue_alu_op_mod_is_set(alu, OM(SCALE));
417*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.sngl.pck.pck.format = PCK_FMT_U8888;
418*61046927SAndroid Build Coastguard Worker       break;
419*61046927SAndroid Build Coastguard Worker 
420*61046927SAndroid Build Coastguard Worker    case ROGUE_ALU_OP_ADD64:
421*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.op = ALUOP_INT32_64;
422*61046927SAndroid Build Coastguard Worker 
423*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.int32_64.int32_64_op = INT32_64_OP_ADD64_NMX;
424*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.int32_64.s2neg =
425*61046927SAndroid Build Coastguard Worker          rogue_alu_src_mod_is_set(alu, 2, SM(NEG));
426*61046927SAndroid Build Coastguard Worker       instr_encoding->alu.int32_64.s = 0;
427*61046927SAndroid Build Coastguard Worker 
428*61046927SAndroid Build Coastguard Worker       if (instr_size == 2) {
429*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.int32_64.ext = 1;
430*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.int32_64.s2abs =
431*61046927SAndroid Build Coastguard Worker             rogue_alu_src_mod_is_set(alu, 2, SM(ABS));
432*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.int32_64.s1abs =
433*61046927SAndroid Build Coastguard Worker             rogue_alu_src_mod_is_set(alu, 1, SM(ABS));
434*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.int32_64.s0abs =
435*61046927SAndroid Build Coastguard Worker             rogue_alu_src_mod_is_set(alu, 0, SM(ABS));
436*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.int32_64.s0neg =
437*61046927SAndroid Build Coastguard Worker             rogue_alu_src_mod_is_set(alu, 0, SM(NEG));
438*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.int32_64.s1neg =
439*61046927SAndroid Build Coastguard Worker             rogue_alu_src_mod_is_set(alu, 1, SM(NEG));
440*61046927SAndroid Build Coastguard Worker          instr_encoding->alu.int32_64.cin =
441*61046927SAndroid Build Coastguard Worker             rogue_ref_is_io_p0(&alu->src[4].ref);
442*61046927SAndroid Build Coastguard Worker       }
443*61046927SAndroid Build Coastguard Worker       break;
444*61046927SAndroid Build Coastguard Worker 
445*61046927SAndroid Build Coastguard Worker    default:
446*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported alu op.");
447*61046927SAndroid Build Coastguard Worker    }
448*61046927SAndroid Build Coastguard Worker }
449*61046927SAndroid Build Coastguard Worker #undef OM
450*61046927SAndroid Build Coastguard Worker #undef DM
451*61046927SAndroid Build Coastguard Worker #undef SM
452*61046927SAndroid Build Coastguard Worker 
453*61046927SAndroid Build Coastguard Worker #define OM(op_mod) ROGUE_BACKEND_OP_MOD_##op_mod
rogue_backend_get_cachemode(const rogue_backend_instr * backend)454*61046927SAndroid Build Coastguard Worker static unsigned rogue_backend_get_cachemode(const rogue_backend_instr *backend)
455*61046927SAndroid Build Coastguard Worker {
456*61046927SAndroid Build Coastguard Worker    if (rogue_backend_op_mod_is_set(backend, OM(BYPASS)))
457*61046927SAndroid Build Coastguard Worker       return CACHEMODE_LD_BYPASS;
458*61046927SAndroid Build Coastguard Worker    else if (rogue_backend_op_mod_is_set(backend, OM(FORCELINEFILL)))
459*61046927SAndroid Build Coastguard Worker       return CACHEMODE_LD_FORCE_LINE_FILL;
460*61046927SAndroid Build Coastguard Worker    else if (rogue_backend_op_mod_is_set(backend, OM(WRITETHROUGH)))
461*61046927SAndroid Build Coastguard Worker       return CACHEMODE_ST_WRITE_THROUGH;
462*61046927SAndroid Build Coastguard Worker    else if (rogue_backend_op_mod_is_set(backend, OM(WRITEBACK)))
463*61046927SAndroid Build Coastguard Worker       return CACHEMODE_ST_WRITE_BACK;
464*61046927SAndroid Build Coastguard Worker    else if (rogue_backend_op_mod_is_set(backend, OM(LAZYWRITEBACK)))
465*61046927SAndroid Build Coastguard Worker       return CACHEMODE_ST_WRITE_BACK_LAZY;
466*61046927SAndroid Build Coastguard Worker 
467*61046927SAndroid Build Coastguard Worker    /* Default cache mode. */
468*61046927SAndroid Build Coastguard Worker    return CACHEMODE_LD_NORMAL; /* == CACHEMODE_ST_WRITE_THROUGH */
469*61046927SAndroid Build Coastguard Worker }
470*61046927SAndroid Build Coastguard Worker 
471*61046927SAndroid Build Coastguard Worker static unsigned
rogue_backend_get_slccachemode(const rogue_backend_instr * backend)472*61046927SAndroid Build Coastguard Worker rogue_backend_get_slccachemode(const rogue_backend_instr *backend)
473*61046927SAndroid Build Coastguard Worker {
474*61046927SAndroid Build Coastguard Worker    if (rogue_backend_op_mod_is_set(backend, OM(SLCBYPASS)))
475*61046927SAndroid Build Coastguard Worker       return SLCCACHEMODE_BYPASS;
476*61046927SAndroid Build Coastguard Worker    else if (rogue_backend_op_mod_is_set(backend, OM(SLCWRITEBACK)))
477*61046927SAndroid Build Coastguard Worker       return SLCCACHEMODE_WRITE_BACK;
478*61046927SAndroid Build Coastguard Worker    else if (rogue_backend_op_mod_is_set(backend, OM(SLCWRITETHROUGH)))
479*61046927SAndroid Build Coastguard Worker       return SLCCACHEMODE_WRITE_THROUGH;
480*61046927SAndroid Build Coastguard Worker    else if (rogue_backend_op_mod_is_set(backend, OM(SLCNOALLOC)))
481*61046927SAndroid Build Coastguard Worker       return SLCCACHEMODE_CACHED_READS;
482*61046927SAndroid Build Coastguard Worker 
483*61046927SAndroid Build Coastguard Worker    /* Default SLC cache mode. */
484*61046927SAndroid Build Coastguard Worker    return SLCCACHEMODE_BYPASS;
485*61046927SAndroid Build Coastguard Worker }
486*61046927SAndroid Build Coastguard Worker 
rogue_encode_backend_instr(const rogue_backend_instr * backend,unsigned instr_size,rogue_instr_encoding * instr_encoding)487*61046927SAndroid Build Coastguard Worker static void rogue_encode_backend_instr(const rogue_backend_instr *backend,
488*61046927SAndroid Build Coastguard Worker                                        unsigned instr_size,
489*61046927SAndroid Build Coastguard Worker                                        rogue_instr_encoding *instr_encoding)
490*61046927SAndroid Build Coastguard Worker {
491*61046927SAndroid Build Coastguard Worker    switch (backend->op) {
492*61046927SAndroid Build Coastguard Worker    case ROGUE_BACKEND_OP_FITR_PIXEL:
493*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.op = BACKENDOP_FITR;
494*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.fitr.p = 0;
495*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.fitr.drc =
496*61046927SAndroid Build Coastguard Worker          rogue_ref_get_drc_index(&backend->src[0].ref);
497*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.fitr.mode = FITR_MODE_PIXEL;
498*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.fitr.sat =
499*61046927SAndroid Build Coastguard Worker          rogue_backend_op_mod_is_set(backend, OM(SAT));
500*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.fitr.count =
501*61046927SAndroid Build Coastguard Worker          rogue_ref_get_val(&backend->src[2].ref);
502*61046927SAndroid Build Coastguard Worker       break;
503*61046927SAndroid Build Coastguard Worker 
504*61046927SAndroid Build Coastguard Worker    case ROGUE_BACKEND_OP_FITRP_PIXEL:
505*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.op = BACKENDOP_FITR;
506*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.fitr.p = 1;
507*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.fitr.drc =
508*61046927SAndroid Build Coastguard Worker          rogue_ref_get_drc_index(&backend->src[0].ref);
509*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.fitr.mode = FITR_MODE_PIXEL;
510*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.fitr.sat =
511*61046927SAndroid Build Coastguard Worker          rogue_backend_op_mod_is_set(backend, OM(SAT));
512*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.fitr.count =
513*61046927SAndroid Build Coastguard Worker          rogue_ref_get_val(&backend->src[3].ref);
514*61046927SAndroid Build Coastguard Worker       break;
515*61046927SAndroid Build Coastguard Worker 
516*61046927SAndroid Build Coastguard Worker    case ROGUE_BACKEND_OP_UVSW_WRITE:
517*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.op = BACKENDOP_UVSW;
518*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.uvsw.writeop = UVSW_WRITEOP_WRITE;
519*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.uvsw.imm = 1;
520*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.uvsw.imm_src.imm_addr =
521*61046927SAndroid Build Coastguard Worker          rogue_ref_get_reg_index(&backend->dst[0].ref);
522*61046927SAndroid Build Coastguard Worker       break;
523*61046927SAndroid Build Coastguard Worker 
524*61046927SAndroid Build Coastguard Worker    case ROGUE_BACKEND_OP_UVSW_EMIT:
525*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.op = BACKENDOP_UVSW;
526*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.uvsw.writeop = UVSW_WRITEOP_EMIT;
527*61046927SAndroid Build Coastguard Worker       break;
528*61046927SAndroid Build Coastguard Worker 
529*61046927SAndroid Build Coastguard Worker    case ROGUE_BACKEND_OP_UVSW_ENDTASK:
530*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.op = BACKENDOP_UVSW;
531*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.uvsw.writeop = UVSW_WRITEOP_END;
532*61046927SAndroid Build Coastguard Worker       break;
533*61046927SAndroid Build Coastguard Worker 
534*61046927SAndroid Build Coastguard Worker    case ROGUE_BACKEND_OP_UVSW_EMITTHENENDTASK:
535*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.op = BACKENDOP_UVSW;
536*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.uvsw.writeop = UVSW_WRITEOP_EMIT_END;
537*61046927SAndroid Build Coastguard Worker       break;
538*61046927SAndroid Build Coastguard Worker 
539*61046927SAndroid Build Coastguard Worker    case ROGUE_BACKEND_OP_UVSW_WRITETHENEMITTHENENDTASK:
540*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.op = BACKENDOP_UVSW;
541*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.uvsw.writeop = UVSW_WRITEOP_WRITE_EMIT_END;
542*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.uvsw.imm = 1;
543*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.uvsw.imm_src.imm_addr =
544*61046927SAndroid Build Coastguard Worker          rogue_ref_get_reg_index(&backend->dst[0].ref);
545*61046927SAndroid Build Coastguard Worker       break;
546*61046927SAndroid Build Coastguard Worker 
547*61046927SAndroid Build Coastguard Worker    case ROGUE_BACKEND_OP_LD: {
548*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.op = BACKENDOP_DMA;
549*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.dmaop = DMAOP_LD;
550*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.ld.drc =
551*61046927SAndroid Build Coastguard Worker          rogue_ref_get_drc_index(&backend->src[0].ref);
552*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.ld.cachemode =
553*61046927SAndroid Build Coastguard Worker          rogue_backend_get_cachemode(backend);
554*61046927SAndroid Build Coastguard Worker 
555*61046927SAndroid Build Coastguard Worker       bool imm_burstlen = rogue_ref_is_val(&backend->src[1].ref);
556*61046927SAndroid Build Coastguard Worker 
557*61046927SAndroid Build Coastguard Worker       rogue_burstlen burstlen = {
558*61046927SAndroid Build Coastguard Worker          ._ = imm_burstlen ? rogue_ref_get_val(&backend->src[1].ref) : 0
559*61046927SAndroid Build Coastguard Worker       };
560*61046927SAndroid Build Coastguard Worker 
561*61046927SAndroid Build Coastguard Worker       if (imm_burstlen) {
562*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.ld.burstlen_2_0 = burstlen._2_0;
563*61046927SAndroid Build Coastguard Worker       } else {
564*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.ld.srcselbl =
565*61046927SAndroid Build Coastguard Worker             rogue_ref_get_io_src_index(&backend->src[1].ref);
566*61046927SAndroid Build Coastguard Worker       }
567*61046927SAndroid Build Coastguard Worker 
568*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.ld.srcseladd =
569*61046927SAndroid Build Coastguard Worker          rogue_ref_get_io_src_index(&backend->src[2].ref);
570*61046927SAndroid Build Coastguard Worker 
571*61046927SAndroid Build Coastguard Worker       if (instr_size == 3) {
572*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.ld.ext = 1;
573*61046927SAndroid Build Coastguard Worker          if (imm_burstlen)
574*61046927SAndroid Build Coastguard Worker             instr_encoding->backend.dma.ld.burstlen_3 = burstlen._3;
575*61046927SAndroid Build Coastguard Worker 
576*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.ld.slccachemode =
577*61046927SAndroid Build Coastguard Worker             rogue_backend_get_slccachemode(backend);
578*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.ld.notimmbl = !imm_burstlen;
579*61046927SAndroid Build Coastguard Worker       }
580*61046927SAndroid Build Coastguard Worker 
581*61046927SAndroid Build Coastguard Worker       break;
582*61046927SAndroid Build Coastguard Worker    }
583*61046927SAndroid Build Coastguard Worker 
584*61046927SAndroid Build Coastguard Worker    case ROGUE_BACKEND_OP_ST: {
585*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.op = BACKENDOP_DMA;
586*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.dmaop = DMAOP_ST;
587*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.st.drc =
588*61046927SAndroid Build Coastguard Worker          rogue_ref_get_drc_index(&backend->src[2].ref);
589*61046927SAndroid Build Coastguard Worker 
590*61046927SAndroid Build Coastguard Worker       bool imm_burstlen = rogue_ref_is_val(&backend->src[3].ref);
591*61046927SAndroid Build Coastguard Worker 
592*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.st.immbl = imm_burstlen;
593*61046927SAndroid Build Coastguard Worker 
594*61046927SAndroid Build Coastguard Worker       if (imm_burstlen) {
595*61046927SAndroid Build Coastguard Worker          rogue_burstlen burstlen = { ._ = rogue_ref_get_val(
596*61046927SAndroid Build Coastguard Worker                                         &backend->src[3].ref) };
597*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.st.burstlen_2_0 = burstlen._2_0;
598*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.st.burstlen_3 = burstlen._3;
599*61046927SAndroid Build Coastguard Worker       } else {
600*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.st.srcselbl =
601*61046927SAndroid Build Coastguard Worker             rogue_ref_get_io_src_index(&backend->src[3].ref);
602*61046927SAndroid Build Coastguard Worker       }
603*61046927SAndroid Build Coastguard Worker 
604*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.st.cachemode =
605*61046927SAndroid Build Coastguard Worker          rogue_backend_get_cachemode(backend);
606*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.st.srcseladd =
607*61046927SAndroid Build Coastguard Worker          rogue_ref_get_io_src_index(&backend->src[4].ref);
608*61046927SAndroid Build Coastguard Worker 
609*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.st.dsize =
610*61046927SAndroid Build Coastguard Worker          rogue_ref_get_val(&backend->src[1].ref);
611*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.st.srcseldata =
612*61046927SAndroid Build Coastguard Worker          rogue_ref_get_io_src_index(&backend->src[0].ref);
613*61046927SAndroid Build Coastguard Worker 
614*61046927SAndroid Build Coastguard Worker       if (instr_size == 4) {
615*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.st.ext = 1;
616*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.st.srcmask =
617*61046927SAndroid Build Coastguard Worker             rogue_ref_get_io_src_index(&backend->src[5].ref);
618*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.st.slccachemode =
619*61046927SAndroid Build Coastguard Worker             rogue_backend_get_slccachemode(backend);
620*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.st.nottiled =
621*61046927SAndroid Build Coastguard Worker             !rogue_backend_op_mod_is_set(backend, OM(TILED));
622*61046927SAndroid Build Coastguard Worker       }
623*61046927SAndroid Build Coastguard Worker 
624*61046927SAndroid Build Coastguard Worker       break;
625*61046927SAndroid Build Coastguard Worker    }
626*61046927SAndroid Build Coastguard Worker 
627*61046927SAndroid Build Coastguard Worker    case ROGUE_BACKEND_OP_SMP1D:
628*61046927SAndroid Build Coastguard Worker    case ROGUE_BACKEND_OP_SMP2D:
629*61046927SAndroid Build Coastguard Worker    case ROGUE_BACKEND_OP_SMP3D:
630*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.op = BACKENDOP_DMA;
631*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.dmaop = DMAOP_SMP;
632*61046927SAndroid Build Coastguard Worker 
633*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.smp.drc =
634*61046927SAndroid Build Coastguard Worker          rogue_ref_get_drc_index(&backend->src[0].ref);
635*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.smp.fcnorm =
636*61046927SAndroid Build Coastguard Worker          rogue_backend_op_mod_is_set(backend, OM(FCNORM));
637*61046927SAndroid Build Coastguard Worker 
638*61046927SAndroid Build Coastguard Worker       if (rogue_backend_op_mod_is_set(backend, OM(BIAS)))
639*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.lodm = LODM_BIAS;
640*61046927SAndroid Build Coastguard Worker       else if (rogue_backend_op_mod_is_set(backend, OM(REPLACE)))
641*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.lodm = LODM_REPLACE;
642*61046927SAndroid Build Coastguard Worker       else if (rogue_backend_op_mod_is_set(backend, OM(GRADIENT)))
643*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.lodm = LODM_GRADIENTS;
644*61046927SAndroid Build Coastguard Worker       else
645*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.lodm = LODM_NORMAL;
646*61046927SAndroid Build Coastguard Worker 
647*61046927SAndroid Build Coastguard Worker       switch (rogue_ref_get_val(&backend->src[5].ref)) {
648*61046927SAndroid Build Coastguard Worker       case 1:
649*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.chan = SMPCHAN_1;
650*61046927SAndroid Build Coastguard Worker          break;
651*61046927SAndroid Build Coastguard Worker 
652*61046927SAndroid Build Coastguard Worker       case 2:
653*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.chan = SMPCHAN_2;
654*61046927SAndroid Build Coastguard Worker          break;
655*61046927SAndroid Build Coastguard Worker 
656*61046927SAndroid Build Coastguard Worker       case 3:
657*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.chan = SMPCHAN_3;
658*61046927SAndroid Build Coastguard Worker          break;
659*61046927SAndroid Build Coastguard Worker 
660*61046927SAndroid Build Coastguard Worker       case 4:
661*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.chan = SMPCHAN_4;
662*61046927SAndroid Build Coastguard Worker          break;
663*61046927SAndroid Build Coastguard Worker 
664*61046927SAndroid Build Coastguard Worker       default:
665*61046927SAndroid Build Coastguard Worker          unreachable("Unsupported number of channels.");
666*61046927SAndroid Build Coastguard Worker       }
667*61046927SAndroid Build Coastguard Worker 
668*61046927SAndroid Build Coastguard Worker       switch (backend->op) {
669*61046927SAndroid Build Coastguard Worker       case ROGUE_BACKEND_OP_SMP1D:
670*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.dmn = DMN_1D;
671*61046927SAndroid Build Coastguard Worker          break;
672*61046927SAndroid Build Coastguard Worker 
673*61046927SAndroid Build Coastguard Worker       case ROGUE_BACKEND_OP_SMP2D:
674*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.dmn = DMN_2D;
675*61046927SAndroid Build Coastguard Worker          break;
676*61046927SAndroid Build Coastguard Worker 
677*61046927SAndroid Build Coastguard Worker       case ROGUE_BACKEND_OP_SMP3D:
678*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.dmn = DMN_3D;
679*61046927SAndroid Build Coastguard Worker          break;
680*61046927SAndroid Build Coastguard Worker 
681*61046927SAndroid Build Coastguard Worker       default:
682*61046927SAndroid Build Coastguard Worker          unreachable("Unsupported sampler op.");
683*61046927SAndroid Build Coastguard Worker       }
684*61046927SAndroid Build Coastguard Worker 
685*61046927SAndroid Build Coastguard Worker       if (instr_size > 2) {
686*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.exta = 1;
687*61046927SAndroid Build Coastguard Worker 
688*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.tao =
689*61046927SAndroid Build Coastguard Worker             rogue_backend_op_mod_is_set(backend, OM(TAO));
690*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.soo =
691*61046927SAndroid Build Coastguard Worker             rogue_backend_op_mod_is_set(backend, OM(SOO));
692*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.sno =
693*61046927SAndroid Build Coastguard Worker             rogue_backend_op_mod_is_set(backend, OM(SNO));
694*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.nncoords =
695*61046927SAndroid Build Coastguard Worker             rogue_backend_op_mod_is_set(backend, OM(NNCOORDS));
696*61046927SAndroid Build Coastguard Worker 
697*61046927SAndroid Build Coastguard Worker          if (rogue_backend_op_mod_is_set(backend, OM(DATA)))
698*61046927SAndroid Build Coastguard Worker             instr_encoding->backend.dma.smp.sbmode = SBMODE_DATA;
699*61046927SAndroid Build Coastguard Worker          else if (rogue_backend_op_mod_is_set(backend, OM(INFO)))
700*61046927SAndroid Build Coastguard Worker             instr_encoding->backend.dma.smp.sbmode = SBMODE_INFO;
701*61046927SAndroid Build Coastguard Worker          else if (rogue_backend_op_mod_is_set(backend, OM(BOTH)))
702*61046927SAndroid Build Coastguard Worker             instr_encoding->backend.dma.smp.sbmode = SBMODE_BOTH;
703*61046927SAndroid Build Coastguard Worker          else
704*61046927SAndroid Build Coastguard Worker             instr_encoding->backend.dma.smp.sbmode = SBMODE_NONE;
705*61046927SAndroid Build Coastguard Worker 
706*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.proj =
707*61046927SAndroid Build Coastguard Worker             rogue_backend_op_mod_is_set(backend, OM(PROJ));
708*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.pplod =
709*61046927SAndroid Build Coastguard Worker             rogue_backend_op_mod_is_set(backend, OM(PPLOD));
710*61046927SAndroid Build Coastguard Worker       }
711*61046927SAndroid Build Coastguard Worker 
712*61046927SAndroid Build Coastguard Worker       if (instr_size > 3) {
713*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.extb = 1;
714*61046927SAndroid Build Coastguard Worker 
715*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.w =
716*61046927SAndroid Build Coastguard Worker             rogue_backend_op_mod_is_set(backend, OM(WRT));
717*61046927SAndroid Build Coastguard Worker 
718*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.cachemode =
719*61046927SAndroid Build Coastguard Worker             rogue_backend_get_cachemode(backend);
720*61046927SAndroid Build Coastguard Worker 
721*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.swap =
722*61046927SAndroid Build Coastguard Worker             rogue_backend_op_mod_is_set(backend, OM(SCHEDSWAP));
723*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.f16 =
724*61046927SAndroid Build Coastguard Worker             rogue_backend_op_mod_is_set(backend, OM(F16));
725*61046927SAndroid Build Coastguard Worker 
726*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.slccachemode =
727*61046927SAndroid Build Coastguard Worker             rogue_backend_get_slccachemode(backend);
728*61046927SAndroid Build Coastguard Worker       }
729*61046927SAndroid Build Coastguard Worker 
730*61046927SAndroid Build Coastguard Worker       if (instr_size > 4) {
731*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.extc = 1;
732*61046927SAndroid Build Coastguard Worker 
733*61046927SAndroid Build Coastguard Worker          instr_encoding->backend.dma.smp.array =
734*61046927SAndroid Build Coastguard Worker             rogue_backend_op_mod_is_set(backend, OM(ARRAY));
735*61046927SAndroid Build Coastguard Worker       }
736*61046927SAndroid Build Coastguard Worker 
737*61046927SAndroid Build Coastguard Worker       break;
738*61046927SAndroid Build Coastguard Worker 
739*61046927SAndroid Build Coastguard Worker    case ROGUE_BACKEND_OP_IDF:
740*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.op = BACKENDOP_DMA;
741*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.dmaop = DMAOP_IDF;
742*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.idf.drc =
743*61046927SAndroid Build Coastguard Worker          rogue_ref_get_drc_index(&backend->src[0].ref);
744*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.dma.idf.srcseladd =
745*61046927SAndroid Build Coastguard Worker          rogue_ref_get_io_src_index(&backend->src[1].ref);
746*61046927SAndroid Build Coastguard Worker       break;
747*61046927SAndroid Build Coastguard Worker 
748*61046927SAndroid Build Coastguard Worker    case ROGUE_BACKEND_OP_EMITPIX:
749*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.op = BACKENDOP_EMIT;
750*61046927SAndroid Build Coastguard Worker       instr_encoding->backend.emitpix.freep =
751*61046927SAndroid Build Coastguard Worker          rogue_backend_op_mod_is_set(backend, OM(FREEP));
752*61046927SAndroid Build Coastguard Worker       break;
753*61046927SAndroid Build Coastguard Worker 
754*61046927SAndroid Build Coastguard Worker    default:
755*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported backend op.");
756*61046927SAndroid Build Coastguard Worker    }
757*61046927SAndroid Build Coastguard Worker }
758*61046927SAndroid Build Coastguard Worker #undef OM
759*61046927SAndroid Build Coastguard Worker 
760*61046927SAndroid Build Coastguard Worker #define OM(op_mod) ROGUE_CTRL_OP_MOD_##op_mod
rogue_encode_ctrl_instr(const rogue_ctrl_instr * ctrl,unsigned instr_size,rogue_instr_encoding * instr_encoding)761*61046927SAndroid Build Coastguard Worker static void rogue_encode_ctrl_instr(const rogue_ctrl_instr *ctrl,
762*61046927SAndroid Build Coastguard Worker                                     unsigned instr_size,
763*61046927SAndroid Build Coastguard Worker                                     rogue_instr_encoding *instr_encoding)
764*61046927SAndroid Build Coastguard Worker {
765*61046927SAndroid Build Coastguard Worker    /* Only some control instructions have additional bytes. */
766*61046927SAndroid Build Coastguard Worker    switch (ctrl->op) {
767*61046927SAndroid Build Coastguard Worker    case ROGUE_CTRL_OP_NOP:
768*61046927SAndroid Build Coastguard Worker       memset(&instr_encoding->ctrl.nop, 0, sizeof(instr_encoding->ctrl.nop));
769*61046927SAndroid Build Coastguard Worker       break;
770*61046927SAndroid Build Coastguard Worker 
771*61046927SAndroid Build Coastguard Worker    case ROGUE_CTRL_OP_BR:
772*61046927SAndroid Build Coastguard Worker    case ROGUE_CTRL_OP_BA: {
773*61046927SAndroid Build Coastguard Worker       bool branch_abs = (ctrl->op == ROGUE_CTRL_OP_BA);
774*61046927SAndroid Build Coastguard Worker       rogue_offset32 offset;
775*61046927SAndroid Build Coastguard Worker 
776*61046927SAndroid Build Coastguard Worker       instr_encoding->ctrl.ba.abs = branch_abs;
777*61046927SAndroid Build Coastguard Worker       instr_encoding->ctrl.ba.allp =
778*61046927SAndroid Build Coastguard Worker          rogue_ctrl_op_mod_is_set(ctrl, OM(ALLINST));
779*61046927SAndroid Build Coastguard Worker       instr_encoding->ctrl.ba.anyp =
780*61046927SAndroid Build Coastguard Worker          rogue_ctrl_op_mod_is_set(ctrl, OM(ANYINST));
781*61046927SAndroid Build Coastguard Worker       instr_encoding->ctrl.ba.link = rogue_ctrl_op_mod_is_set(ctrl, OM(LINK));
782*61046927SAndroid Build Coastguard Worker 
783*61046927SAndroid Build Coastguard Worker       if (branch_abs) {
784*61046927SAndroid Build Coastguard Worker          offset._ = rogue_ref_get_val(&ctrl->src[0].ref);
785*61046927SAndroid Build Coastguard Worker       } else {
786*61046927SAndroid Build Coastguard Worker          rogue_instr_group *block_group =
787*61046927SAndroid Build Coastguard Worker             list_entry(ctrl->target_block->instrs.next,
788*61046927SAndroid Build Coastguard Worker                        rogue_instr_group,
789*61046927SAndroid Build Coastguard Worker                        link);
790*61046927SAndroid Build Coastguard Worker          offset._ = block_group->size.offset - (ctrl->instr.group->size.offset +
791*61046927SAndroid Build Coastguard Worker                                                 ctrl->instr.group->size.total);
792*61046927SAndroid Build Coastguard Worker       }
793*61046927SAndroid Build Coastguard Worker 
794*61046927SAndroid Build Coastguard Worker       instr_encoding->ctrl.ba.offset_7_1 = offset._7_1;
795*61046927SAndroid Build Coastguard Worker       instr_encoding->ctrl.ba.offset_15_8 = offset._15_8;
796*61046927SAndroid Build Coastguard Worker       instr_encoding->ctrl.ba.offset_23_16 = offset._23_16;
797*61046927SAndroid Build Coastguard Worker       instr_encoding->ctrl.ba.offset_31_24 = offset._31_24;
798*61046927SAndroid Build Coastguard Worker 
799*61046927SAndroid Build Coastguard Worker       break;
800*61046927SAndroid Build Coastguard Worker    }
801*61046927SAndroid Build Coastguard Worker 
802*61046927SAndroid Build Coastguard Worker    default:
803*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported ctrl op.");
804*61046927SAndroid Build Coastguard Worker    }
805*61046927SAndroid Build Coastguard Worker }
806*61046927SAndroid Build Coastguard Worker #undef OM
807*61046927SAndroid Build Coastguard Worker 
rogue_encode_bitwise_instr(const rogue_bitwise_instr * bitwise,unsigned instr_size,rogue_instr_encoding * instr_encoding)808*61046927SAndroid Build Coastguard Worker static void rogue_encode_bitwise_instr(const rogue_bitwise_instr *bitwise,
809*61046927SAndroid Build Coastguard Worker                                        unsigned instr_size,
810*61046927SAndroid Build Coastguard Worker                                        rogue_instr_encoding *instr_encoding)
811*61046927SAndroid Build Coastguard Worker {
812*61046927SAndroid Build Coastguard Worker    switch (bitwise->op) {
813*61046927SAndroid Build Coastguard Worker    case ROGUE_BITWISE_OP_BYP0: {
814*61046927SAndroid Build Coastguard Worker       instr_encoding->bitwise.phase0 = 1;
815*61046927SAndroid Build Coastguard Worker       instr_encoding->bitwise.ph0.shft = SHFT1_BYP;
816*61046927SAndroid Build Coastguard Worker       instr_encoding->bitwise.ph0.cnt_byp = 1;
817*61046927SAndroid Build Coastguard Worker 
818*61046927SAndroid Build Coastguard Worker       rogue_imm32 imm32;
819*61046927SAndroid Build Coastguard Worker       if (rogue_ref_is_val(&bitwise->src[1].ref))
820*61046927SAndroid Build Coastguard Worker          imm32._ = rogue_ref_get_val(&bitwise->src[1].ref);
821*61046927SAndroid Build Coastguard Worker 
822*61046927SAndroid Build Coastguard Worker       if (instr_size > 1) {
823*61046927SAndroid Build Coastguard Worker          instr_encoding->bitwise.ph0.ext = 1;
824*61046927SAndroid Build Coastguard Worker          instr_encoding->bitwise.ph0.imm_7_0 = imm32._7_0;
825*61046927SAndroid Build Coastguard Worker          instr_encoding->bitwise.ph0.imm_15_8 = imm32._15_8;
826*61046927SAndroid Build Coastguard Worker       }
827*61046927SAndroid Build Coastguard Worker 
828*61046927SAndroid Build Coastguard Worker       if (instr_size > 3) {
829*61046927SAndroid Build Coastguard Worker          instr_encoding->bitwise.ph0.bm = 1;
830*61046927SAndroid Build Coastguard Worker          instr_encoding->bitwise.ph0.imm_23_16 = imm32._23_16;
831*61046927SAndroid Build Coastguard Worker          instr_encoding->bitwise.ph0.imm_31_24 = imm32._31_24;
832*61046927SAndroid Build Coastguard Worker       }
833*61046927SAndroid Build Coastguard Worker 
834*61046927SAndroid Build Coastguard Worker       break;
835*61046927SAndroid Build Coastguard Worker    }
836*61046927SAndroid Build Coastguard Worker 
837*61046927SAndroid Build Coastguard Worker    default:
838*61046927SAndroid Build Coastguard Worker       unreachable("Invalid bitwise op.");
839*61046927SAndroid Build Coastguard Worker    }
840*61046927SAndroid Build Coastguard Worker }
841*61046927SAndroid Build Coastguard Worker 
rogue_encode_instr_group_instrs(rogue_instr_group * group,struct util_dynarray * binary)842*61046927SAndroid Build Coastguard Worker static void rogue_encode_instr_group_instrs(rogue_instr_group *group,
843*61046927SAndroid Build Coastguard Worker                                             struct util_dynarray *binary)
844*61046927SAndroid Build Coastguard Worker {
845*61046927SAndroid Build Coastguard Worker    rogue_instr_encoding instr_encoding;
846*61046927SAndroid Build Coastguard Worker 
847*61046927SAndroid Build Coastguard Worker    /* Reverse order for encoding. */
848*61046927SAndroid Build Coastguard Worker    rogue_foreach_phase_in_set_rev (p, group->header.phases) {
849*61046927SAndroid Build Coastguard Worker       if (!group->size.instrs[p])
850*61046927SAndroid Build Coastguard Worker          continue;
851*61046927SAndroid Build Coastguard Worker 
852*61046927SAndroid Build Coastguard Worker       memset(&instr_encoding, 0, sizeof(instr_encoding));
853*61046927SAndroid Build Coastguard Worker 
854*61046927SAndroid Build Coastguard Worker       const rogue_instr *instr = group->instrs[p];
855*61046927SAndroid Build Coastguard Worker       switch (instr->type) {
856*61046927SAndroid Build Coastguard Worker       case ROGUE_INSTR_TYPE_ALU:
857*61046927SAndroid Build Coastguard Worker          rogue_encode_alu_instr(rogue_instr_as_alu(instr),
858*61046927SAndroid Build Coastguard Worker                                 group->size.instrs[p],
859*61046927SAndroid Build Coastguard Worker                                 &instr_encoding);
860*61046927SAndroid Build Coastguard Worker          break;
861*61046927SAndroid Build Coastguard Worker 
862*61046927SAndroid Build Coastguard Worker       case ROGUE_INSTR_TYPE_BACKEND:
863*61046927SAndroid Build Coastguard Worker          rogue_encode_backend_instr(rogue_instr_as_backend(instr),
864*61046927SAndroid Build Coastguard Worker                                     group->size.instrs[p],
865*61046927SAndroid Build Coastguard Worker                                     &instr_encoding);
866*61046927SAndroid Build Coastguard Worker          break;
867*61046927SAndroid Build Coastguard Worker 
868*61046927SAndroid Build Coastguard Worker       case ROGUE_INSTR_TYPE_CTRL:
869*61046927SAndroid Build Coastguard Worker          rogue_encode_ctrl_instr(rogue_instr_as_ctrl(instr),
870*61046927SAndroid Build Coastguard Worker                                  group->size.instrs[p],
871*61046927SAndroid Build Coastguard Worker                                  &instr_encoding);
872*61046927SAndroid Build Coastguard Worker          break;
873*61046927SAndroid Build Coastguard Worker 
874*61046927SAndroid Build Coastguard Worker       case ROGUE_INSTR_TYPE_BITWISE:
875*61046927SAndroid Build Coastguard Worker          rogue_encode_bitwise_instr(rogue_instr_as_bitwise(instr),
876*61046927SAndroid Build Coastguard Worker                                     group->size.instrs[p],
877*61046927SAndroid Build Coastguard Worker                                     &instr_encoding);
878*61046927SAndroid Build Coastguard Worker          break;
879*61046927SAndroid Build Coastguard Worker 
880*61046927SAndroid Build Coastguard Worker       default:
881*61046927SAndroid Build Coastguard Worker          unreachable("Unsupported instruction type.");
882*61046927SAndroid Build Coastguard Worker       }
883*61046927SAndroid Build Coastguard Worker 
884*61046927SAndroid Build Coastguard Worker       util_dynarray_append_mem(binary, group->size.instrs[p], &instr_encoding);
885*61046927SAndroid Build Coastguard Worker    }
886*61046927SAndroid Build Coastguard Worker }
887*61046927SAndroid Build Coastguard Worker 
rogue_encode_source_map(const rogue_instr_group * group,bool upper_srcs,rogue_source_map_encoding * e)888*61046927SAndroid Build Coastguard Worker static void rogue_encode_source_map(const rogue_instr_group *group,
889*61046927SAndroid Build Coastguard Worker                                     bool upper_srcs,
890*61046927SAndroid Build Coastguard Worker                                     rogue_source_map_encoding *e)
891*61046927SAndroid Build Coastguard Worker {
892*61046927SAndroid Build Coastguard Worker    unsigned base = upper_srcs ? 3 : 0;
893*61046927SAndroid Build Coastguard Worker    unsigned index = upper_srcs ? group->encode_info.upper_src_index
894*61046927SAndroid Build Coastguard Worker                                : group->encode_info.lower_src_index;
895*61046927SAndroid Build Coastguard Worker    const rogue_reg_src_info *info = upper_srcs
896*61046927SAndroid Build Coastguard Worker                                        ? &rogue_reg_upper_src_infos[index]
897*61046927SAndroid Build Coastguard Worker                                        : &rogue_reg_lower_src_infos[index];
898*61046927SAndroid Build Coastguard Worker    const rogue_instr_group_io_sel *io_sel = &group->io_sel;
899*61046927SAndroid Build Coastguard Worker 
900*61046927SAndroid Build Coastguard Worker    rogue_mux mux = { 0 };
901*61046927SAndroid Build Coastguard Worker 
902*61046927SAndroid Build Coastguard Worker    if (!upper_srcs && rogue_ref_is_io(&io_sel->iss[0])) {
903*61046927SAndroid Build Coastguard Worker       switch (io_sel->iss[0].io) {
904*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_S0:
905*61046927SAndroid Build Coastguard Worker          mux._ = IS0_S0;
906*61046927SAndroid Build Coastguard Worker          break;
907*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_S3:
908*61046927SAndroid Build Coastguard Worker          mux._ = IS0_S3;
909*61046927SAndroid Build Coastguard Worker          break;
910*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_S4:
911*61046927SAndroid Build Coastguard Worker          mux._ = IS0_S4;
912*61046927SAndroid Build Coastguard Worker          break;
913*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_S5:
914*61046927SAndroid Build Coastguard Worker          mux._ = IS0_S5;
915*61046927SAndroid Build Coastguard Worker          break;
916*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_S1:
917*61046927SAndroid Build Coastguard Worker          mux._ = IS0_S1;
918*61046927SAndroid Build Coastguard Worker          break;
919*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_S2:
920*61046927SAndroid Build Coastguard Worker          mux._ = IS0_S2;
921*61046927SAndroid Build Coastguard Worker          break;
922*61046927SAndroid Build Coastguard Worker 
923*61046927SAndroid Build Coastguard Worker       default:
924*61046927SAndroid Build Coastguard Worker          unreachable("IS0 set to unsupported value.");
925*61046927SAndroid Build Coastguard Worker       }
926*61046927SAndroid Build Coastguard Worker    }
927*61046927SAndroid Build Coastguard Worker 
928*61046927SAndroid Build Coastguard Worker    rogue_sbA sbA = { 0 };
929*61046927SAndroid Build Coastguard Worker    rogue_sA sA = { 0 };
930*61046927SAndroid Build Coastguard Worker 
931*61046927SAndroid Build Coastguard Worker    if (!rogue_ref_is_null(&io_sel->srcs[base + 0])) {
932*61046927SAndroid Build Coastguard Worker       sbA._ = rogue_reg_bank_encoding(
933*61046927SAndroid Build Coastguard Worker          rogue_ref_get_reg_class(&io_sel->srcs[base + 0]));
934*61046927SAndroid Build Coastguard Worker       sA._ = rogue_ref_get_reg_index(&io_sel->srcs[base + 0]);
935*61046927SAndroid Build Coastguard Worker    }
936*61046927SAndroid Build Coastguard Worker 
937*61046927SAndroid Build Coastguard Worker    rogue_sbB sbB = { 0 };
938*61046927SAndroid Build Coastguard Worker    rogue_sB sB = { 0 };
939*61046927SAndroid Build Coastguard Worker 
940*61046927SAndroid Build Coastguard Worker    if (!rogue_ref_is_null(&io_sel->srcs[base + 1])) {
941*61046927SAndroid Build Coastguard Worker       sbB._ = rogue_reg_bank_encoding(
942*61046927SAndroid Build Coastguard Worker          rogue_ref_get_reg_class(&io_sel->srcs[base + 1]));
943*61046927SAndroid Build Coastguard Worker       sB._ = rogue_ref_get_reg_index(&io_sel->srcs[base + 1]);
944*61046927SAndroid Build Coastguard Worker    }
945*61046927SAndroid Build Coastguard Worker 
946*61046927SAndroid Build Coastguard Worker    rogue_sbC sbC = { 0 };
947*61046927SAndroid Build Coastguard Worker    rogue_sC sC = { 0 };
948*61046927SAndroid Build Coastguard Worker 
949*61046927SAndroid Build Coastguard Worker    if (!rogue_ref_is_null(&io_sel->srcs[base + 2])) {
950*61046927SAndroid Build Coastguard Worker       sbC._ = rogue_reg_bank_encoding(
951*61046927SAndroid Build Coastguard Worker          rogue_ref_get_reg_class(&io_sel->srcs[base + 2]));
952*61046927SAndroid Build Coastguard Worker       sC._ = rogue_ref_get_reg_index(&io_sel->srcs[base + 2]);
953*61046927SAndroid Build Coastguard Worker    }
954*61046927SAndroid Build Coastguard Worker 
955*61046927SAndroid Build Coastguard Worker    /* Byte 0 is common for all encodings. */
956*61046927SAndroid Build Coastguard Worker    e->sbA_0 = sbA._0;
957*61046927SAndroid Build Coastguard Worker    e->sA_5_0 = sA._5_0;
958*61046927SAndroid Build Coastguard Worker 
959*61046927SAndroid Build Coastguard Worker    switch (info->num_srcs) {
960*61046927SAndroid Build Coastguard Worker    case 1:
961*61046927SAndroid Build Coastguard Worker       switch (info->bytes) {
962*61046927SAndroid Build Coastguard Worker       case 3:
963*61046927SAndroid Build Coastguard Worker          /* Byte 1 */
964*61046927SAndroid Build Coastguard Worker          assert(!upper_srcs || !mux._1_0);
965*61046927SAndroid Build Coastguard Worker 
966*61046927SAndroid Build Coastguard Worker          e->sA_1.mux_1_0 = mux._1_0;
967*61046927SAndroid Build Coastguard Worker          e->sA_1.sbA_2_1 = sbA._2_1;
968*61046927SAndroid Build Coastguard Worker          e->sA_1.sA_7_6 = sA._7_6;
969*61046927SAndroid Build Coastguard Worker 
970*61046927SAndroid Build Coastguard Worker          /* Byte 2 */
971*61046927SAndroid Build Coastguard Worker          e->sA_2.sA_10_8 = sA._10_8;
972*61046927SAndroid Build Coastguard Worker 
973*61046927SAndroid Build Coastguard Worker          e->ext0 = 1;
974*61046927SAndroid Build Coastguard Worker          FALLTHROUGH;
975*61046927SAndroid Build Coastguard Worker 
976*61046927SAndroid Build Coastguard Worker       case 1:
977*61046927SAndroid Build Coastguard Worker          break;
978*61046927SAndroid Build Coastguard Worker 
979*61046927SAndroid Build Coastguard Worker       default:
980*61046927SAndroid Build Coastguard Worker          unreachable("Unsupported source/bytes combination.");
981*61046927SAndroid Build Coastguard Worker       }
982*61046927SAndroid Build Coastguard Worker       break;
983*61046927SAndroid Build Coastguard Worker 
984*61046927SAndroid Build Coastguard Worker    case 2:
985*61046927SAndroid Build Coastguard Worker       e->ext0 = 1;
986*61046927SAndroid Build Coastguard Worker       e->sel = 1;
987*61046927SAndroid Build Coastguard Worker       switch (info->bytes) {
988*61046927SAndroid Build Coastguard Worker       case 4:
989*61046927SAndroid Build Coastguard Worker          /* Byte 3 */
990*61046927SAndroid Build Coastguard Worker          assert(!upper_srcs || !mux._2);
991*61046927SAndroid Build Coastguard Worker 
992*61046927SAndroid Build Coastguard Worker          e->sB_3.sA_10_8 = sA._10_8;
993*61046927SAndroid Build Coastguard Worker          e->sB_3.mux_2 = mux._2;
994*61046927SAndroid Build Coastguard Worker          e->sB_3.sbA_2 = sbA._2;
995*61046927SAndroid Build Coastguard Worker          e->sB_3.sA_7 = sA._7;
996*61046927SAndroid Build Coastguard Worker          e->sB_3.sB_7 = sB._7;
997*61046927SAndroid Build Coastguard Worker 
998*61046927SAndroid Build Coastguard Worker          e->ext2 = 1;
999*61046927SAndroid Build Coastguard Worker          FALLTHROUGH;
1000*61046927SAndroid Build Coastguard Worker 
1001*61046927SAndroid Build Coastguard Worker       case 3:
1002*61046927SAndroid Build Coastguard Worker          /* Byte 2 */
1003*61046927SAndroid Build Coastguard Worker          assert(!upper_srcs || !mux._1_0);
1004*61046927SAndroid Build Coastguard Worker 
1005*61046927SAndroid Build Coastguard Worker          e->mux_1_0 = mux._1_0;
1006*61046927SAndroid Build Coastguard Worker          e->sbA_1 = sbA._1;
1007*61046927SAndroid Build Coastguard Worker          e->sbB_1 = sbB._1;
1008*61046927SAndroid Build Coastguard Worker          e->sA_6 = sA._6;
1009*61046927SAndroid Build Coastguard Worker          e->sB_6_5 = sB._6_5;
1010*61046927SAndroid Build Coastguard Worker 
1011*61046927SAndroid Build Coastguard Worker          e->ext1 = 1;
1012*61046927SAndroid Build Coastguard Worker          FALLTHROUGH;
1013*61046927SAndroid Build Coastguard Worker 
1014*61046927SAndroid Build Coastguard Worker       case 2:
1015*61046927SAndroid Build Coastguard Worker          /* Byte 1 */
1016*61046927SAndroid Build Coastguard Worker          e->sbB_0 = sbB._0;
1017*61046927SAndroid Build Coastguard Worker          e->sB_4_0 = sB._4_0;
1018*61046927SAndroid Build Coastguard Worker          break;
1019*61046927SAndroid Build Coastguard Worker 
1020*61046927SAndroid Build Coastguard Worker       default:
1021*61046927SAndroid Build Coastguard Worker          unreachable("Unsupported source/bytes combination.");
1022*61046927SAndroid Build Coastguard Worker       }
1023*61046927SAndroid Build Coastguard Worker       break;
1024*61046927SAndroid Build Coastguard Worker 
1025*61046927SAndroid Build Coastguard Worker    case 3:
1026*61046927SAndroid Build Coastguard Worker       e->ext0 = 1;
1027*61046927SAndroid Build Coastguard Worker       e->ext1 = 1;
1028*61046927SAndroid Build Coastguard Worker       switch (info->bytes) {
1029*61046927SAndroid Build Coastguard Worker       case 6:
1030*61046927SAndroid Build Coastguard Worker          /* Byte 5 */
1031*61046927SAndroid Build Coastguard Worker          assert(!upper_srcs || !sC._10_8);
1032*61046927SAndroid Build Coastguard Worker 
1033*61046927SAndroid Build Coastguard Worker          e->sC_5.sC_10_8 = sC._10_8;
1034*61046927SAndroid Build Coastguard Worker          e->sC_5.sA_10_8 = sA._10_8;
1035*61046927SAndroid Build Coastguard Worker 
1036*61046927SAndroid Build Coastguard Worker          e->sC_4.ext4 = 1;
1037*61046927SAndroid Build Coastguard Worker          FALLTHROUGH;
1038*61046927SAndroid Build Coastguard Worker 
1039*61046927SAndroid Build Coastguard Worker       case 5:
1040*61046927SAndroid Build Coastguard Worker          /* Byte 4 */
1041*61046927SAndroid Build Coastguard Worker          assert(!upper_srcs || !mux._2);
1042*61046927SAndroid Build Coastguard Worker          assert(!upper_srcs || !sbC._2);
1043*61046927SAndroid Build Coastguard Worker 
1044*61046927SAndroid Build Coastguard Worker          e->sC_4.sbC_2 = sbC._2;
1045*61046927SAndroid Build Coastguard Worker          e->sC_4.sC_7_6 = sC._7_6;
1046*61046927SAndroid Build Coastguard Worker          e->sC_4.mux_2 = mux._2;
1047*61046927SAndroid Build Coastguard Worker          e->sC_4.sbA_2 = sbA._2;
1048*61046927SAndroid Build Coastguard Worker          e->sC_4.sA_7 = sA._7;
1049*61046927SAndroid Build Coastguard Worker          e->sC_4.sB_7 = sB._7;
1050*61046927SAndroid Build Coastguard Worker 
1051*61046927SAndroid Build Coastguard Worker          e->ext2 = 1;
1052*61046927SAndroid Build Coastguard Worker          FALLTHROUGH;
1053*61046927SAndroid Build Coastguard Worker 
1054*61046927SAndroid Build Coastguard Worker       case 4:
1055*61046927SAndroid Build Coastguard Worker          /* Byte 1 */
1056*61046927SAndroid Build Coastguard Worker          e->sbB_0 = sbB._0;
1057*61046927SAndroid Build Coastguard Worker          e->sB_4_0 = sB._4_0;
1058*61046927SAndroid Build Coastguard Worker 
1059*61046927SAndroid Build Coastguard Worker          /* Byte 2 */
1060*61046927SAndroid Build Coastguard Worker          assert(!upper_srcs || !mux._1_0);
1061*61046927SAndroid Build Coastguard Worker 
1062*61046927SAndroid Build Coastguard Worker          e->mux_1_0 = mux._1_0;
1063*61046927SAndroid Build Coastguard Worker          e->sbA_1 = sbA._1;
1064*61046927SAndroid Build Coastguard Worker          e->sbB_1 = sbB._1;
1065*61046927SAndroid Build Coastguard Worker          e->sA_6 = sA._6;
1066*61046927SAndroid Build Coastguard Worker          e->sB_6_5 = sB._6_5;
1067*61046927SAndroid Build Coastguard Worker 
1068*61046927SAndroid Build Coastguard Worker          /* Byte 3 */
1069*61046927SAndroid Build Coastguard Worker          e->sbC_1_0 = sbC._1_0;
1070*61046927SAndroid Build Coastguard Worker          e->sC_5_0 = sC._5_0;
1071*61046927SAndroid Build Coastguard Worker          break;
1072*61046927SAndroid Build Coastguard Worker 
1073*61046927SAndroid Build Coastguard Worker       default:
1074*61046927SAndroid Build Coastguard Worker          unreachable("Unsupported source/bytes combination.");
1075*61046927SAndroid Build Coastguard Worker       }
1076*61046927SAndroid Build Coastguard Worker       break;
1077*61046927SAndroid Build Coastguard Worker 
1078*61046927SAndroid Build Coastguard Worker    default:
1079*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported source/bytes combination.");
1080*61046927SAndroid Build Coastguard Worker    }
1081*61046927SAndroid Build Coastguard Worker }
1082*61046927SAndroid Build Coastguard Worker 
rogue_encode_dest_map(const rogue_instr_group * group,rogue_dest_map_encoding * e)1083*61046927SAndroid Build Coastguard Worker static void rogue_encode_dest_map(const rogue_instr_group *group,
1084*61046927SAndroid Build Coastguard Worker                                   rogue_dest_map_encoding *e)
1085*61046927SAndroid Build Coastguard Worker {
1086*61046927SAndroid Build Coastguard Worker    const rogue_reg_dst_info *info =
1087*61046927SAndroid Build Coastguard Worker       &rogue_reg_dst_infos[group->encode_info.dst_index];
1088*61046927SAndroid Build Coastguard Worker    const rogue_instr_group_io_sel *io_sel = &group->io_sel;
1089*61046927SAndroid Build Coastguard Worker 
1090*61046927SAndroid Build Coastguard Worker    unsigned num_dsts = !rogue_ref_is_null(&io_sel->dsts[0]) +
1091*61046927SAndroid Build Coastguard Worker                        !rogue_ref_is_null(&io_sel->dsts[1]);
1092*61046927SAndroid Build Coastguard Worker 
1093*61046927SAndroid Build Coastguard Worker    switch (num_dsts) {
1094*61046927SAndroid Build Coastguard Worker    case 1: {
1095*61046927SAndroid Build Coastguard Worker       const rogue_ref *dst_ref = !rogue_ref_is_null(&io_sel->dsts[0])
1096*61046927SAndroid Build Coastguard Worker                                     ? &io_sel->dsts[0]
1097*61046927SAndroid Build Coastguard Worker                                     : &io_sel->dsts[1];
1098*61046927SAndroid Build Coastguard Worker 
1099*61046927SAndroid Build Coastguard Worker       rogue_dbN dbN = { ._ = rogue_reg_bank_encoding(
1100*61046927SAndroid Build Coastguard Worker                            rogue_ref_get_reg_class(dst_ref)) };
1101*61046927SAndroid Build Coastguard Worker       rogue_dN dN = { ._ = rogue_ref_get_reg_index(dst_ref) };
1102*61046927SAndroid Build Coastguard Worker 
1103*61046927SAndroid Build Coastguard Worker       switch (info->bytes) {
1104*61046927SAndroid Build Coastguard Worker       case 2:
1105*61046927SAndroid Build Coastguard Worker          e->dN_10_8 = dN._10_8;
1106*61046927SAndroid Build Coastguard Worker          e->dbN_2_1 = dbN._2_1;
1107*61046927SAndroid Build Coastguard Worker          e->dN_7_6 = dN._7_6;
1108*61046927SAndroid Build Coastguard Worker 
1109*61046927SAndroid Build Coastguard Worker          e->ext0 = 1;
1110*61046927SAndroid Build Coastguard Worker          FALLTHROUGH;
1111*61046927SAndroid Build Coastguard Worker 
1112*61046927SAndroid Build Coastguard Worker       case 1:
1113*61046927SAndroid Build Coastguard Worker          e->dbN_0 = dbN._0;
1114*61046927SAndroid Build Coastguard Worker          e->dN_5_0 = dN._5_0;
1115*61046927SAndroid Build Coastguard Worker          break;
1116*61046927SAndroid Build Coastguard Worker 
1117*61046927SAndroid Build Coastguard Worker       default:
1118*61046927SAndroid Build Coastguard Worker          unreachable("Unsupported dest/bytes combination.");
1119*61046927SAndroid Build Coastguard Worker       }
1120*61046927SAndroid Build Coastguard Worker       break;
1121*61046927SAndroid Build Coastguard Worker    }
1122*61046927SAndroid Build Coastguard Worker    case 2: {
1123*61046927SAndroid Build Coastguard Worker       rogue_db0 db0 = { ._ = rogue_reg_bank_encoding(
1124*61046927SAndroid Build Coastguard Worker                            rogue_ref_get_reg_class(&io_sel->dsts[0])) };
1125*61046927SAndroid Build Coastguard Worker       rogue_d0 d0 = { ._ = rogue_ref_get_reg_index(&io_sel->dsts[0]) };
1126*61046927SAndroid Build Coastguard Worker       rogue_db1 db1 = { ._ = rogue_reg_bank_encoding(
1127*61046927SAndroid Build Coastguard Worker                            rogue_ref_get_reg_class(&io_sel->dsts[1])) };
1128*61046927SAndroid Build Coastguard Worker       rogue_d1 d1 = { ._ = rogue_ref_get_reg_index(&io_sel->dsts[1]) };
1129*61046927SAndroid Build Coastguard Worker 
1130*61046927SAndroid Build Coastguard Worker       switch (info->bytes) {
1131*61046927SAndroid Build Coastguard Worker       case 4:
1132*61046927SAndroid Build Coastguard Worker          e->d1_10_8 = d1._10_8;
1133*61046927SAndroid Build Coastguard Worker          e->d0_10_8 = d0._10_8;
1134*61046927SAndroid Build Coastguard Worker 
1135*61046927SAndroid Build Coastguard Worker          e->ext2 = 1;
1136*61046927SAndroid Build Coastguard Worker          FALLTHROUGH;
1137*61046927SAndroid Build Coastguard Worker 
1138*61046927SAndroid Build Coastguard Worker       case 3:
1139*61046927SAndroid Build Coastguard Worker          e->db1_2_1 = db1._2_1;
1140*61046927SAndroid Build Coastguard Worker          e->d1_7_6 = d1._7_6;
1141*61046927SAndroid Build Coastguard Worker          e->db0_2_1 = db0._2_1;
1142*61046927SAndroid Build Coastguard Worker          e->d0_7 = d0._7;
1143*61046927SAndroid Build Coastguard Worker 
1144*61046927SAndroid Build Coastguard Worker          e->ext1 = 1;
1145*61046927SAndroid Build Coastguard Worker          FALLTHROUGH;
1146*61046927SAndroid Build Coastguard Worker 
1147*61046927SAndroid Build Coastguard Worker       case 2:
1148*61046927SAndroid Build Coastguard Worker          e->db0_0 = db0._0;
1149*61046927SAndroid Build Coastguard Worker          e->d0_6_0 = d0._6_0;
1150*61046927SAndroid Build Coastguard Worker 
1151*61046927SAndroid Build Coastguard Worker          e->db1_0 = db1._0;
1152*61046927SAndroid Build Coastguard Worker          e->d1_5_0 = d1._5_0;
1153*61046927SAndroid Build Coastguard Worker          break;
1154*61046927SAndroid Build Coastguard Worker 
1155*61046927SAndroid Build Coastguard Worker       default:
1156*61046927SAndroid Build Coastguard Worker          unreachable("Unsupported dest/bytes combination.");
1157*61046927SAndroid Build Coastguard Worker       }
1158*61046927SAndroid Build Coastguard Worker    } break;
1159*61046927SAndroid Build Coastguard Worker 
1160*61046927SAndroid Build Coastguard Worker    default:
1161*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported dest/bytes combination.");
1162*61046927SAndroid Build Coastguard Worker    }
1163*61046927SAndroid Build Coastguard Worker }
1164*61046927SAndroid Build Coastguard Worker 
rogue_encode_iss_map(const rogue_instr_group * group,rogue_iss_encoding * e)1165*61046927SAndroid Build Coastguard Worker static void rogue_encode_iss_map(const rogue_instr_group *group,
1166*61046927SAndroid Build Coastguard Worker                                  rogue_iss_encoding *e)
1167*61046927SAndroid Build Coastguard Worker {
1168*61046927SAndroid Build Coastguard Worker    const rogue_instr_group_io_sel *io_sel = &group->io_sel;
1169*61046927SAndroid Build Coastguard Worker 
1170*61046927SAndroid Build Coastguard Worker    if (rogue_ref_is_io(&io_sel->iss[1]))
1171*61046927SAndroid Build Coastguard Worker       switch (rogue_ref_get_io(&io_sel->iss[1])) {
1172*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_FT0:
1173*61046927SAndroid Build Coastguard Worker          e->is1 = IS1_FT0;
1174*61046927SAndroid Build Coastguard Worker          break;
1175*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_FTE:
1176*61046927SAndroid Build Coastguard Worker          e->is1 = IS1_FTE;
1177*61046927SAndroid Build Coastguard Worker          break;
1178*61046927SAndroid Build Coastguard Worker 
1179*61046927SAndroid Build Coastguard Worker       default:
1180*61046927SAndroid Build Coastguard Worker          unreachable("Unsupported setting for IS1.");
1181*61046927SAndroid Build Coastguard Worker       }
1182*61046927SAndroid Build Coastguard Worker 
1183*61046927SAndroid Build Coastguard Worker    if (rogue_ref_is_io(&io_sel->iss[2]))
1184*61046927SAndroid Build Coastguard Worker       switch (rogue_ref_get_io(&io_sel->iss[2])) {
1185*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_FT1:
1186*61046927SAndroid Build Coastguard Worker          e->is2 = IS2_FT1;
1187*61046927SAndroid Build Coastguard Worker          break;
1188*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_FTE:
1189*61046927SAndroid Build Coastguard Worker          e->is2 = IS2_FTE;
1190*61046927SAndroid Build Coastguard Worker          break;
1191*61046927SAndroid Build Coastguard Worker 
1192*61046927SAndroid Build Coastguard Worker       default:
1193*61046927SAndroid Build Coastguard Worker          unreachable("Unsupported setting for IS2.");
1194*61046927SAndroid Build Coastguard Worker       }
1195*61046927SAndroid Build Coastguard Worker 
1196*61046927SAndroid Build Coastguard Worker    if (rogue_ref_is_io(&io_sel->iss[3]))
1197*61046927SAndroid Build Coastguard Worker       switch (rogue_ref_get_io(&io_sel->iss[3])) {
1198*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_FT0:
1199*61046927SAndroid Build Coastguard Worker          e->is3 = IS3_FT0;
1200*61046927SAndroid Build Coastguard Worker          break;
1201*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_FT1:
1202*61046927SAndroid Build Coastguard Worker          e->is3 = IS3_FT1;
1203*61046927SAndroid Build Coastguard Worker          break;
1204*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_S2:
1205*61046927SAndroid Build Coastguard Worker          e->is3 = IS3_S2;
1206*61046927SAndroid Build Coastguard Worker          break;
1207*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_FTE:
1208*61046927SAndroid Build Coastguard Worker          e->is3 = IS3_FTE;
1209*61046927SAndroid Build Coastguard Worker          break;
1210*61046927SAndroid Build Coastguard Worker 
1211*61046927SAndroid Build Coastguard Worker       default:
1212*61046927SAndroid Build Coastguard Worker          unreachable("Unsupported setting for IS3.");
1213*61046927SAndroid Build Coastguard Worker       }
1214*61046927SAndroid Build Coastguard Worker 
1215*61046927SAndroid Build Coastguard Worker    if (rogue_ref_is_io(&io_sel->iss[4]))
1216*61046927SAndroid Build Coastguard Worker       switch (rogue_ref_get_io(&io_sel->iss[4])) {
1217*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_FT0:
1218*61046927SAndroid Build Coastguard Worker          e->is4 = IS4_FT0;
1219*61046927SAndroid Build Coastguard Worker          break;
1220*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_FT1:
1221*61046927SAndroid Build Coastguard Worker          e->is4 = IS4_FT1;
1222*61046927SAndroid Build Coastguard Worker          break;
1223*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_FT2:
1224*61046927SAndroid Build Coastguard Worker          e->is4 = IS4_FT2;
1225*61046927SAndroid Build Coastguard Worker          break;
1226*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_FTE:
1227*61046927SAndroid Build Coastguard Worker          e->is4 = IS4_FTE;
1228*61046927SAndroid Build Coastguard Worker          break;
1229*61046927SAndroid Build Coastguard Worker 
1230*61046927SAndroid Build Coastguard Worker       default:
1231*61046927SAndroid Build Coastguard Worker          unreachable("Unsupported setting for IS4.");
1232*61046927SAndroid Build Coastguard Worker       }
1233*61046927SAndroid Build Coastguard Worker 
1234*61046927SAndroid Build Coastguard Worker    if (rogue_ref_is_io(&io_sel->iss[5]))
1235*61046927SAndroid Build Coastguard Worker       switch (rogue_ref_get_io(&io_sel->iss[5])) {
1236*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_FT0:
1237*61046927SAndroid Build Coastguard Worker          e->is5 = IS5_FT0;
1238*61046927SAndroid Build Coastguard Worker          break;
1239*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_FT1:
1240*61046927SAndroid Build Coastguard Worker          e->is5 = IS5_FT1;
1241*61046927SAndroid Build Coastguard Worker          break;
1242*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_FT2:
1243*61046927SAndroid Build Coastguard Worker          e->is5 = IS5_FT2;
1244*61046927SAndroid Build Coastguard Worker          break;
1245*61046927SAndroid Build Coastguard Worker       case ROGUE_IO_FTE:
1246*61046927SAndroid Build Coastguard Worker          e->is5 = IS5_FTE;
1247*61046927SAndroid Build Coastguard Worker          break;
1248*61046927SAndroid Build Coastguard Worker 
1249*61046927SAndroid Build Coastguard Worker       default:
1250*61046927SAndroid Build Coastguard Worker          unreachable("Unsupported setting for IS5.");
1251*61046927SAndroid Build Coastguard Worker       }
1252*61046927SAndroid Build Coastguard Worker }
1253*61046927SAndroid Build Coastguard Worker 
rogue_encode_instr_group_io(const rogue_instr_group * group,struct util_dynarray * binary)1254*61046927SAndroid Build Coastguard Worker static void rogue_encode_instr_group_io(const rogue_instr_group *group,
1255*61046927SAndroid Build Coastguard Worker                                         struct util_dynarray *binary)
1256*61046927SAndroid Build Coastguard Worker {
1257*61046927SAndroid Build Coastguard Worker    if (group->size.lower_srcs) {
1258*61046927SAndroid Build Coastguard Worker       rogue_source_map_encoding lower_srcs = { 0 };
1259*61046927SAndroid Build Coastguard Worker       rogue_encode_source_map(group, false, &lower_srcs);
1260*61046927SAndroid Build Coastguard Worker       util_dynarray_append_mem(binary, group->size.lower_srcs, &lower_srcs);
1261*61046927SAndroid Build Coastguard Worker    }
1262*61046927SAndroid Build Coastguard Worker 
1263*61046927SAndroid Build Coastguard Worker    if (group->size.upper_srcs) {
1264*61046927SAndroid Build Coastguard Worker       rogue_source_map_encoding upper_srcs = { 0 };
1265*61046927SAndroid Build Coastguard Worker       rogue_encode_source_map(group, true, &upper_srcs);
1266*61046927SAndroid Build Coastguard Worker       util_dynarray_append_mem(binary, group->size.upper_srcs, &upper_srcs);
1267*61046927SAndroid Build Coastguard Worker    }
1268*61046927SAndroid Build Coastguard Worker 
1269*61046927SAndroid Build Coastguard Worker    if (group->size.iss) {
1270*61046927SAndroid Build Coastguard Worker       rogue_iss_encoding internal_src_sel = { 0 };
1271*61046927SAndroid Build Coastguard Worker       rogue_encode_iss_map(group, &internal_src_sel);
1272*61046927SAndroid Build Coastguard Worker       util_dynarray_append_mem(binary, group->size.iss, &internal_src_sel);
1273*61046927SAndroid Build Coastguard Worker    }
1274*61046927SAndroid Build Coastguard Worker 
1275*61046927SAndroid Build Coastguard Worker    if (group->size.dsts) {
1276*61046927SAndroid Build Coastguard Worker       rogue_dest_map_encoding dests = { 0 };
1277*61046927SAndroid Build Coastguard Worker       rogue_encode_dest_map(group, &dests);
1278*61046927SAndroid Build Coastguard Worker       util_dynarray_append_mem(binary, group->size.dsts, &dests);
1279*61046927SAndroid Build Coastguard Worker    }
1280*61046927SAndroid Build Coastguard Worker }
1281*61046927SAndroid Build Coastguard Worker 
rogue_encode_instr_group_padding(const rogue_instr_group * group,struct util_dynarray * binary)1282*61046927SAndroid Build Coastguard Worker static void rogue_encode_instr_group_padding(const rogue_instr_group *group,
1283*61046927SAndroid Build Coastguard Worker                                              struct util_dynarray *binary)
1284*61046927SAndroid Build Coastguard Worker {
1285*61046927SAndroid Build Coastguard Worker    if (group->size.word_padding)
1286*61046927SAndroid Build Coastguard Worker       util_dynarray_append(binary, uint8_t, 0xff);
1287*61046927SAndroid Build Coastguard Worker 
1288*61046927SAndroid Build Coastguard Worker    if (group->size.align_padding) {
1289*61046927SAndroid Build Coastguard Worker       assert(!(group->size.align_padding % 2));
1290*61046927SAndroid Build Coastguard Worker       unsigned align_words = group->size.align_padding / 2;
1291*61046927SAndroid Build Coastguard Worker       util_dynarray_append(binary, uint8_t, 0xf0 | align_words);
1292*61046927SAndroid Build Coastguard Worker       for (unsigned u = 0; u < group->size.align_padding - 1; ++u)
1293*61046927SAndroid Build Coastguard Worker          util_dynarray_append(binary, uint8_t, 0xff);
1294*61046927SAndroid Build Coastguard Worker    }
1295*61046927SAndroid Build Coastguard Worker }
1296*61046927SAndroid Build Coastguard Worker 
rogue_encode_instr_group(rogue_instr_group * group,struct util_dynarray * binary)1297*61046927SAndroid Build Coastguard Worker static void rogue_encode_instr_group(rogue_instr_group *group,
1298*61046927SAndroid Build Coastguard Worker                                      struct util_dynarray *binary)
1299*61046927SAndroid Build Coastguard Worker {
1300*61046927SAndroid Build Coastguard Worker    rogue_encode_instr_group_header(group, binary);
1301*61046927SAndroid Build Coastguard Worker    rogue_encode_instr_group_instrs(group, binary);
1302*61046927SAndroid Build Coastguard Worker    rogue_encode_instr_group_io(group, binary);
1303*61046927SAndroid Build Coastguard Worker    rogue_encode_instr_group_padding(group, binary);
1304*61046927SAndroid Build Coastguard Worker }
1305*61046927SAndroid Build Coastguard Worker 
1306*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_encode_shader(rogue_build_ctx * ctx,rogue_shader * shader,struct util_dynarray * binary)1307*61046927SAndroid Build Coastguard Worker void rogue_encode_shader(rogue_build_ctx *ctx,
1308*61046927SAndroid Build Coastguard Worker                          rogue_shader *shader,
1309*61046927SAndroid Build Coastguard Worker                          struct util_dynarray *binary)
1310*61046927SAndroid Build Coastguard Worker {
1311*61046927SAndroid Build Coastguard Worker    if (!shader->is_grouped)
1312*61046927SAndroid Build Coastguard Worker       unreachable("Can't encode shader with ungrouped instructions.");
1313*61046927SAndroid Build Coastguard Worker 
1314*61046927SAndroid Build Coastguard Worker    util_dynarray_init(binary, ctx);
1315*61046927SAndroid Build Coastguard Worker 
1316*61046927SAndroid Build Coastguard Worker    rogue_foreach_instr_group_in_shader (group, shader)
1317*61046927SAndroid Build Coastguard Worker       rogue_encode_instr_group(group, binary);
1318*61046927SAndroid Build Coastguard Worker }
1319