Refine the shared function ID define.
[contrib/beignet.git] / backend / src / backend / gen8_encoder.cpp
1 /*
2  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
3  Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4  develop this 3D driver.
5
6  Permission is hereby granted, free of charge, to any person obtaining
7  a copy of this software and associated documentation files (the
8  "Software"), to deal in the Software without restriction, including
9  without limitation the rights to use, copy, modify, merge, publish,
10  distribute, sublicense, and/or sell copies of the Software, and to
11  permit persons to whom the Software is furnished to do so, subject to
12  the following conditions:
13
14  The above copyright notice and this permission notice (including the
15  next paragraph) shall be included in all copies or substantial
16  portions of the Software.
17
18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26  **********************************************************************/
27
28 #include "backend/gen8_encoder.hpp"
29
30 static const uint32_t untypedRWMask[] = {
31   GEN_UNTYPED_ALPHA|GEN_UNTYPED_BLUE|GEN_UNTYPED_GREEN|GEN_UNTYPED_RED,
32   GEN_UNTYPED_ALPHA|GEN_UNTYPED_BLUE|GEN_UNTYPED_GREEN,
33   GEN_UNTYPED_ALPHA|GEN_UNTYPED_BLUE,
34   GEN_UNTYPED_ALPHA,
35   0
36 };
37
38 namespace gbe
39 {
40   void Gen8Encoder::setHeader(GenNativeInstruction *insn) {
41     Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
42     if (this->curr.execWidth == 8)
43       gen8_insn->header.execution_size = GEN_WIDTH_8;
44     else if (this->curr.execWidth == 16)
45       gen8_insn->header.execution_size = GEN_WIDTH_16;
46     else if (this->curr.execWidth == 1)
47       gen8_insn->header.execution_size = GEN_WIDTH_1;
48     else if (this->curr.execWidth == 4)
49       gen8_insn->header.execution_size = GEN_WIDTH_4;
50     else
51       NOT_IMPLEMENTED;
52     gen8_insn->header.acc_wr_control = this->curr.accWrEnable;
53     gen8_insn->header.quarter_control = this->curr.quarterControl;
54     gen8_insn->header.nib_ctrl = this->curr.nibControl;
55     gen8_insn->bits1.ia1.mask_control = this->curr.noMask;
56     gen8_insn->bits1.ia1.flag_reg_nr = this->curr.flag;
57     gen8_insn->bits1.ia1.flag_sub_reg_nr = this->curr.subFlag;
58     if (this->curr.predicate != GEN_PREDICATE_NONE) {
59       gen8_insn->header.predicate_control = this->curr.predicate;
60       gen8_insn->header.predicate_inverse = this->curr.inversePredicate;
61     }
62     gen8_insn->header.saturate = this->curr.saturate;
63   }
64
65   void Gen8Encoder::setDPUntypedRW(GenNativeInstruction *insn,
66                                     uint32_t bti,
67                                     uint32_t rgba,
68                                     uint32_t msg_type,
69                                     uint32_t msg_length,
70                                     uint32_t response_length)
71   {
72     Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
73     const GenMessageTarget sfid = GEN_SFID_DATAPORT1_DATA;
74     setMessageDescriptor(insn, sfid, msg_length, response_length);
75     gen8_insn->bits3.gen7_untyped_rw.msg_type = msg_type;
76     gen8_insn->bits3.gen7_untyped_rw.bti = bti;
77     gen8_insn->bits3.gen7_untyped_rw.rgba = rgba;
78     if (curr.execWidth == 8)
79       gen8_insn->bits3.gen7_untyped_rw.simd_mode = GEN_UNTYPED_SIMD8;
80     else if (curr.execWidth == 16)
81       gen8_insn->bits3.gen7_untyped_rw.simd_mode = GEN_UNTYPED_SIMD16;
82     else
83       NOT_SUPPORTED;
84   }
85
86   void Gen8Encoder::setTypedWriteMessage(GenNativeInstruction *insn, unsigned char bti,
87                                           unsigned char msg_type, uint32_t msg_length, bool header_present)
88   {
89     Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
90     const GenMessageTarget sfid = GEN_SFID_DATAPORT1_DATA;
91     setMessageDescriptor(insn, sfid, msg_length, 0, header_present);
92     gen8_insn->bits3.gen7_typed_rw.bti = bti;
93     gen8_insn->bits3.gen7_typed_rw.msg_type = msg_type;
94
95     /* Always using the low 8 slots here. */
96     gen8_insn->bits3.gen7_typed_rw.slot = 1;
97   }
98
99   void Gen8Encoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister src, uint32_t bti, uint32_t srcNum) {
100     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
101     Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
102     uint32_t msg_length = 0;
103     uint32_t response_length = 0;
104
105     if (this->curr.execWidth == 8) {
106       msg_length = srcNum;
107       response_length = 1;
108     } else if (this->curr.execWidth == 16) {
109       msg_length = 2 * srcNum;
110       response_length = 2;
111     } else
112       NOT_IMPLEMENTED;
113
114     this->setHeader(insn);
115     this->setDst(insn, GenRegister::uw16grf(dst.nr, 0));
116     this->setSrc0(insn, GenRegister::ud8grf(src.nr, 0));
117     this->setSrc1(insn, GenRegister::immud(0));
118
119     const GenMessageTarget sfid = GEN_SFID_DATAPORT1_DATA;
120     setMessageDescriptor(insn, sfid, msg_length, response_length);
121     gen8_insn->bits3.gen7_atomic_op.msg_type = GEN75_P1_UNTYPED_ATOMIC_OP;
122     gen8_insn->bits3.gen7_atomic_op.bti = bti;
123     gen8_insn->bits3.gen7_atomic_op.return_data = 1;
124     gen8_insn->bits3.gen7_atomic_op.aop_type = function;
125
126     if (this->curr.execWidth == 8)
127       gen8_insn->bits3.gen7_atomic_op.simd_mode = GEN_ATOMIC_SIMD8;
128     else if (this->curr.execWidth == 16)
129       gen8_insn->bits3.gen7_atomic_op.simd_mode = GEN_ATOMIC_SIMD16;
130     else
131       NOT_SUPPORTED;
132   }
133
134   void Gen8Encoder::UNTYPED_READ(GenRegister dst, GenRegister src, uint32_t bti, uint32_t elemNum) {
135     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
136     assert(elemNum >= 1 || elemNum <= 4);
137     uint32_t msg_length = 0;
138     uint32_t response_length = 0;
139     if (this->curr.execWidth == 8) {
140       msg_length = 1;
141       response_length = elemNum;
142     } else if (this->curr.execWidth == 16) {
143       msg_length = 2;
144       response_length = 2 * elemNum;
145     } else
146       NOT_IMPLEMENTED;
147
148     this->setHeader(insn);
149     this->setDst(insn,  GenRegister::uw16grf(dst.nr, 0));
150     this->setSrc0(insn, GenRegister::ud8grf(src.nr, 0));
151     this->setSrc1(insn, GenRegister::immud(0));
152     setDPUntypedRW(insn,
153                    bti,
154                    untypedRWMask[elemNum],
155                    GEN75_P1_UNTYPED_READ,
156                    msg_length,
157                    response_length);
158   }
159
160   void Gen8Encoder::UNTYPED_WRITE(GenRegister msg, uint32_t bti, uint32_t elemNum) {
161     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
162     assert(elemNum >= 1 || elemNum <= 4);
163     uint32_t msg_length = 0;
164     uint32_t response_length = 0;
165     this->setHeader(insn);
166     if (this->curr.execWidth == 8) {
167       this->setDst(insn, GenRegister::retype(GenRegister::null(), GEN_TYPE_UD));
168       msg_length = 1 + elemNum;
169     } else if (this->curr.execWidth == 16) {
170       this->setDst(insn, GenRegister::retype(GenRegister::null(), GEN_TYPE_UW));
171       msg_length = 2 * (1 + elemNum);
172     }
173     else
174       NOT_IMPLEMENTED;
175     this->setSrc0(insn, GenRegister::ud8grf(msg.nr, 0));
176     this->setSrc1(insn, GenRegister::immud(0));
177     setDPUntypedRW(insn,
178                    bti,
179                    untypedRWMask[elemNum],
180                    GEN75_P1_UNTYPED_SURFACE_WRITE,
181                    msg_length,
182                    response_length);
183   }
184
185   void Gen8Encoder::LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value) {
186     union { double d; unsigned u[2]; } u;
187     u.d = value;
188     GenRegister r = GenRegister::retype(tmp, GEN_TYPE_UD);
189     push();
190     curr.predicate = GEN_PREDICATE_NONE;
191     curr.noMask = 1;
192     curr.execWidth = 1;
193     MOV(r, GenRegister::immud(u.u[0]));
194     MOV(GenRegister::suboffset(r, 1), GenRegister::immud(u.u[1]));
195     pop();
196     r.type = GEN_TYPE_DF;
197     r.vstride = GEN_VERTICAL_STRIDE_0;
198     r.width = GEN_WIDTH_1;
199     r.hstride = GEN_HORIZONTAL_STRIDE_0;
200     push();
201     uint32_t width = curr.execWidth;
202     curr.execWidth = 8;
203     curr.predicate = GEN_PREDICATE_NONE;
204     curr.noMask = 1;
205     curr.quarterControl = GEN_COMPRESSION_Q1;
206     MOV(dest, r);
207     if (width == 16) {
208       curr.quarterControl = GEN_COMPRESSION_Q2;
209       MOV(GenRegister::offset(dest, 2), r);
210     }
211     pop();
212   }
213
214   void Gen8Encoder::MOV_DF(GenRegister dest, GenRegister src0, GenRegister r) {
215     GBE_ASSERT((src0.type == GEN_TYPE_F && dest.isdf()) || (src0.isdf() && dest.type == GEN_TYPE_F));
216     int w = curr.execWidth;
217     GenRegister r0;
218     r0 = GenRegister::h2(r);
219     push();
220     curr.execWidth = 4;
221     curr.predicate = GEN_PREDICATE_NONE;
222     curr.noMask = 1;
223     MOV(r0, src0);
224     MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 4));
225     curr.noMask = 0;
226     curr.quarterControl = 0;
227     curr.nibControl = 0;
228     MOV(dest, r0);
229     curr.nibControl = 1;
230     MOV(GenRegister::suboffset(dest, 4), GenRegister::suboffset(r0, 4));
231     pop();
232     if (w == 16) {
233       push();
234       curr.execWidth = 4;
235       curr.predicate = GEN_PREDICATE_NONE;
236       curr.noMask = 1;
237       MOV(r0, GenRegister::suboffset(src0, 8));
238       MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 12));
239       curr.noMask = 0;
240       curr.quarterControl = 1;
241       curr.nibControl = 0;
242       MOV(GenRegister::suboffset(dest, 8), r0);
243       curr.nibControl = 1;
244       MOV(GenRegister::suboffset(dest, 12), GenRegister::suboffset(r0, 4));
245       pop();
246     }
247   }
248
249   void Gen8Encoder::JMPI(GenRegister src, bool longjmp) {
250     alu2(this, GEN_OPCODE_JMPI, GenRegister::ip(), GenRegister::ip(), src);
251   }
252
253   void Gen8Encoder::patchJMPI(uint32_t insnID, int32_t jip, int32_t uip) {
254     GenNativeInstruction &insn = *(GenNativeInstruction *)&this->store[insnID];
255     GBE_ASSERT(insnID < this->store.size());
256     GBE_ASSERT(insn.header.opcode == GEN_OPCODE_JMPI ||
257                insn.header.opcode == GEN_OPCODE_BRD  ||
258                insn.header.opcode == GEN_OPCODE_ENDIF ||
259                insn.header.opcode == GEN_OPCODE_IF ||
260                insn.header.opcode == GEN_OPCODE_BRC ||
261                insn.header.opcode == GEN_OPCODE_WHILE ||
262                insn.header.opcode == GEN_OPCODE_ELSE);
263
264     if( insn.header.opcode == GEN_OPCODE_WHILE ) {
265       // if this WHILE instruction jump back to an ELSE instruction,
266       // need add distance to go to the next instruction.
267       GenNativeInstruction & insn_else = *(GenNativeInstruction *)&this->store[insnID+jip];
268       if(insn_else.header.opcode == GEN_OPCODE_ELSE) {
269         jip += 2;
270       }
271     }
272
273     if(insn.header.opcode == GEN_OPCODE_ELSE)
274       uip = jip;
275
276     if (insn.header.opcode == GEN_OPCODE_IF ||
277         insn.header.opcode == GEN_OPCODE_ELSE) {
278       Gen8NativeInstruction *gen8_insn = &insn.gen8_insn;
279       this->setSrc0(&insn, GenRegister::immud(0));
280       gen8_insn->bits2.gen8_branch.uip = uip*8;
281       gen8_insn->bits3.gen8_branch.jip = jip*8;
282       return;
283     }
284     else if (insn.header.opcode == GEN_OPCODE_JMPI) {
285       //jumpDistance'unit is Qword, and the HSW's offset of jmpi is in byte, so multi 8
286       jip = (jip - 2);
287     }
288
289     this->setSrc1(&insn, GenRegister::immd(jip*8));
290   }
291
292   void Gen8Encoder::setDst(GenNativeInstruction *insn, GenRegister dest) {
293     Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
294     if (dest.file != GEN_ARCHITECTURE_REGISTER_FILE)
295       assert(dest.nr < 128);
296
297     gen8_insn->bits1.da1.dest_reg_file = dest.file;
298     gen8_insn->bits1.da1.dest_reg_type = dest.type;
299     gen8_insn->bits1.da1.dest_address_mode = dest.address_mode;
300     gen8_insn->bits1.da1.dest_reg_nr = dest.nr;
301     gen8_insn->bits1.da1.dest_subreg_nr = dest.subnr;
302     if (dest.hstride == GEN_HORIZONTAL_STRIDE_0) {
303       if (dest.type == GEN_TYPE_UB || dest.type == GEN_TYPE_B)
304         dest.hstride = GEN_HORIZONTAL_STRIDE_4;
305       else if (dest.type == GEN_TYPE_UW || dest.type == GEN_TYPE_W)
306         dest.hstride = GEN_HORIZONTAL_STRIDE_2;
307       else
308         dest.hstride = GEN_HORIZONTAL_STRIDE_1;
309     }
310     gen8_insn->bits1.da1.dest_horiz_stride = dest.hstride;
311   }
312
313   void Gen8Encoder::setSrc0(GenNativeInstruction *insn, GenRegister reg) {
314     Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
315     if (reg.file != GEN_ARCHITECTURE_REGISTER_FILE)
316       assert(reg.nr < 128);
317
318     if (reg.address_mode == GEN_ADDRESS_DIRECT) {
319       gen8_insn->bits1.da1.src0_reg_file = reg.file;
320       gen8_insn->bits1.da1.src0_reg_type = reg.type;
321       gen8_insn->bits2.da1.src0_abs = reg.absolute;
322       gen8_insn->bits2.da1.src0_negate = reg.negation;
323       gen8_insn->bits2.da1.src0_address_mode = reg.address_mode;
324       if (reg.file == GEN_IMMEDIATE_VALUE) {
325         gen8_insn->bits3.ud = reg.value.ud;
326
327         /* Required to set some fields in src1 as well: */
328         gen8_insn->bits2.da1.src1_reg_file = 0; /* arf */
329         gen8_insn->bits2.da1.src1_reg_type = reg.type;
330       }
331       else {
332         if (gen8_insn->header.access_mode == GEN_ALIGN_1) {
333           gen8_insn->bits2.da1.src0_subreg_nr = reg.subnr;
334           gen8_insn->bits2.da1.src0_reg_nr = reg.nr;
335         } else {
336           gen8_insn->bits2.da16.src0_subreg_nr = reg.subnr / 16;
337           gen8_insn->bits2.da16.src0_reg_nr = reg.nr;
338         }
339
340         if (reg.width == GEN_WIDTH_1 &&
341             gen8_insn->header.execution_size == GEN_WIDTH_1) {
342           gen8_insn->bits2.da1.src0_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
343           gen8_insn->bits2.da1.src0_width = GEN_WIDTH_1;
344           gen8_insn->bits2.da1.src0_vert_stride = GEN_VERTICAL_STRIDE_0;
345         }
346         else {
347           gen8_insn->bits2.da1.src0_horiz_stride = reg.hstride;
348           gen8_insn->bits2.da1.src0_width = reg.width;
349           gen8_insn->bits2.da1.src0_vert_stride = reg.vstride;
350         }
351       }
352     } else {
353       gen8_insn->bits1.ia1.src0_reg_file = GEN_GENERAL_REGISTER_FILE;
354       gen8_insn->bits1.ia1.src0_reg_type = reg.type;
355       gen8_insn->bits2.ia1.src0_subreg_nr = 0;
356       gen8_insn->bits2.ia1.src0_indirect_offset = 0;
357       gen8_insn->bits2.ia1.src0_abs = 0;
358       gen8_insn->bits2.ia1.src0_negate = 0;
359       gen8_insn->bits2.ia1.src0_address_mode = reg.address_mode;
360       gen8_insn->bits2.ia1.src0_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
361       gen8_insn->bits2.ia1.src0_width = GEN_WIDTH_1;
362       gen8_insn->bits2.ia1.src0_vert_stride = GEN_VERTICAL_STRIDE_ONE_DIMENSIONAL;
363     }
364   }
365
366   void Gen8Encoder::setSrc1(GenNativeInstruction *insn, GenRegister reg) {
367     Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
368     assert(reg.nr < 128);
369     assert(reg.file != GEN_ARCHITECTURE_REGISTER_FILE || reg.nr == 0);
370
371     gen8_insn->bits2.da1.src1_reg_file = reg.file;
372     gen8_insn->bits2.da1.src1_reg_type = reg.type;
373     gen8_insn->bits3.da1.src1_abs = reg.absolute;
374     gen8_insn->bits3.da1.src1_negate = reg.negation;
375
376     assert(gen8_insn->bits1.da1.src0_reg_file != GEN_IMMEDIATE_VALUE);
377
378     if (reg.file == GEN_IMMEDIATE_VALUE)
379       gen8_insn->bits3.ud = reg.value.ud;
380     else {
381       assert (reg.address_mode == GEN_ADDRESS_DIRECT);
382       if (gen8_insn->header.access_mode == GEN_ALIGN_1) {
383         gen8_insn->bits3.da1.src1_subreg_nr = reg.subnr;
384         gen8_insn->bits3.da1.src1_reg_nr = reg.nr;
385       } else {
386         gen8_insn->bits3.da16.src1_subreg_nr = reg.subnr / 16;
387         gen8_insn->bits3.da16.src1_reg_nr = reg.nr;
388       }
389
390       if (reg.width == GEN_WIDTH_1 &&
391           gen8_insn->header.execution_size == GEN_WIDTH_1) {
392         gen8_insn->bits3.da1.src1_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
393         gen8_insn->bits3.da1.src1_width = GEN_WIDTH_1;
394         gen8_insn->bits3.da1.src1_vert_stride = GEN_VERTICAL_STRIDE_0;
395       } else {
396         gen8_insn->bits3.da1.src1_horiz_stride = reg.hstride;
397         gen8_insn->bits3.da1.src1_width = reg.width;
398         gen8_insn->bits3.da1.src1_vert_stride = reg.vstride;
399       }
400     }
401   }
402
403 #define NO_SWIZZLE ((0<<0) | (1<<2) | (2<<4) | (3<<6))
404
405   void Gen8Encoder::alu3(uint32_t opcode,
406                               GenRegister dest,
407                               GenRegister src0,
408                               GenRegister src1,
409                               GenRegister src2)
410   {
411      GenNativeInstruction *insn = this->next(opcode);
412      Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
413
414      assert(dest.file == GEN_GENERAL_REGISTER_FILE);
415      assert(dest.nr < 128);
416      assert(dest.address_mode == GEN_ADDRESS_DIRECT);
417      assert(dest.type = GEN_TYPE_F);
418      //gen8_insn->bits1.da3src.dest_reg_file = 0;
419      gen8_insn->bits1.da3src.dest_reg_nr = dest.nr;
420      gen8_insn->bits1.da3src.dest_subreg_nr = dest.subnr / 16;
421      gen8_insn->bits1.da3src.dest_writemask = 0xf;
422      this->setHeader(insn);
423      gen8_insn->header.access_mode = GEN_ALIGN_16;
424      gen8_insn->header.execution_size = GEN_WIDTH_8;
425
426      assert(src0.file == GEN_GENERAL_REGISTER_FILE);
427      assert(src0.address_mode == GEN_ADDRESS_DIRECT);
428      assert(src0.nr < 128);
429      assert(src0.type == GEN_TYPE_F);
430      gen8_insn->bits2.da3src.src0_swizzle = NO_SWIZZLE;
431      gen8_insn->bits2.da3src.src0_subreg_nr = src0.subnr / 4 ;
432      gen8_insn->bits2.da3src.src0_reg_nr = src0.nr;
433      gen8_insn->bits1.da3src.src0_abs = src0.absolute;
434      gen8_insn->bits1.da3src.src0_negate = src0.negation;
435      gen8_insn->bits2.da3src.src0_rep_ctrl = src0.vstride == GEN_VERTICAL_STRIDE_0;
436
437      assert(src1.file == GEN_GENERAL_REGISTER_FILE);
438      assert(src1.address_mode == GEN_ADDRESS_DIRECT);
439      assert(src1.nr < 128);
440      assert(src1.type == GEN_TYPE_F);
441      gen8_insn->bits2.da3src.src1_swizzle = NO_SWIZZLE;
442      gen8_insn->bits2.da3src.src1_subreg_nr_low = (src1.subnr / 4) & 0x3;
443      gen8_insn->bits3.da3src.src1_subreg_nr_high = (src1.subnr / 4) >> 2;
444      gen8_insn->bits2.da3src.src1_rep_ctrl = src1.vstride == GEN_VERTICAL_STRIDE_0;
445      gen8_insn->bits3.da3src.src1_reg_nr = src1.nr;
446      gen8_insn->bits1.da3src.src1_abs = src1.absolute;
447      gen8_insn->bits1.da3src.src1_negate = src1.negation;
448
449      assert(src2.file == GEN_GENERAL_REGISTER_FILE);
450      assert(src2.address_mode == GEN_ADDRESS_DIRECT);
451      assert(src2.nr < 128);
452      assert(src2.type == GEN_TYPE_F);
453      gen8_insn->bits3.da3src.src2_swizzle = NO_SWIZZLE;
454      gen8_insn->bits3.da3src.src2_subreg_nr = src2.subnr / 4;
455      gen8_insn->bits3.da3src.src2_rep_ctrl = src2.vstride == GEN_VERTICAL_STRIDE_0;
456      gen8_insn->bits3.da3src.src2_reg_nr = src2.nr;
457      gen8_insn->bits1.da3src.src2_abs = src2.absolute;
458      gen8_insn->bits1.da3src.src2_negate = src2.negation;
459
460      // Emit second half of the instruction
461      if (this->curr.execWidth == 16) {
462       GenNativeInstruction q1Insn = *insn;
463       insn = this->next(opcode);
464       *insn = q1Insn;
465       gen8_insn = &insn->gen8_insn;
466       gen8_insn->header.quarter_control = GEN_COMPRESSION_Q2;
467       gen8_insn->bits1.da3src.dest_reg_nr++;
468       if (gen8_insn->bits2.da3src.src0_rep_ctrl == 0)
469         gen8_insn->bits2.da3src.src0_reg_nr++;
470       if (gen8_insn->bits2.da3src.src1_rep_ctrl == 0)
471         gen8_insn->bits3.da3src.src1_reg_nr++;
472       if (gen8_insn->bits3.da3src.src2_rep_ctrl == 0)
473         gen8_insn->bits3.da3src.src2_reg_nr++;
474      }
475   }
476 } /* End of the name space. */