BDW: Pass Jip and Uip when patchJMPI.
[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_CACHE;
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_CACHE;
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_CACHE;
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       Gen8NativeInstruction *gen8_insn = &insn.gen8_insn;
278       this->setSrc0(&insn, GenRegister::immud(0));
279       gen8_insn->bits2.gen8_branch.uip = uip*8;
280       gen8_insn->bits3.gen8_branch.jip = jip*8;
281       return;
282     }
283     else if (insn.header.opcode == GEN_OPCODE_JMPI) {
284       //jumpDistance'unit is Qword, and the HSW's offset of jmpi is in byte, so multi 8
285       jip = (jip - 2);
286     }
287
288     this->setSrc1(&insn, GenRegister::immd(jip*8));
289   }
290
291   void Gen8Encoder::setDst(GenNativeInstruction *insn, GenRegister dest) {
292     Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
293     if (dest.file != GEN_ARCHITECTURE_REGISTER_FILE)
294       assert(dest.nr < 128);
295
296     gen8_insn->bits1.da1.dest_reg_file = dest.file;
297     gen8_insn->bits1.da1.dest_reg_type = dest.type;
298     gen8_insn->bits1.da1.dest_address_mode = dest.address_mode;
299     gen8_insn->bits1.da1.dest_reg_nr = dest.nr;
300     gen8_insn->bits1.da1.dest_subreg_nr = dest.subnr;
301     if (dest.hstride == GEN_HORIZONTAL_STRIDE_0) {
302       if (dest.type == GEN_TYPE_UB || dest.type == GEN_TYPE_B)
303         dest.hstride = GEN_HORIZONTAL_STRIDE_4;
304       else if (dest.type == GEN_TYPE_UW || dest.type == GEN_TYPE_W)
305         dest.hstride = GEN_HORIZONTAL_STRIDE_2;
306       else
307         dest.hstride = GEN_HORIZONTAL_STRIDE_1;
308     }
309     gen8_insn->bits1.da1.dest_horiz_stride = dest.hstride;
310   }
311
312   void Gen8Encoder::setSrc0(GenNativeInstruction *insn, GenRegister reg) {
313     Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
314     if (reg.file != GEN_ARCHITECTURE_REGISTER_FILE)
315       assert(reg.nr < 128);
316
317     if (reg.address_mode == GEN_ADDRESS_DIRECT) {
318       gen8_insn->bits1.da1.src0_reg_file = reg.file;
319       gen8_insn->bits1.da1.src0_reg_type = reg.type;
320       gen8_insn->bits2.da1.src0_abs = reg.absolute;
321       gen8_insn->bits2.da1.src0_negate = reg.negation;
322       gen8_insn->bits2.da1.src0_address_mode = reg.address_mode;
323       if (reg.file == GEN_IMMEDIATE_VALUE) {
324         gen8_insn->bits3.ud = reg.value.ud;
325
326         /* Required to set some fields in src1 as well: */
327         gen8_insn->bits2.da1.src1_reg_file = 0; /* arf */
328         gen8_insn->bits2.da1.src1_reg_type = reg.type;
329       }
330       else {
331         if (gen8_insn->header.access_mode == GEN_ALIGN_1) {
332           gen8_insn->bits2.da1.src0_subreg_nr = reg.subnr;
333           gen8_insn->bits2.da1.src0_reg_nr = reg.nr;
334         } else {
335           gen8_insn->bits2.da16.src0_subreg_nr = reg.subnr / 16;
336           gen8_insn->bits2.da16.src0_reg_nr = reg.nr;
337         }
338
339         if (reg.width == GEN_WIDTH_1 &&
340             gen8_insn->header.execution_size == GEN_WIDTH_1) {
341           gen8_insn->bits2.da1.src0_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
342           gen8_insn->bits2.da1.src0_width = GEN_WIDTH_1;
343           gen8_insn->bits2.da1.src0_vert_stride = GEN_VERTICAL_STRIDE_0;
344         }
345         else {
346           gen8_insn->bits2.da1.src0_horiz_stride = reg.hstride;
347           gen8_insn->bits2.da1.src0_width = reg.width;
348           gen8_insn->bits2.da1.src0_vert_stride = reg.vstride;
349         }
350       }
351     } else {
352       gen8_insn->bits1.ia1.src0_reg_file = GEN_GENERAL_REGISTER_FILE;
353       gen8_insn->bits1.ia1.src0_reg_type = reg.type;
354       gen8_insn->bits2.ia1.src0_subreg_nr = 0;
355       gen8_insn->bits2.ia1.src0_indirect_offset = 0;
356       gen8_insn->bits2.ia1.src0_abs = 0;
357       gen8_insn->bits2.ia1.src0_negate = 0;
358       gen8_insn->bits2.ia1.src0_address_mode = reg.address_mode;
359       gen8_insn->bits2.ia1.src0_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
360       gen8_insn->bits2.ia1.src0_width = GEN_WIDTH_1;
361       gen8_insn->bits2.ia1.src0_vert_stride = GEN_VERTICAL_STRIDE_ONE_DIMENSIONAL;
362     }
363   }
364
365   void Gen8Encoder::setSrc1(GenNativeInstruction *insn, GenRegister reg) {
366     Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
367     assert(reg.nr < 128);
368     assert(reg.file != GEN_ARCHITECTURE_REGISTER_FILE || reg.nr == 0);
369
370     gen8_insn->bits2.da1.src1_reg_file = reg.file;
371     gen8_insn->bits2.da1.src1_reg_type = reg.type;
372     gen8_insn->bits3.da1.src1_abs = reg.absolute;
373     gen8_insn->bits3.da1.src1_negate = reg.negation;
374
375     assert(gen8_insn->bits1.da1.src0_reg_file != GEN_IMMEDIATE_VALUE);
376
377     if (reg.file == GEN_IMMEDIATE_VALUE)
378       gen8_insn->bits3.ud = reg.value.ud;
379     else {
380       assert (reg.address_mode == GEN_ADDRESS_DIRECT);
381       if (gen8_insn->header.access_mode == GEN_ALIGN_1) {
382         gen8_insn->bits3.da1.src1_subreg_nr = reg.subnr;
383         gen8_insn->bits3.da1.src1_reg_nr = reg.nr;
384       } else {
385         gen8_insn->bits3.da16.src1_subreg_nr = reg.subnr / 16;
386         gen8_insn->bits3.da16.src1_reg_nr = reg.nr;
387       }
388
389       if (reg.width == GEN_WIDTH_1 &&
390           gen8_insn->header.execution_size == GEN_WIDTH_1) {
391         gen8_insn->bits3.da1.src1_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
392         gen8_insn->bits3.da1.src1_width = GEN_WIDTH_1;
393         gen8_insn->bits3.da1.src1_vert_stride = GEN_VERTICAL_STRIDE_0;
394       } else {
395         gen8_insn->bits3.da1.src1_horiz_stride = reg.hstride;
396         gen8_insn->bits3.da1.src1_width = reg.width;
397         gen8_insn->bits3.da1.src1_vert_stride = reg.vstride;
398       }
399     }
400   }
401
402 #define NO_SWIZZLE ((0<<0) | (1<<2) | (2<<4) | (3<<6))
403
404   void Gen8Encoder::alu3(uint32_t opcode,
405                               GenRegister dest,
406                               GenRegister src0,
407                               GenRegister src1,
408                               GenRegister src2)
409   {
410      GenNativeInstruction *insn = this->next(opcode);
411      Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
412
413      assert(dest.file == GEN_GENERAL_REGISTER_FILE);
414      assert(dest.nr < 128);
415      assert(dest.address_mode == GEN_ADDRESS_DIRECT);
416      assert(dest.type = GEN_TYPE_F);
417      //gen8_insn->bits1.da3src.dest_reg_file = 0;
418      gen8_insn->bits1.da3src.dest_reg_nr = dest.nr;
419      gen8_insn->bits1.da3src.dest_subreg_nr = dest.subnr / 16;
420      gen8_insn->bits1.da3src.dest_writemask = 0xf;
421      this->setHeader(insn);
422      gen8_insn->header.access_mode = GEN_ALIGN_16;
423      gen8_insn->header.execution_size = GEN_WIDTH_8;
424
425      assert(src0.file == GEN_GENERAL_REGISTER_FILE);
426      assert(src0.address_mode == GEN_ADDRESS_DIRECT);
427      assert(src0.nr < 128);
428      assert(src0.type == GEN_TYPE_F);
429      gen8_insn->bits2.da3src.src0_swizzle = NO_SWIZZLE;
430      gen8_insn->bits2.da3src.src0_subreg_nr = src0.subnr / 4 ;
431      gen8_insn->bits2.da3src.src0_reg_nr = src0.nr;
432      gen8_insn->bits1.da3src.src0_abs = src0.absolute;
433      gen8_insn->bits1.da3src.src0_negate = src0.negation;
434      gen8_insn->bits2.da3src.src0_rep_ctrl = src0.vstride == GEN_VERTICAL_STRIDE_0;
435
436      assert(src1.file == GEN_GENERAL_REGISTER_FILE);
437      assert(src1.address_mode == GEN_ADDRESS_DIRECT);
438      assert(src1.nr < 128);
439      assert(src1.type == GEN_TYPE_F);
440      gen8_insn->bits2.da3src.src1_swizzle = NO_SWIZZLE;
441      gen8_insn->bits2.da3src.src1_subreg_nr_low = (src1.subnr / 4) & 0x3;
442      gen8_insn->bits3.da3src.src1_subreg_nr_high = (src1.subnr / 4) >> 2;
443      gen8_insn->bits2.da3src.src1_rep_ctrl = src1.vstride == GEN_VERTICAL_STRIDE_0;
444      gen8_insn->bits3.da3src.src1_reg_nr = src1.nr;
445      gen8_insn->bits1.da3src.src1_abs = src1.absolute;
446      gen8_insn->bits1.da3src.src1_negate = src1.negation;
447
448      assert(src2.file == GEN_GENERAL_REGISTER_FILE);
449      assert(src2.address_mode == GEN_ADDRESS_DIRECT);
450      assert(src2.nr < 128);
451      assert(src2.type == GEN_TYPE_F);
452      gen8_insn->bits3.da3src.src2_swizzle = NO_SWIZZLE;
453      gen8_insn->bits3.da3src.src2_subreg_nr = src2.subnr / 4;
454      gen8_insn->bits3.da3src.src2_rep_ctrl = src2.vstride == GEN_VERTICAL_STRIDE_0;
455      gen8_insn->bits3.da3src.src2_reg_nr = src2.nr;
456      gen8_insn->bits1.da3src.src2_abs = src2.absolute;
457      gen8_insn->bits1.da3src.src2_negate = src2.negation;
458
459      // Emit second half of the instruction
460      if (this->curr.execWidth == 16) {
461       GenNativeInstruction q1Insn = *insn;
462       insn = this->next(opcode);
463       *insn = q1Insn;
464       gen8_insn = &insn->gen8_insn;
465       gen8_insn->header.quarter_control = GEN_COMPRESSION_Q2;
466       gen8_insn->bits1.da3src.dest_reg_nr++;
467       if (gen8_insn->bits2.da3src.src0_rep_ctrl == 0)
468         gen8_insn->bits2.da3src.src0_reg_nr++;
469       if (gen8_insn->bits2.da3src.src1_rep_ctrl == 0)
470         gen8_insn->bits3.da3src.src1_reg_nr++;
471       if (gen8_insn->bits3.da3src.src2_rep_ctrl == 0)
472         gen8_insn->bits3.da3src.src2_reg_nr++;
473      }
474   }
475 } /* End of the name space. */