BDW: Fix load/store half error.
[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::F16TO32(GenRegister dest, GenRegister src0) {
100     MOV(GenRegister::retype(dest, GEN_TYPE_F), GenRegister::retype(src0, GEN_TYPE_HF));
101   }
102
103   void Gen8Encoder::F32TO16(GenRegister dest, GenRegister src0) {
104     MOV(GenRegister::retype(dest, GEN_TYPE_HF), GenRegister::retype(src0, GEN_TYPE_F));
105   }
106
107   void Gen8Encoder::ATOMIC(GenRegister dst, uint32_t function, GenRegister src, uint32_t bti, uint32_t srcNum) {
108     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
109     Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
110     uint32_t msg_length = 0;
111     uint32_t response_length = 0;
112
113     if (this->curr.execWidth == 8) {
114       msg_length = srcNum;
115       response_length = 1;
116     } else if (this->curr.execWidth == 16) {
117       msg_length = 2 * srcNum;
118       response_length = 2;
119     } else
120       NOT_IMPLEMENTED;
121
122     this->setHeader(insn);
123     this->setDst(insn, GenRegister::uw16grf(dst.nr, 0));
124     this->setSrc0(insn, GenRegister::ud8grf(src.nr, 0));
125     this->setSrc1(insn, GenRegister::immud(0));
126
127     const GenMessageTarget sfid = GEN_SFID_DATAPORT1_DATA;
128     setMessageDescriptor(insn, sfid, msg_length, response_length);
129     gen8_insn->bits3.gen7_atomic_op.msg_type = GEN75_P1_UNTYPED_ATOMIC_OP;
130     gen8_insn->bits3.gen7_atomic_op.bti = bti;
131     gen8_insn->bits3.gen7_atomic_op.return_data = 1;
132     gen8_insn->bits3.gen7_atomic_op.aop_type = function;
133
134     if (this->curr.execWidth == 8)
135       gen8_insn->bits3.gen7_atomic_op.simd_mode = GEN_ATOMIC_SIMD8;
136     else if (this->curr.execWidth == 16)
137       gen8_insn->bits3.gen7_atomic_op.simd_mode = GEN_ATOMIC_SIMD16;
138     else
139       NOT_SUPPORTED;
140   }
141
142   void Gen8Encoder::UNTYPED_READ(GenRegister dst, GenRegister src, uint32_t bti, uint32_t elemNum) {
143     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
144     assert(elemNum >= 1 || elemNum <= 4);
145     uint32_t msg_length = 0;
146     uint32_t response_length = 0;
147     if (this->curr.execWidth == 8) {
148       msg_length = 1;
149       response_length = elemNum;
150     } else if (this->curr.execWidth == 16) {
151       msg_length = 2;
152       response_length = 2 * elemNum;
153     } else
154       NOT_IMPLEMENTED;
155
156     this->setHeader(insn);
157     this->setDst(insn,  GenRegister::uw16grf(dst.nr, 0));
158     this->setSrc0(insn, GenRegister::ud8grf(src.nr, 0));
159     this->setSrc1(insn, GenRegister::immud(0));
160     setDPUntypedRW(insn,
161                    bti,
162                    untypedRWMask[elemNum],
163                    GEN75_P1_UNTYPED_READ,
164                    msg_length,
165                    response_length);
166   }
167
168   void Gen8Encoder::UNTYPED_WRITE(GenRegister msg, uint32_t bti, uint32_t elemNum) {
169     GenNativeInstruction *insn = this->next(GEN_OPCODE_SEND);
170     assert(elemNum >= 1 || elemNum <= 4);
171     uint32_t msg_length = 0;
172     uint32_t response_length = 0;
173     this->setHeader(insn);
174     if (this->curr.execWidth == 8) {
175       this->setDst(insn, GenRegister::retype(GenRegister::null(), GEN_TYPE_UD));
176       msg_length = 1 + elemNum;
177     } else if (this->curr.execWidth == 16) {
178       this->setDst(insn, GenRegister::retype(GenRegister::null(), GEN_TYPE_UW));
179       msg_length = 2 * (1 + elemNum);
180     }
181     else
182       NOT_IMPLEMENTED;
183     this->setSrc0(insn, GenRegister::ud8grf(msg.nr, 0));
184     this->setSrc1(insn, GenRegister::immud(0));
185     setDPUntypedRW(insn,
186                    bti,
187                    untypedRWMask[elemNum],
188                    GEN75_P1_UNTYPED_SURFACE_WRITE,
189                    msg_length,
190                    response_length);
191   }
192
193   void Gen8Encoder::LOAD_DF_IMM(GenRegister dest, GenRegister tmp, double value) {
194     union { double d; unsigned u[2]; } u;
195     u.d = value;
196     GenRegister r = GenRegister::retype(tmp, GEN_TYPE_UD);
197     push();
198     curr.predicate = GEN_PREDICATE_NONE;
199     curr.noMask = 1;
200     curr.execWidth = 1;
201     MOV(r, GenRegister::immud(u.u[0]));
202     MOV(GenRegister::suboffset(r, 1), GenRegister::immud(u.u[1]));
203     pop();
204     r.type = GEN_TYPE_DF;
205     r.vstride = GEN_VERTICAL_STRIDE_0;
206     r.width = GEN_WIDTH_1;
207     r.hstride = GEN_HORIZONTAL_STRIDE_0;
208     push();
209     uint32_t width = curr.execWidth;
210     curr.execWidth = 8;
211     curr.predicate = GEN_PREDICATE_NONE;
212     curr.noMask = 1;
213     curr.quarterControl = GEN_COMPRESSION_Q1;
214     MOV(dest, r);
215     if (width == 16) {
216       curr.quarterControl = GEN_COMPRESSION_Q2;
217       MOV(GenRegister::offset(dest, 2), r);
218     }
219     pop();
220   }
221
222   void Gen8Encoder::MOV_DF(GenRegister dest, GenRegister src0, GenRegister r) {
223     GBE_ASSERT((src0.type == GEN_TYPE_F && dest.isdf()) || (src0.isdf() && dest.type == GEN_TYPE_F));
224     int w = curr.execWidth;
225     GenRegister r0;
226     r0 = GenRegister::h2(r);
227     push();
228     curr.execWidth = 4;
229     curr.predicate = GEN_PREDICATE_NONE;
230     curr.noMask = 1;
231     MOV(r0, src0);
232     MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 4));
233     curr.noMask = 0;
234     curr.quarterControl = 0;
235     curr.nibControl = 0;
236     MOV(dest, r0);
237     curr.nibControl = 1;
238     MOV(GenRegister::suboffset(dest, 4), GenRegister::suboffset(r0, 4));
239     pop();
240     if (w == 16) {
241       push();
242       curr.execWidth = 4;
243       curr.predicate = GEN_PREDICATE_NONE;
244       curr.noMask = 1;
245       MOV(r0, GenRegister::suboffset(src0, 8));
246       MOV(GenRegister::suboffset(r0, 4), GenRegister::suboffset(src0, 12));
247       curr.noMask = 0;
248       curr.quarterControl = 1;
249       curr.nibControl = 0;
250       MOV(GenRegister::suboffset(dest, 8), r0);
251       curr.nibControl = 1;
252       MOV(GenRegister::suboffset(dest, 12), GenRegister::suboffset(r0, 4));
253       pop();
254     }
255   }
256
257   void Gen8Encoder::JMPI(GenRegister src, bool longjmp) {
258     alu2(this, GEN_OPCODE_JMPI, GenRegister::ip(), GenRegister::ip(), src);
259   }
260
261   void Gen8Encoder::patchJMPI(uint32_t insnID, int32_t jip, int32_t uip) {
262     GenNativeInstruction &insn = *(GenNativeInstruction *)&this->store[insnID];
263     GBE_ASSERT(insnID < this->store.size());
264     GBE_ASSERT(insn.header.opcode == GEN_OPCODE_JMPI ||
265                insn.header.opcode == GEN_OPCODE_BRD  ||
266                insn.header.opcode == GEN_OPCODE_ENDIF ||
267                insn.header.opcode == GEN_OPCODE_IF ||
268                insn.header.opcode == GEN_OPCODE_BRC ||
269                insn.header.opcode == GEN_OPCODE_WHILE ||
270                insn.header.opcode == GEN_OPCODE_ELSE);
271
272     if( insn.header.opcode == GEN_OPCODE_WHILE ) {
273       // if this WHILE instruction jump back to an ELSE instruction,
274       // need add distance to go to the next instruction.
275       GenNativeInstruction & insn_else = *(GenNativeInstruction *)&this->store[insnID+jip];
276       if(insn_else.header.opcode == GEN_OPCODE_ELSE) {
277         jip += 2;
278       }
279     }
280
281     if(insn.header.opcode == GEN_OPCODE_ELSE)
282       uip = jip;
283
284     if (insn.header.opcode == GEN_OPCODE_IF ||
285         insn.header.opcode == GEN_OPCODE_ELSE) {
286       Gen8NativeInstruction *gen8_insn = &insn.gen8_insn;
287       this->setSrc0(&insn, GenRegister::immud(0));
288       gen8_insn->bits2.gen8_branch.uip = uip*8;
289       gen8_insn->bits3.gen8_branch.jip = jip*8;
290       return;
291     }
292     else if (insn.header.opcode == GEN_OPCODE_JMPI) {
293       //jumpDistance'unit is Qword, and the HSW's offset of jmpi is in byte, so multi 8
294       jip = (jip - 2);
295     }
296
297     this->setSrc1(&insn, GenRegister::immd(jip*8));
298   }
299
300   void Gen8Encoder::setDst(GenNativeInstruction *insn, GenRegister dest) {
301     Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
302     if (dest.file != GEN_ARCHITECTURE_REGISTER_FILE)
303       assert(dest.nr < 128);
304
305     gen8_insn->bits1.da1.dest_reg_file = dest.file;
306     gen8_insn->bits1.da1.dest_reg_type = dest.type;
307     gen8_insn->bits1.da1.dest_address_mode = dest.address_mode;
308     gen8_insn->bits1.da1.dest_reg_nr = dest.nr;
309     gen8_insn->bits1.da1.dest_subreg_nr = dest.subnr;
310     if (dest.hstride == GEN_HORIZONTAL_STRIDE_0) {
311       if (dest.type == GEN_TYPE_UB || dest.type == GEN_TYPE_B)
312         dest.hstride = GEN_HORIZONTAL_STRIDE_4;
313       else if (dest.type == GEN_TYPE_UW || dest.type == GEN_TYPE_W)
314         dest.hstride = GEN_HORIZONTAL_STRIDE_2;
315       else
316         dest.hstride = GEN_HORIZONTAL_STRIDE_1;
317     }
318     gen8_insn->bits1.da1.dest_horiz_stride = dest.hstride;
319   }
320
321   void Gen8Encoder::setSrc0(GenNativeInstruction *insn, GenRegister reg) {
322     Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
323     if (reg.file != GEN_ARCHITECTURE_REGISTER_FILE)
324       assert(reg.nr < 128);
325
326     if (reg.address_mode == GEN_ADDRESS_DIRECT) {
327       gen8_insn->bits1.da1.src0_reg_file = reg.file;
328       gen8_insn->bits1.da1.src0_reg_type = reg.type;
329       gen8_insn->bits2.da1.src0_abs = reg.absolute;
330       gen8_insn->bits2.da1.src0_negate = reg.negation;
331       gen8_insn->bits2.da1.src0_address_mode = reg.address_mode;
332       if (reg.file == GEN_IMMEDIATE_VALUE) {
333         gen8_insn->bits3.ud = reg.value.ud;
334
335         /* Required to set some fields in src1 as well: */
336         gen8_insn->bits2.da1.src1_reg_file = 0; /* arf */
337         gen8_insn->bits2.da1.src1_reg_type = reg.type;
338       }
339       else {
340         if (gen8_insn->header.access_mode == GEN_ALIGN_1) {
341           gen8_insn->bits2.da1.src0_subreg_nr = reg.subnr;
342           gen8_insn->bits2.da1.src0_reg_nr = reg.nr;
343         } else {
344           gen8_insn->bits2.da16.src0_subreg_nr = reg.subnr / 16;
345           gen8_insn->bits2.da16.src0_reg_nr = reg.nr;
346         }
347
348         if (reg.width == GEN_WIDTH_1 &&
349             gen8_insn->header.execution_size == GEN_WIDTH_1) {
350           gen8_insn->bits2.da1.src0_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
351           gen8_insn->bits2.da1.src0_width = GEN_WIDTH_1;
352           gen8_insn->bits2.da1.src0_vert_stride = GEN_VERTICAL_STRIDE_0;
353         }
354         else {
355           gen8_insn->bits2.da1.src0_horiz_stride = reg.hstride;
356           gen8_insn->bits2.da1.src0_width = reg.width;
357           gen8_insn->bits2.da1.src0_vert_stride = reg.vstride;
358         }
359       }
360     } else {
361       gen8_insn->bits1.ia1.src0_reg_file = GEN_GENERAL_REGISTER_FILE;
362       gen8_insn->bits1.ia1.src0_reg_type = reg.type;
363       gen8_insn->bits2.ia1.src0_subreg_nr = 0;
364       gen8_insn->bits2.ia1.src0_indirect_offset = 0;
365       gen8_insn->bits2.ia1.src0_abs = 0;
366       gen8_insn->bits2.ia1.src0_negate = 0;
367       gen8_insn->bits2.ia1.src0_address_mode = reg.address_mode;
368       gen8_insn->bits2.ia1.src0_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
369       gen8_insn->bits2.ia1.src0_width = GEN_WIDTH_1;
370       gen8_insn->bits2.ia1.src0_vert_stride = GEN_VERTICAL_STRIDE_ONE_DIMENSIONAL;
371     }
372   }
373
374   void Gen8Encoder::setSrc1(GenNativeInstruction *insn, GenRegister reg) {
375     Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
376     assert(reg.nr < 128);
377     assert(reg.file != GEN_ARCHITECTURE_REGISTER_FILE || reg.nr == 0);
378
379     gen8_insn->bits2.da1.src1_reg_file = reg.file;
380     gen8_insn->bits2.da1.src1_reg_type = reg.type;
381     gen8_insn->bits3.da1.src1_abs = reg.absolute;
382     gen8_insn->bits3.da1.src1_negate = reg.negation;
383
384     assert(gen8_insn->bits1.da1.src0_reg_file != GEN_IMMEDIATE_VALUE);
385
386     if (reg.file == GEN_IMMEDIATE_VALUE)
387       gen8_insn->bits3.ud = reg.value.ud;
388     else {
389       assert (reg.address_mode == GEN_ADDRESS_DIRECT);
390       if (gen8_insn->header.access_mode == GEN_ALIGN_1) {
391         gen8_insn->bits3.da1.src1_subreg_nr = reg.subnr;
392         gen8_insn->bits3.da1.src1_reg_nr = reg.nr;
393       } else {
394         gen8_insn->bits3.da16.src1_subreg_nr = reg.subnr / 16;
395         gen8_insn->bits3.da16.src1_reg_nr = reg.nr;
396       }
397
398       if (reg.width == GEN_WIDTH_1 &&
399           gen8_insn->header.execution_size == GEN_WIDTH_1) {
400         gen8_insn->bits3.da1.src1_horiz_stride = GEN_HORIZONTAL_STRIDE_0;
401         gen8_insn->bits3.da1.src1_width = GEN_WIDTH_1;
402         gen8_insn->bits3.da1.src1_vert_stride = GEN_VERTICAL_STRIDE_0;
403       } else {
404         gen8_insn->bits3.da1.src1_horiz_stride = reg.hstride;
405         gen8_insn->bits3.da1.src1_width = reg.width;
406         gen8_insn->bits3.da1.src1_vert_stride = reg.vstride;
407       }
408     }
409   }
410
411 #define NO_SWIZZLE ((0<<0) | (1<<2) | (2<<4) | (3<<6))
412
413   void Gen8Encoder::alu3(uint32_t opcode,
414                               GenRegister dest,
415                               GenRegister src0,
416                               GenRegister src1,
417                               GenRegister src2)
418   {
419      GenNativeInstruction *insn = this->next(opcode);
420      Gen8NativeInstruction *gen8_insn = &insn->gen8_insn;
421
422      assert(dest.file == GEN_GENERAL_REGISTER_FILE);
423      assert(dest.nr < 128);
424      assert(dest.address_mode == GEN_ADDRESS_DIRECT);
425      assert(dest.type = GEN_TYPE_F);
426      //gen8_insn->bits1.da3src.dest_reg_file = 0;
427      gen8_insn->bits1.da3src.dest_reg_nr = dest.nr;
428      gen8_insn->bits1.da3src.dest_subreg_nr = dest.subnr / 16;
429      gen8_insn->bits1.da3src.dest_writemask = 0xf;
430      this->setHeader(insn);
431      gen8_insn->header.access_mode = GEN_ALIGN_16;
432      gen8_insn->header.execution_size = GEN_WIDTH_8;
433
434      assert(src0.file == GEN_GENERAL_REGISTER_FILE);
435      assert(src0.address_mode == GEN_ADDRESS_DIRECT);
436      assert(src0.nr < 128);
437      assert(src0.type == GEN_TYPE_F);
438      gen8_insn->bits2.da3src.src0_swizzle = NO_SWIZZLE;
439      gen8_insn->bits2.da3src.src0_subreg_nr = src0.subnr / 4 ;
440      gen8_insn->bits2.da3src.src0_reg_nr = src0.nr;
441      gen8_insn->bits1.da3src.src0_abs = src0.absolute;
442      gen8_insn->bits1.da3src.src0_negate = src0.negation;
443      gen8_insn->bits2.da3src.src0_rep_ctrl = src0.vstride == GEN_VERTICAL_STRIDE_0;
444
445      assert(src1.file == GEN_GENERAL_REGISTER_FILE);
446      assert(src1.address_mode == GEN_ADDRESS_DIRECT);
447      assert(src1.nr < 128);
448      assert(src1.type == GEN_TYPE_F);
449      gen8_insn->bits2.da3src.src1_swizzle = NO_SWIZZLE;
450      gen8_insn->bits2.da3src.src1_subreg_nr_low = (src1.subnr / 4) & 0x3;
451      gen8_insn->bits3.da3src.src1_subreg_nr_high = (src1.subnr / 4) >> 2;
452      gen8_insn->bits2.da3src.src1_rep_ctrl = src1.vstride == GEN_VERTICAL_STRIDE_0;
453      gen8_insn->bits3.da3src.src1_reg_nr = src1.nr;
454      gen8_insn->bits1.da3src.src1_abs = src1.absolute;
455      gen8_insn->bits1.da3src.src1_negate = src1.negation;
456
457      assert(src2.file == GEN_GENERAL_REGISTER_FILE);
458      assert(src2.address_mode == GEN_ADDRESS_DIRECT);
459      assert(src2.nr < 128);
460      assert(src2.type == GEN_TYPE_F);
461      gen8_insn->bits3.da3src.src2_swizzle = NO_SWIZZLE;
462      gen8_insn->bits3.da3src.src2_subreg_nr = src2.subnr / 4;
463      gen8_insn->bits3.da3src.src2_rep_ctrl = src2.vstride == GEN_VERTICAL_STRIDE_0;
464      gen8_insn->bits3.da3src.src2_reg_nr = src2.nr;
465      gen8_insn->bits1.da3src.src2_abs = src2.absolute;
466      gen8_insn->bits1.da3src.src2_negate = src2.negation;
467
468      // Emit second half of the instruction
469      if (this->curr.execWidth == 16) {
470       GenNativeInstruction q1Insn = *insn;
471       insn = this->next(opcode);
472       *insn = q1Insn;
473       gen8_insn = &insn->gen8_insn;
474       gen8_insn->header.quarter_control = GEN_COMPRESSION_Q2;
475       gen8_insn->bits1.da3src.dest_reg_nr++;
476       if (gen8_insn->bits2.da3src.src0_rep_ctrl == 0)
477         gen8_insn->bits2.da3src.src0_reg_nr++;
478       if (gen8_insn->bits2.da3src.src1_rep_ctrl == 0)
479         gen8_insn->bits3.da3src.src1_reg_nr++;
480       if (gen8_insn->bits3.da3src.src2_rep_ctrl == 0)
481         gen8_insn->bits3.da3src.src2_reg_nr++;
482      }
483   }
484 } /* End of the name space. */