OSDN Git Service

radeonsi: initial WIP SI code
[android-x86/external-mesa.git] / src / gallium / drivers / radeon / AMDILIOExpansion.cpp
1 //===----------- AMDILIOExpansion.cpp - IO Expansion Pass -----------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //==-----------------------------------------------------------------------===//
9 // The AMDIL IO Expansion class expands pseudo IO instructions into a sequence
10 // of instructions that produces the correct results. These instructions are
11 // not expanded earlier in the pass because any pass before this can assume to
12 // be able to generate a load/store instruction. So this pass can only have
13 // passes that execute after it if no load/store instructions can be generated.
14 //===----------------------------------------------------------------------===//
15 #include "AMDILIOExpansion.h"
16 #include "AMDIL.h"
17 #include "AMDILDevices.h"
18 #include "AMDILGlobalManager.h"
19 #include "AMDILKernelManager.h"
20 #include "AMDILMachineFunctionInfo.h"
21 #include "AMDILTargetMachine.h"
22 #include "AMDILUtilityFunctions.h"
23 #include "llvm/CodeGen/MachineConstantPool.h"
24 #include "llvm/CodeGen/MachineInstr.h"
25 #include "llvm/CodeGen/MachineInstrBuilder.h"
26 #include "llvm/CodeGen/MachineMemOperand.h"
27 #include "llvm/DerivedTypes.h"
28 #include "llvm/Support/DebugLoc.h"
29 #include "llvm/Target/TargetMachine.h"
30 #include "llvm/Value.h"
31
32 using namespace llvm;
33
34 char AMDILIOExpansion::ID = 0;
35 namespace llvm {
36   FunctionPass*
37     createAMDILIOExpansion(TargetMachine &TM AMDIL_OPT_LEVEL_DECL)
38     {
39       return TM.getSubtarget<AMDILSubtarget>()
40         .device()->getIOExpansion(TM AMDIL_OPT_LEVEL_VAR);
41     }
42 }
43
44 AMDILIOExpansion::AMDILIOExpansion(TargetMachine &tm
45      AMDIL_OPT_LEVEL_DECL) :
46   MachineFunctionPass(ID), TM(tm)
47 {
48   mSTM = &tm.getSubtarget<AMDILSubtarget>();
49   mDebug = DEBUGME;
50   mTII = tm.getInstrInfo();
51   mKM = NULL;
52 }
53
54 AMDILIOExpansion::~AMDILIOExpansion()
55 {
56 }
57   bool
58 AMDILIOExpansion::runOnMachineFunction(MachineFunction &MF)
59 {
60   mKM = const_cast<AMDILKernelManager*>(mSTM->getKernelManager());
61   mMFI = MF.getInfo<AMDILMachineFunctionInfo>();
62   for (MachineFunction::iterator MFI = MF.begin(), MFE = MF.end();
63       MFI != MFE; ++MFI) {
64     MachineBasicBlock *MBB = MFI;
65     for (MachineBasicBlock::iterator MBI = MBB->begin(), MBE = MBB->end();
66         MBI != MBE; ++MBI) {
67       MachineInstr *MI = MBI;
68       if (isIOInstruction(MI)) {
69         mBB = MBB;
70         saveInst = false;
71         expandIOInstruction(MI);
72         if (!saveInst) {
73           // erase returns the instruction after
74           // and we want the instruction before
75           MBI = MBB->erase(MI);
76           --MBI;
77         }
78       }
79     }
80   }
81   return false;
82 }
83 const char *AMDILIOExpansion::getPassName() const
84 {
85   return "AMDIL Generic IO Expansion Pass";
86 }
87   bool
88 AMDILIOExpansion::isIOInstruction(MachineInstr *MI)
89 {
90   if (!MI) {
91     return false;
92   }
93   switch(MI->getOpcode()) {
94     default:
95       return false;
96       ExpandCaseToAllTypes(AMDIL::CPOOLLOAD)
97         ExpandCaseToAllTypes(AMDIL::CPOOLSEXTLOAD)
98         ExpandCaseToAllTypes(AMDIL::CPOOLZEXTLOAD)
99         ExpandCaseToAllTypes(AMDIL::CPOOLAEXTLOAD)
100         ExpandCaseToAllTypes(AMDIL::CONSTANTLOAD)
101         ExpandCaseToAllTypes(AMDIL::CONSTANTSEXTLOAD)
102         ExpandCaseToAllTypes(AMDIL::CONSTANTZEXTLOAD)
103         ExpandCaseToAllTypes(AMDIL::CONSTANTAEXTLOAD)
104         ExpandCaseToAllTypes(AMDIL::PRIVATELOAD)
105         ExpandCaseToAllTypes(AMDIL::PRIVATESEXTLOAD)
106         ExpandCaseToAllTypes(AMDIL::PRIVATEZEXTLOAD)
107         ExpandCaseToAllTypes(AMDIL::PRIVATEAEXTLOAD)
108         ExpandCaseToAllTypes(AMDIL::PRIVATESTORE)
109         ExpandCaseToAllTruncTypes(AMDIL::PRIVATETRUNCSTORE)
110         ExpandCaseToAllTypes(AMDIL::REGIONSTORE)
111         ExpandCaseToAllTruncTypes(AMDIL::REGIONTRUNCSTORE)
112         ExpandCaseToAllTypes(AMDIL::REGIONLOAD)
113         ExpandCaseToAllTypes(AMDIL::REGIONSEXTLOAD)
114         ExpandCaseToAllTypes(AMDIL::REGIONZEXTLOAD)
115         ExpandCaseToAllTypes(AMDIL::REGIONAEXTLOAD)
116         ExpandCaseToAllTypes(AMDIL::LOCALSTORE)
117         ExpandCaseToAllTruncTypes(AMDIL::LOCALTRUNCSTORE)
118         ExpandCaseToAllTypes(AMDIL::LOCALLOAD)
119         ExpandCaseToAllTypes(AMDIL::LOCALSEXTLOAD)
120         ExpandCaseToAllTypes(AMDIL::LOCALZEXTLOAD)
121         ExpandCaseToAllTypes(AMDIL::LOCALAEXTLOAD)
122         ExpandCaseToAllTypes(AMDIL::GLOBALLOAD)
123         ExpandCaseToAllTypes(AMDIL::GLOBALSEXTLOAD)
124         ExpandCaseToAllTypes(AMDIL::GLOBALAEXTLOAD)
125         ExpandCaseToAllTypes(AMDIL::GLOBALZEXTLOAD)
126         ExpandCaseToAllTypes(AMDIL::GLOBALSTORE)
127         ExpandCaseToAllTruncTypes(AMDIL::GLOBALTRUNCSTORE)
128         return true;
129   };
130   return false;
131 }
132 void
133 AMDILIOExpansion::expandIOInstruction(MachineInstr *MI)
134 {
135   assert(isIOInstruction(MI) && "Must be an IO instruction to "
136       "be passed to this function!");
137   switch (MI->getOpcode()) {
138     default:
139       assert(0 && "Not an IO Instruction!");
140       ExpandCaseToAllTypes(AMDIL::GLOBALLOAD);
141       ExpandCaseToAllTypes(AMDIL::GLOBALSEXTLOAD);
142       ExpandCaseToAllTypes(AMDIL::GLOBALZEXTLOAD);
143       ExpandCaseToAllTypes(AMDIL::GLOBALAEXTLOAD);
144       expandGlobalLoad(MI);
145       break;
146       ExpandCaseToAllTypes(AMDIL::REGIONLOAD);
147       ExpandCaseToAllTypes(AMDIL::REGIONSEXTLOAD);
148       ExpandCaseToAllTypes(AMDIL::REGIONZEXTLOAD);
149       ExpandCaseToAllTypes(AMDIL::REGIONAEXTLOAD);
150       expandRegionLoad(MI);
151       break;
152       ExpandCaseToAllTypes(AMDIL::LOCALLOAD);
153       ExpandCaseToAllTypes(AMDIL::LOCALSEXTLOAD);
154       ExpandCaseToAllTypes(AMDIL::LOCALZEXTLOAD);
155       ExpandCaseToAllTypes(AMDIL::LOCALAEXTLOAD);
156       expandLocalLoad(MI);
157       break;
158       ExpandCaseToAllTypes(AMDIL::CONSTANTLOAD);
159       ExpandCaseToAllTypes(AMDIL::CONSTANTSEXTLOAD);
160       ExpandCaseToAllTypes(AMDIL::CONSTANTZEXTLOAD);
161       ExpandCaseToAllTypes(AMDIL::CONSTANTAEXTLOAD);
162       expandConstantLoad(MI);
163       break;
164       ExpandCaseToAllTypes(AMDIL::PRIVATELOAD);
165       ExpandCaseToAllTypes(AMDIL::PRIVATESEXTLOAD);
166       ExpandCaseToAllTypes(AMDIL::PRIVATEZEXTLOAD);
167       ExpandCaseToAllTypes(AMDIL::PRIVATEAEXTLOAD);
168       expandPrivateLoad(MI);
169       break;
170       ExpandCaseToAllTypes(AMDIL::CPOOLLOAD);
171       ExpandCaseToAllTypes(AMDIL::CPOOLSEXTLOAD);
172       ExpandCaseToAllTypes(AMDIL::CPOOLZEXTLOAD);
173       ExpandCaseToAllTypes(AMDIL::CPOOLAEXTLOAD);
174       expandConstantPoolLoad(MI);
175       break;
176       ExpandCaseToAllTruncTypes(AMDIL::GLOBALTRUNCSTORE)
177       ExpandCaseToAllTypes(AMDIL::GLOBALSTORE);
178       expandGlobalStore(MI);
179       break;
180       ExpandCaseToAllTruncTypes(AMDIL::PRIVATETRUNCSTORE);
181       ExpandCaseToAllTypes(AMDIL::PRIVATESTORE);
182       expandPrivateStore(MI);
183       break;
184       ExpandCaseToAllTruncTypes(AMDIL::REGIONTRUNCSTORE);
185       ExpandCaseToAllTypes(AMDIL::REGIONSTORE);
186       expandRegionStore(MI);
187       break;
188       ExpandCaseToAllTruncTypes(AMDIL::LOCALTRUNCSTORE);
189       ExpandCaseToAllTypes(AMDIL::LOCALSTORE);
190       expandLocalStore(MI);
191       break;
192   }
193 }
194   bool
195 AMDILIOExpansion::isAddrCalcInstr(MachineInstr *MI)
196 {
197   switch(MI->getOpcode()) {
198     ExpandCaseToAllTypes(AMDIL::PRIVATELOAD)
199       ExpandCaseToAllTypes(AMDIL::PRIVATESEXTLOAD)
200       ExpandCaseToAllTypes(AMDIL::PRIVATEZEXTLOAD)
201       ExpandCaseToAllTypes(AMDIL::PRIVATEAEXTLOAD)
202       {
203         // This section of code is a workaround for the problem of
204         // globally scoped constant address variables. The problems
205         // comes that although they are declared in the constant
206         // address space, all variables must be allocated in the
207         // private address space. So when there is a load from
208         // the global address, it automatically goes into the private
209         // address space. However, the data section is placed in the
210         // constant address space so we need to check to see if our
211         // load base address is a global variable or not. Only if it
212         // is not a global variable can we do the address calculation
213         // into the private memory ring.
214
215         MachineMemOperand& memOp = (**MI->memoperands_begin());
216         const Value *V = memOp.getValue();
217         if (V) {
218           const GlobalValue *GV = dyn_cast<GlobalVariable>(V);
219           return mSTM->device()->usesSoftware(AMDILDeviceInfo::PrivateMem)
220             && !(GV);
221         } else {
222           return false;
223         }
224       }
225     ExpandCaseToAllTypes(AMDIL::CPOOLLOAD);
226     ExpandCaseToAllTypes(AMDIL::CPOOLSEXTLOAD);
227     ExpandCaseToAllTypes(AMDIL::CPOOLZEXTLOAD);
228     ExpandCaseToAllTypes(AMDIL::CPOOLAEXTLOAD);
229     return MI->getOperand(1).isReg();
230     ExpandCaseToAllTruncTypes(AMDIL::PRIVATETRUNCSTORE);
231     ExpandCaseToAllTypes(AMDIL::PRIVATESTORE);
232     return mSTM->device()->usesSoftware(AMDILDeviceInfo::PrivateMem);
233     ExpandCaseToAllTruncTypes(AMDIL::LOCALTRUNCSTORE);
234     ExpandCaseToAllTypes(AMDIL::LOCALSTORE);
235     ExpandCaseToAllTypes(AMDIL::LOCALLOAD);
236     ExpandCaseToAllTypes(AMDIL::LOCALSEXTLOAD);
237     ExpandCaseToAllTypes(AMDIL::LOCALZEXTLOAD);
238     ExpandCaseToAllTypes(AMDIL::LOCALAEXTLOAD);
239     return mSTM->device()->usesSoftware(AMDILDeviceInfo::LocalMem);
240   };
241   return false;
242
243 }
244   bool
245 AMDILIOExpansion::isExtendLoad(MachineInstr *MI)
246 {
247   return isSExtLoadInst(TM.getInstrInfo(), MI) ||
248          isZExtLoadInst(TM.getInstrInfo(), MI) ||
249          isAExtLoadInst(TM.getInstrInfo(), MI)
250     || isSWSExtLoadInst(MI);
251 }
252
253   bool
254 AMDILIOExpansion::isHardwareRegion(MachineInstr *MI)
255 {
256   switch(MI->getOpcode()) {
257     default:
258       return false;
259       break;
260       ExpandCaseToAllTypes(AMDIL::REGIONLOAD)
261         ExpandCaseToAllTypes(AMDIL::REGIONSEXTLOAD)
262         ExpandCaseToAllTypes(AMDIL::REGIONZEXTLOAD)
263         ExpandCaseToAllTypes(AMDIL::REGIONAEXTLOAD)
264         ExpandCaseToAllTypes(AMDIL::REGIONSTORE)
265         ExpandCaseToAllTruncTypes(AMDIL::REGIONTRUNCSTORE)
266         return mSTM->device()->usesHardware(AMDILDeviceInfo::RegionMem);
267   };
268   return false;
269 }
270   bool
271 AMDILIOExpansion::isHardwareLocal(MachineInstr *MI)
272 {
273   switch(MI->getOpcode()) {
274     default:
275       return false;
276       break;
277       ExpandCaseToAllTypes(AMDIL::LOCALLOAD)
278         ExpandCaseToAllTypes(AMDIL::LOCALSEXTLOAD)
279         ExpandCaseToAllTypes(AMDIL::LOCALZEXTLOAD)
280         ExpandCaseToAllTypes(AMDIL::LOCALAEXTLOAD)
281         ExpandCaseToAllTypes(AMDIL::LOCALSTORE)
282         ExpandCaseToAllTruncTypes(AMDIL::LOCALTRUNCSTORE)
283         return mSTM->device()->usesHardware(AMDILDeviceInfo::LocalMem);
284   };
285   return false;
286 }
287   bool
288 AMDILIOExpansion::isPackedData(MachineInstr *MI)
289 {
290   switch(MI->getOpcode()) {
291     default:
292       if (isTruncStoreInst(TM.getInstrInfo(), MI)) {
293         switch (MI->getDesc().OpInfo[0].RegClass) {
294           default:
295             break;
296           case AMDIL::GPRV2I64RegClassID:
297           case AMDIL::GPRV2I32RegClassID:
298             switch (getMemorySize(MI)) {
299               case 2:
300               case 4:
301                 return true;
302               default:
303                 break;
304             }
305             break;
306           case AMDIL::GPRV4I32RegClassID:
307             switch (getMemorySize(MI)) {
308               case 4:
309               case 8:
310                 return true;
311               default:
312                 break;
313             }
314             break;
315         }
316       } 
317       break;
318       ExpandCaseToPackedTypes(AMDIL::CPOOLLOAD);
319       ExpandCaseToPackedTypes(AMDIL::CPOOLSEXTLOAD);
320       ExpandCaseToPackedTypes(AMDIL::CPOOLZEXTLOAD);
321       ExpandCaseToPackedTypes(AMDIL::CPOOLAEXTLOAD);
322       ExpandCaseToPackedTypes(AMDIL::GLOBALLOAD);
323       ExpandCaseToPackedTypes(AMDIL::GLOBALSEXTLOAD);
324       ExpandCaseToPackedTypes(AMDIL::GLOBALZEXTLOAD);
325       ExpandCaseToPackedTypes(AMDIL::GLOBALAEXTLOAD);
326       ExpandCaseToPackedTypes(AMDIL::LOCALLOAD);
327       ExpandCaseToPackedTypes(AMDIL::LOCALSEXTLOAD);
328       ExpandCaseToPackedTypes(AMDIL::LOCALZEXTLOAD);
329       ExpandCaseToPackedTypes(AMDIL::LOCALAEXTLOAD);
330       ExpandCaseToPackedTypes(AMDIL::REGIONLOAD);
331       ExpandCaseToPackedTypes(AMDIL::REGIONSEXTLOAD);
332       ExpandCaseToPackedTypes(AMDIL::REGIONZEXTLOAD);
333       ExpandCaseToPackedTypes(AMDIL::REGIONAEXTLOAD);
334       ExpandCaseToPackedTypes(AMDIL::PRIVATELOAD);
335       ExpandCaseToPackedTypes(AMDIL::PRIVATESEXTLOAD);
336       ExpandCaseToPackedTypes(AMDIL::PRIVATEZEXTLOAD);
337       ExpandCaseToPackedTypes(AMDIL::PRIVATEAEXTLOAD);
338       ExpandCaseToPackedTypes(AMDIL::CONSTANTLOAD);
339       ExpandCaseToPackedTypes(AMDIL::CONSTANTSEXTLOAD);
340       ExpandCaseToPackedTypes(AMDIL::CONSTANTAEXTLOAD);
341       ExpandCaseToPackedTypes(AMDIL::CONSTANTZEXTLOAD);
342       ExpandCaseToAllTruncTypes(AMDIL::GLOBALTRUNCSTORE)
343       ExpandCaseToAllTruncTypes(AMDIL::PRIVATETRUNCSTORE);
344       ExpandCaseToAllTruncTypes(AMDIL::LOCALTRUNCSTORE);
345       ExpandCaseToAllTruncTypes(AMDIL::REGIONTRUNCSTORE);
346       ExpandCaseToPackedTypes(AMDIL::GLOBALSTORE);
347       ExpandCaseToPackedTypes(AMDIL::PRIVATESTORE);
348       ExpandCaseToPackedTypes(AMDIL::LOCALSTORE);
349       ExpandCaseToPackedTypes(AMDIL::REGIONSTORE);
350       return true;
351   }
352   return false;
353 }
354
355   bool
356 AMDILIOExpansion::isStaticCPLoad(MachineInstr *MI)
357 {
358   switch(MI->getOpcode()) {
359     ExpandCaseToAllTypes(AMDIL::CPOOLLOAD);
360     ExpandCaseToAllTypes(AMDIL::CPOOLSEXTLOAD);
361     ExpandCaseToAllTypes(AMDIL::CPOOLZEXTLOAD);
362     ExpandCaseToAllTypes(AMDIL::CPOOLAEXTLOAD);
363     {
364       uint32_t x = 0;
365       uint32_t num = MI->getNumOperands();
366       for (x = 0; x < num; ++x) {
367         if (MI->getOperand(x).isCPI()) {
368           return true;
369         }
370       }
371     }
372     break;
373     default:
374     break;
375   }
376   return false;
377 }
378
379   bool
380 AMDILIOExpansion::isNbitType(Type *mType, uint32_t nBits, bool isScalar)
381 {
382   if (!mType) {
383     return false;
384   }
385   if (dyn_cast<PointerType>(mType)) {
386     PointerType *PT = dyn_cast<PointerType>(mType);
387     return isNbitType(PT->getElementType(), nBits);
388   } else if (dyn_cast<StructType>(mType)) {
389     return getTypeSize(mType) == nBits;
390   } else if (dyn_cast<VectorType>(mType)) {
391     VectorType *VT = dyn_cast<VectorType>(mType);
392     size_t size = VT->getScalarSizeInBits();
393     return (isScalar ? 
394         VT->getNumElements() * size == nBits : size == nBits);
395   } else if (dyn_cast<ArrayType>(mType)) {
396     ArrayType *AT = dyn_cast<ArrayType>(mType);
397     size_t size = AT->getScalarSizeInBits();
398     return (isScalar ? 
399         AT->getNumElements() * size == nBits : size == nBits);
400   } else if (mType->isSized()) {
401     return mType->getScalarSizeInBits() == nBits;
402   } else {
403     assert(0 && "Found a type that we don't know how to handle!");
404     return false;
405   }
406 }
407
408   bool
409 AMDILIOExpansion::isHardwareInst(MachineInstr *MI)
410 {
411   AMDILAS::InstrResEnc curRes;
412   curRes.u16all = MI->getAsmPrinterFlags();
413   return curRes.bits.HardwareInst;
414 }
415
416 REG_PACKED_TYPE
417 AMDILIOExpansion::getPackedID(MachineInstr *MI)
418 {
419   switch (MI->getOpcode()) {
420     default:
421       break;
422     case AMDIL::GLOBALTRUNCSTORE_v2i64i8:
423     case AMDIL::REGIONTRUNCSTORE_v2i64i8:
424     case AMDIL::LOCALTRUNCSTORE_v2i64i8:
425     case AMDIL::PRIVATETRUNCSTORE_v2i64i8:
426     case AMDIL::GLOBALTRUNCSTORE_v2i32i8:
427     case AMDIL::REGIONTRUNCSTORE_v2i32i8:
428     case AMDIL::LOCALTRUNCSTORE_v2i32i8:
429     case AMDIL::PRIVATETRUNCSTORE_v2i32i8:
430     case AMDIL::GLOBALTRUNCSTORE_v2i16i8:
431     case AMDIL::REGIONTRUNCSTORE_v2i16i8:
432     case AMDIL::LOCALTRUNCSTORE_v2i16i8:
433     case AMDIL::PRIVATETRUNCSTORE_v2i16i8:
434     case AMDIL::GLOBALSTORE_v2i8:
435     case AMDIL::LOCALSTORE_v2i8:
436     case AMDIL::REGIONSTORE_v2i8:
437     case AMDIL::PRIVATESTORE_v2i8:
438       return PACK_V2I8;
439     case AMDIL::GLOBALTRUNCSTORE_v4i32i8:
440     case AMDIL::REGIONTRUNCSTORE_v4i32i8:
441     case AMDIL::LOCALTRUNCSTORE_v4i32i8:
442     case AMDIL::PRIVATETRUNCSTORE_v4i32i8:
443     case AMDIL::GLOBALTRUNCSTORE_v4i16i8:
444     case AMDIL::REGIONTRUNCSTORE_v4i16i8:
445     case AMDIL::LOCALTRUNCSTORE_v4i16i8:
446     case AMDIL::PRIVATETRUNCSTORE_v4i16i8:
447     case AMDIL::GLOBALSTORE_v4i8:
448     case AMDIL::LOCALSTORE_v4i8:
449     case AMDIL::REGIONSTORE_v4i8:
450     case AMDIL::PRIVATESTORE_v4i8:
451       return PACK_V4I8;
452     case AMDIL::GLOBALTRUNCSTORE_v2i64i16:
453     case AMDIL::REGIONTRUNCSTORE_v2i64i16:
454     case AMDIL::LOCALTRUNCSTORE_v2i64i16:
455     case AMDIL::PRIVATETRUNCSTORE_v2i64i16:
456     case AMDIL::GLOBALTRUNCSTORE_v2i32i16:
457     case AMDIL::REGIONTRUNCSTORE_v2i32i16:
458     case AMDIL::LOCALTRUNCSTORE_v2i32i16:
459     case AMDIL::PRIVATETRUNCSTORE_v2i32i16:
460     case AMDIL::GLOBALSTORE_v2i16:
461     case AMDIL::LOCALSTORE_v2i16:
462     case AMDIL::REGIONSTORE_v2i16:
463     case AMDIL::PRIVATESTORE_v2i16:
464       return PACK_V2I16;
465     case AMDIL::GLOBALTRUNCSTORE_v4i32i16:
466     case AMDIL::REGIONTRUNCSTORE_v4i32i16:
467     case AMDIL::LOCALTRUNCSTORE_v4i32i16:
468     case AMDIL::PRIVATETRUNCSTORE_v4i32i16:
469     case AMDIL::GLOBALSTORE_v4i16:
470     case AMDIL::LOCALSTORE_v4i16:
471     case AMDIL::REGIONSTORE_v4i16:
472     case AMDIL::PRIVATESTORE_v4i16:
473       return PACK_V4I16;
474     case AMDIL::GLOBALLOAD_v2i8:
475     case AMDIL::GLOBALSEXTLOAD_v2i8:
476     case AMDIL::GLOBALAEXTLOAD_v2i8:
477     case AMDIL::GLOBALZEXTLOAD_v2i8:
478     case AMDIL::LOCALLOAD_v2i8:
479     case AMDIL::LOCALSEXTLOAD_v2i8:
480     case AMDIL::LOCALAEXTLOAD_v2i8:
481     case AMDIL::LOCALZEXTLOAD_v2i8:
482     case AMDIL::REGIONLOAD_v2i8:
483     case AMDIL::REGIONSEXTLOAD_v2i8:
484     case AMDIL::REGIONAEXTLOAD_v2i8:
485     case AMDIL::REGIONZEXTLOAD_v2i8:
486     case AMDIL::PRIVATELOAD_v2i8:
487     case AMDIL::PRIVATESEXTLOAD_v2i8:
488     case AMDIL::PRIVATEAEXTLOAD_v2i8:
489     case AMDIL::PRIVATEZEXTLOAD_v2i8:
490     case AMDIL::CONSTANTLOAD_v2i8:
491     case AMDIL::CONSTANTSEXTLOAD_v2i8:
492     case AMDIL::CONSTANTAEXTLOAD_v2i8:
493     case AMDIL::CONSTANTZEXTLOAD_v2i8:
494       return UNPACK_V2I8;
495     case AMDIL::GLOBALLOAD_v4i8:
496     case AMDIL::GLOBALSEXTLOAD_v4i8:
497     case AMDIL::GLOBALAEXTLOAD_v4i8:
498     case AMDIL::GLOBALZEXTLOAD_v4i8:
499     case AMDIL::LOCALLOAD_v4i8:
500     case AMDIL::LOCALSEXTLOAD_v4i8:
501     case AMDIL::LOCALAEXTLOAD_v4i8:
502     case AMDIL::LOCALZEXTLOAD_v4i8:
503     case AMDIL::REGIONLOAD_v4i8:
504     case AMDIL::REGIONSEXTLOAD_v4i8:
505     case AMDIL::REGIONAEXTLOAD_v4i8:
506     case AMDIL::REGIONZEXTLOAD_v4i8:
507     case AMDIL::PRIVATELOAD_v4i8:
508     case AMDIL::PRIVATESEXTLOAD_v4i8:
509     case AMDIL::PRIVATEAEXTLOAD_v4i8:
510     case AMDIL::PRIVATEZEXTLOAD_v4i8:
511     case AMDIL::CONSTANTLOAD_v4i8:
512     case AMDIL::CONSTANTSEXTLOAD_v4i8:
513     case AMDIL::CONSTANTAEXTLOAD_v4i8:
514     case AMDIL::CONSTANTZEXTLOAD_v4i8:
515       return UNPACK_V4I8;
516     case AMDIL::GLOBALLOAD_v2i16:
517     case AMDIL::GLOBALSEXTLOAD_v2i16:
518     case AMDIL::GLOBALAEXTLOAD_v2i16:
519     case AMDIL::GLOBALZEXTLOAD_v2i16:
520     case AMDIL::LOCALLOAD_v2i16:
521     case AMDIL::LOCALSEXTLOAD_v2i16:
522     case AMDIL::LOCALAEXTLOAD_v2i16:
523     case AMDIL::LOCALZEXTLOAD_v2i16:
524     case AMDIL::REGIONLOAD_v2i16:
525     case AMDIL::REGIONSEXTLOAD_v2i16:
526     case AMDIL::REGIONAEXTLOAD_v2i16:
527     case AMDIL::REGIONZEXTLOAD_v2i16:
528     case AMDIL::PRIVATELOAD_v2i16:
529     case AMDIL::PRIVATESEXTLOAD_v2i16:
530     case AMDIL::PRIVATEAEXTLOAD_v2i16:
531     case AMDIL::PRIVATEZEXTLOAD_v2i16:
532     case AMDIL::CONSTANTLOAD_v2i16:
533     case AMDIL::CONSTANTSEXTLOAD_v2i16:
534     case AMDIL::CONSTANTAEXTLOAD_v2i16:
535     case AMDIL::CONSTANTZEXTLOAD_v2i16:
536       return UNPACK_V2I16;
537     case AMDIL::GLOBALLOAD_v4i16:
538     case AMDIL::GLOBALSEXTLOAD_v4i16:
539     case AMDIL::GLOBALAEXTLOAD_v4i16:
540     case AMDIL::GLOBALZEXTLOAD_v4i16:
541     case AMDIL::LOCALLOAD_v4i16:
542     case AMDIL::LOCALSEXTLOAD_v4i16:
543     case AMDIL::LOCALAEXTLOAD_v4i16:
544     case AMDIL::LOCALZEXTLOAD_v4i16:
545     case AMDIL::REGIONLOAD_v4i16:
546     case AMDIL::REGIONSEXTLOAD_v4i16:
547     case AMDIL::REGIONAEXTLOAD_v4i16:
548     case AMDIL::REGIONZEXTLOAD_v4i16:
549     case AMDIL::PRIVATELOAD_v4i16:
550     case AMDIL::PRIVATESEXTLOAD_v4i16:
551     case AMDIL::PRIVATEAEXTLOAD_v4i16:
552     case AMDIL::PRIVATEZEXTLOAD_v4i16:
553     case AMDIL::CONSTANTLOAD_v4i16:
554     case AMDIL::CONSTANTSEXTLOAD_v4i16:
555     case AMDIL::CONSTANTAEXTLOAD_v4i16:
556     case AMDIL::CONSTANTZEXTLOAD_v4i16:
557       return UNPACK_V4I16;
558   };
559   return NO_PACKING;
560 }
561
562   uint32_t
563 AMDILIOExpansion::getPointerID(MachineInstr *MI)
564 {
565   AMDILAS::InstrResEnc curInst;
566   getAsmPrinterFlags(MI, curInst);
567   return curInst.bits.ResourceID;
568 }
569
570   uint32_t
571 AMDILIOExpansion::getShiftSize(MachineInstr *MI)
572 {
573   switch(getPackedID(MI)) {
574     default:
575       return 0;
576     case PACK_V2I8:
577     case PACK_V4I8:
578     case UNPACK_V2I8:
579     case UNPACK_V4I8:
580       return 1;
581     case PACK_V2I16:
582     case PACK_V4I16:
583     case UNPACK_V2I16:
584     case UNPACK_V4I16:
585       return 2;
586   }
587   return 0;
588 }
589   uint32_t
590 AMDILIOExpansion::getMemorySize(MachineInstr *MI)
591 {
592   if (MI->memoperands_empty()) {
593     return 4;
594   }
595   return (uint32_t)((*MI->memoperands_begin())->getSize());
596 }
597
598   void
599 AMDILIOExpansion::expandLongExtend(MachineInstr *MI,
600     uint32_t numComps, uint32_t size, bool signedShift)
601 {
602   DebugLoc DL = MI->getDebugLoc();
603   switch(size) {
604     default:
605       assert(0 && "Found a case we don't handle!");
606       break;
607     case 8:
608       if (numComps == 1) {
609         expandLongExtendSub32(MI, AMDIL::SHL_i8, AMDIL::SHRVEC_v2i32, 
610             AMDIL::USHRVEC_i8,
611             24, (24ULL | (31ULL << 32)), 24, AMDIL::LCREATE, signedShift);
612       } else if (numComps == 2) {
613         expandLongExtendSub32(MI, AMDIL::SHL_v2i8, AMDIL::SHRVEC_v4i32, 
614             AMDIL::USHRVEC_v2i8,
615             24, (24ULL | (31ULL << 32)), 24, AMDIL::LCREATE_v2i64, signedShift);
616       } else {
617         assert(0 && "Found a case we don't handle!");
618       }
619       break;
620     case 16:
621       if (numComps == 1) {
622         expandLongExtendSub32(MI, AMDIL::SHL_i16, AMDIL::SHRVEC_v2i32, 
623             AMDIL::USHRVEC_i16,
624             16, (16ULL | (31ULL << 32)), 16, AMDIL::LCREATE, signedShift);
625       } else if (numComps == 2) {
626         expandLongExtendSub32(MI, AMDIL::SHL_v2i16, AMDIL::SHRVEC_v4i32, 
627             AMDIL::USHRVEC_v2i16,
628             16, (16ULL | (31ULL << 32)), 16, AMDIL::LCREATE_v2i64, signedShift);
629       } else {
630         assert(0 && "Found a case we don't handle!");
631       }
632       break;
633     case 32:
634       if (numComps == 1) {
635         if (signedShift) {
636           BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHRVEC_i32), AMDIL::R1012)
637             .addReg(AMDIL::R1011)
638             .addImm(mMFI->addi32Literal(31));
639           BuildMI(*mBB, MI, DL, mTII->get(AMDIL::LCREATE), AMDIL::R1011)
640             .addReg(AMDIL::R1011).addReg(AMDIL::R1012);
641         } else {
642           BuildMI(*mBB, MI, DL, mTII->get(AMDIL::LCREATE), AMDIL::R1011)
643             .addReg(AMDIL::R1011)
644             .addImm(mMFI->addi32Literal(0));
645         }
646       } else if (numComps == 2) {
647         if (signedShift) {
648           BuildMI(*mBB, MI, DL, mTII->get(AMDIL::SHRVEC_v2i32), AMDIL::R1012)
649             .addReg(AMDIL::R1011)
650             .addImm(mMFI->addi32Literal(31));
651           BuildMI(*mBB, MI, DL, mTII->get(AMDIL::LCREATE_v2i64), AMDIL::R1011)
652             .addReg(AMDIL::R1011)
653             .addReg(AMDIL::R1012);
654         } else {
655           BuildMI(*mBB, MI, DL, mTII->get(AMDIL::LCREATE_v2i64), AMDIL::R1011)
656             .addReg(AMDIL::R1011)
657             .addImm(mMFI->addi32Literal(0));
658         }
659       } else {
660         assert(0 && "Found a case we don't handle!");
661       }
662   };
663 }
664   void 
665 AMDILIOExpansion::expandLongExtendSub32(MachineInstr *MI, 
666     unsigned SHLop, unsigned SHRop, unsigned USHRop, 
667     unsigned SHLimm, uint64_t SHRimm, unsigned USHRimm, 
668     unsigned LCRop, bool signedShift)
669 {
670   DebugLoc DL = MI->getDebugLoc();
671   BuildMI(*mBB, MI, DL, mTII->get(SHLop), AMDIL::R1011)
672     .addReg(AMDIL::R1011)
673     .addImm(mMFI->addi32Literal(SHLimm));
674   if (signedShift) {
675     BuildMI(*mBB, MI, DL, mTII->get(LCRop), AMDIL::R1011)
676       .addReg(AMDIL::R1011).addReg(AMDIL::R1011);
677     BuildMI(*mBB, MI, DL, mTII->get(SHRop), AMDIL::R1011)
678       .addReg(AMDIL::R1011)
679       .addImm(mMFI->addi64Literal(SHRimm));
680   } else {
681     BuildMI(*mBB, MI, DL, mTII->get(USHRop), AMDIL::R1011)
682       .addReg(AMDIL::R1011)
683       .addImm(mMFI->addi32Literal(USHRimm));
684     BuildMI(*mBB, MI, MI->getDebugLoc(), mTII->get(LCRop), AMDIL::R1011)
685       .addReg(AMDIL::R1011)
686       .addImm(mMFI->addi32Literal(0));
687   }
688 }
689
690   void
691 AMDILIOExpansion::expandIntegerExtend(MachineInstr *MI, unsigned SHLop, 
692     unsigned SHRop, unsigned offset)
693 {
694   DebugLoc DL = MI->getDebugLoc();
695   offset = mMFI->addi32Literal(offset);
696   BuildMI(*mBB, MI, DL,
697       mTII->get(SHLop), AMDIL::R1011)
698     .addReg(AMDIL::R1011).addImm(offset);
699   BuildMI(*mBB, MI, DL,
700       mTII->get(SHRop), AMDIL::R1011)
701     .addReg(AMDIL::R1011).addImm(offset);
702 }
703   void
704 AMDILIOExpansion::expandExtendLoad(MachineInstr *MI)
705 {
706   if (!isExtendLoad(MI)) {
707     return;
708   }
709   Type *mType = NULL;
710   if (!MI->memoperands_empty()) {
711     MachineMemOperand *memOp = (*MI->memoperands_begin());
712     const Value *moVal = (memOp) ? memOp->getValue() : NULL;
713     mType = (moVal) ? moVal->getType() : NULL;
714   }
715   unsigned opcode = 0;
716   DebugLoc DL = MI->getDebugLoc();
717   if (isZExtLoadInst(TM.getInstrInfo(), MI) || isAExtLoadInst(TM.getInstrInfo(), MI) || isSExtLoadInst(TM.getInstrInfo(), MI)) {
718     switch(MI->getDesc().OpInfo[0].RegClass) {
719       default:
720         assert(0 && "Found an extending load that we don't handle!");
721         break;
722       case AMDIL::GPRI16RegClassID:
723         if (!isHardwareLocal(MI)
724             || mSTM->device()->usesSoftware(AMDILDeviceInfo::ByteLDSOps)) {
725           opcode = isSExtLoadInst(TM.getInstrInfo(), MI) ? AMDIL::SHRVEC_i16 : AMDIL::USHRVEC_i16;
726           expandIntegerExtend(MI, AMDIL::SHL_i16, opcode, 24);
727         }
728         break;
729       case AMDIL::GPRV2I16RegClassID:
730         opcode = isSExtLoadInst(TM.getInstrInfo(), MI) ? AMDIL::SHRVEC_v2i16 : AMDIL::USHRVEC_v2i16;
731         expandIntegerExtend(MI, AMDIL::SHL_v2i16, opcode, 24);
732         break;
733       case AMDIL::GPRV4I8RegClassID:        
734         opcode = isSExtLoadInst(TM.getInstrInfo(), MI) ? AMDIL::SHRVEC_v4i8 : AMDIL::USHRVEC_v4i8;
735         expandIntegerExtend(MI, AMDIL::SHL_v4i8, opcode, 24);
736         break;
737       case AMDIL::GPRV4I16RegClassID:
738         opcode = isSExtLoadInst(TM.getInstrInfo(), MI) ? AMDIL::SHRVEC_v4i16 : AMDIL::USHRVEC_v4i16;
739         expandIntegerExtend(MI, AMDIL::SHL_v4i16, opcode, 24);
740         break;
741       case AMDIL::GPRI32RegClassID:
742         // We can be a i8 or i16 bit sign extended value
743         if (isNbitType(mType, 8) || getMemorySize(MI) == 1) {
744           opcode = isSExtLoadInst(TM.getInstrInfo(), MI) ? AMDIL::SHRVEC_i32 : AMDIL::USHRVEC_i32;
745           expandIntegerExtend(MI, AMDIL::SHL_i32, opcode, 24);
746         } else if (isNbitType(mType, 16) || getMemorySize(MI) == 2) {
747           opcode = isSExtLoadInst(TM.getInstrInfo(), MI) ? AMDIL::SHRVEC_i32 : AMDIL::USHRVEC_i32;
748           expandIntegerExtend(MI, AMDIL::SHL_i32, opcode, 16);
749         } else {
750           assert(0 && "Found an extending load that we don't handle!");
751         }
752         break;
753       case AMDIL::GPRV2I32RegClassID:
754         // We can be a v2i8 or v2i16 bit sign extended value
755         if (isNbitType(mType, 8, false) || getMemorySize(MI) == 2) {
756           opcode = isSExtLoadInst(TM.getInstrInfo(), MI) ? AMDIL::SHRVEC_v2i32 : AMDIL::USHRVEC_v2i32;
757           expandIntegerExtend(MI, AMDIL::SHL_v2i32, opcode, 24);
758         } else if (isNbitType(mType, 16, false) || getMemorySize(MI) == 4) {
759           opcode = isSExtLoadInst(TM.getInstrInfo(), MI) ? AMDIL::SHRVEC_v2i32 : AMDIL::USHRVEC_v2i32;
760           expandIntegerExtend(MI, AMDIL::SHL_v2i32, opcode, 16);
761         } else {
762           assert(0 && "Found an extending load that we don't handle!");
763         }
764         break;
765       case AMDIL::GPRV4I32RegClassID:
766         // We can be a v4i8 or v4i16 bit sign extended value
767         if (isNbitType(mType, 8, false) || getMemorySize(MI) == 4) {
768           opcode = isSExtLoadInst(TM.getInstrInfo(), MI) ? AMDIL::SHRVEC_v4i32 : AMDIL::USHRVEC_v4i32;
769           expandIntegerExtend(MI, AMDIL::SHL_v4i32, opcode, 24);
770         } else if (isNbitType(mType, 16, false) || getMemorySize(MI) == 8) {
771           opcode = isSExtLoadInst(TM.getInstrInfo(), MI) ? AMDIL::SHRVEC_v4i32 : AMDIL::USHRVEC_v4i32;
772           expandIntegerExtend(MI, AMDIL::SHL_v4i32, opcode, 16);
773         } else {
774           assert(0 && "Found an extending load that we don't handle!");
775         }
776         break;
777       case AMDIL::GPRI64RegClassID:
778         // We can be a i8, i16 or i32 bit sign extended value
779         if (isNbitType(mType, 8) || getMemorySize(MI) == 1) {
780           expandLongExtend(MI, 1, 8, isSExtLoadInst(TM.getInstrInfo(), MI));
781         } else if (isNbitType(mType, 16) || getMemorySize(MI) == 2) {
782           expandLongExtend(MI, 1, 16, isSExtLoadInst(TM.getInstrInfo(), MI));
783         } else if (isNbitType(mType, 32) || getMemorySize(MI) == 4) {
784           expandLongExtend(MI, 1, 32, isSExtLoadInst(TM.getInstrInfo(), MI));
785         } else {
786           assert(0 && "Found an extending load that we don't handle!");
787         }
788         break;
789       case AMDIL::GPRV2I64RegClassID:
790         // We can be a v2i8, v2i16 or v2i32 bit sign extended value
791         if (isNbitType(mType, 8, false) || getMemorySize(MI) == 2) {
792           expandLongExtend(MI, 2, 8, isSExtLoadInst(TM.getInstrInfo(), MI));
793         } else if (isNbitType(mType, 16, false) || getMemorySize(MI) == 4) {
794           expandLongExtend(MI, 2, 16, isSExtLoadInst(TM.getInstrInfo(), MI));
795         } else if (isNbitType(mType, 32, false) || getMemorySize(MI) == 8) {
796           expandLongExtend(MI, 2, 32, isSExtLoadInst(TM.getInstrInfo(), MI));
797         } else {
798           assert(0 && "Found an extending load that we don't handle!");
799         }
800         break;
801       case AMDIL::GPRF32RegClassID:
802         BuildMI(*mBB, MI, DL, 
803             mTII->get(AMDIL::HTOF_f32), AMDIL::R1011)
804           .addReg(AMDIL::R1011);
805         break;
806       case AMDIL::GPRV2F32RegClassID:
807         BuildMI(*mBB, MI, DL, 
808             mTII->get(AMDIL::HTOF_v2f32), AMDIL::R1011)
809           .addReg(AMDIL::R1011);
810         break;
811       case AMDIL::GPRV4F32RegClassID:
812         BuildMI(*mBB, MI, DL, 
813             mTII->get(AMDIL::HTOF_v4f32), AMDIL::R1011)
814           .addReg(AMDIL::R1011);
815         break;
816       case AMDIL::GPRF64RegClassID:
817         BuildMI(*mBB, MI, DL, 
818             mTII->get(AMDIL::FTOD), AMDIL::R1011)
819           .addReg(AMDIL::R1011);
820         break;
821       case AMDIL::GPRV2F64RegClassID:
822         BuildMI(*mBB, MI, DL, mTII->get(AMDIL::VEXTRACT_v2f32),
823             AMDIL::R1012).addReg(AMDIL::R1011).addImm(2);
824         BuildMI(*mBB, MI, DL, 
825             mTII->get(AMDIL::FTOD), AMDIL::R1011)
826           .addReg(AMDIL::R1011);
827         BuildMI(*mBB, MI, DL, 
828             mTII->get(AMDIL::FTOD), AMDIL::R1012)
829           .addReg(AMDIL::R1012);
830         BuildMI(*mBB, MI, DL,
831             mTII->get(AMDIL::VINSERT_v2f64), AMDIL::R1011)
832           .addReg(AMDIL::R1011).addReg(AMDIL::R1012)
833           .addImm(1 << 8).addImm(1 << 8);
834         break;
835     };
836   } else if (isSWSExtLoadInst(MI)) {
837     switch(MI->getDesc().OpInfo[0].RegClass) {
838       case AMDIL::GPRI8RegClassID:
839         if (!isHardwareLocal(MI)
840             || mSTM->device()->usesSoftware(AMDILDeviceInfo::ByteLDSOps)) {
841           expandIntegerExtend(MI, AMDIL::SHL_i8, AMDIL::SHRVEC_i8, 24);
842         }
843         break;
844       case AMDIL::GPRV2I8RegClassID:
845         expandIntegerExtend(MI, AMDIL::SHL_v2i8, AMDIL::SHRVEC_v2i8, 24);
846         break;
847       case AMDIL::GPRV4I8RegClassID:
848         expandIntegerExtend(MI, AMDIL::SHL_v4i8, AMDIL::SHRVEC_v4i8, 24);
849         break;
850       case AMDIL::GPRI16RegClassID:
851         if (!isHardwareLocal(MI)
852             || mSTM->device()->usesSoftware(AMDILDeviceInfo::ByteLDSOps)) {
853           expandIntegerExtend(MI, AMDIL::SHL_i16, AMDIL::SHRVEC_i16, 16);
854         }
855         break;
856       case AMDIL::GPRV2I16RegClassID:
857         expandIntegerExtend(MI, AMDIL::SHL_v2i16, AMDIL::SHRVEC_v2i16, 16);
858         break;
859       case AMDIL::GPRV4I16RegClassID:
860         expandIntegerExtend(MI, AMDIL::SHL_v4i16, AMDIL::SHRVEC_v4i16, 16);
861         break;
862
863     };
864   }
865 }
866
867   void
868 AMDILIOExpansion::expandTruncData(MachineInstr *MI)
869 {
870   MachineBasicBlock::iterator I = *MI;
871   if (!isTruncStoreInst(TM.getInstrInfo(), MI)) {
872     return;
873   }
874   DebugLoc DL = MI->getDebugLoc();
875   switch (MI->getOpcode()) {
876     default: 
877       MI->dump();
878       assert(!"Found a trunc store instructions we don't handle!");
879       break;
880     case AMDIL::GLOBALTRUNCSTORE_i64i8:
881     case AMDIL::GLOBALTRUNCSTORE_v2i64i8:
882     case AMDIL::LOCALTRUNCSTORE_i64i8:
883     case AMDIL::LOCALTRUNCSTORE_v2i64i8:
884     case AMDIL::REGIONTRUNCSTORE_i64i8:
885     case AMDIL::REGIONTRUNCSTORE_v2i64i8:
886     case AMDIL::PRIVATETRUNCSTORE_i64i8:
887     case AMDIL::PRIVATETRUNCSTORE_v2i64i8:
888       BuildMI(*mBB, MI, DL,
889           mTII->get(AMDIL::LLO_v2i64), AMDIL::R1011)
890           .addReg(AMDIL::R1011);
891     case AMDIL::GLOBALTRUNCSTORE_i16i8:
892     case AMDIL::GLOBALTRUNCSTORE_v2i16i8:
893     case AMDIL::GLOBALTRUNCSTORE_v4i16i8:
894     case AMDIL::LOCALTRUNCSTORE_i16i8:
895     case AMDIL::LOCALTRUNCSTORE_v2i16i8:
896     case AMDIL::LOCALTRUNCSTORE_v4i16i8:
897     case AMDIL::REGIONTRUNCSTORE_i16i8:
898     case AMDIL::REGIONTRUNCSTORE_v2i16i8:
899     case AMDIL::REGIONTRUNCSTORE_v4i16i8:
900     case AMDIL::PRIVATETRUNCSTORE_i16i8:
901     case AMDIL::PRIVATETRUNCSTORE_v2i16i8:
902     case AMDIL::PRIVATETRUNCSTORE_v4i16i8:
903     case AMDIL::GLOBALTRUNCSTORE_i32i8:
904     case AMDIL::GLOBALTRUNCSTORE_v2i32i8:
905     case AMDIL::GLOBALTRUNCSTORE_v4i32i8:
906     case AMDIL::LOCALTRUNCSTORE_i32i8:
907     case AMDIL::LOCALTRUNCSTORE_v2i32i8:
908     case AMDIL::LOCALTRUNCSTORE_v4i32i8:
909     case AMDIL::REGIONTRUNCSTORE_i32i8:
910     case AMDIL::REGIONTRUNCSTORE_v2i32i8:
911     case AMDIL::REGIONTRUNCSTORE_v4i32i8:
912     case AMDIL::PRIVATETRUNCSTORE_i32i8:
913     case AMDIL::PRIVATETRUNCSTORE_v2i32i8:
914     case AMDIL::PRIVATETRUNCSTORE_v4i32i8:
915       BuildMI(*mBB, MI, DL, 
916           mTII->get(AMDIL::BINARY_AND_v4i32), AMDIL::R1011)
917         .addReg(AMDIL::R1011)
918         .addImm(mMFI->addi32Literal(0xFF));
919       break;
920     case AMDIL::GLOBALTRUNCSTORE_i64i16:
921     case AMDIL::GLOBALTRUNCSTORE_v2i64i16:
922     case AMDIL::LOCALTRUNCSTORE_i64i16:
923     case AMDIL::LOCALTRUNCSTORE_v2i64i16:
924     case AMDIL::REGIONTRUNCSTORE_i64i16:
925     case AMDIL::REGIONTRUNCSTORE_v2i64i16:
926     case AMDIL::PRIVATETRUNCSTORE_i64i16:
927     case AMDIL::PRIVATETRUNCSTORE_v2i64i16:
928       BuildMI(*mBB, MI, DL,
929           mTII->get(AMDIL::LLO_v2i64), AMDIL::R1011)
930           .addReg(AMDIL::R1011);
931     case AMDIL::GLOBALTRUNCSTORE_i32i16:
932     case AMDIL::GLOBALTRUNCSTORE_v2i32i16:
933     case AMDIL::GLOBALTRUNCSTORE_v4i32i16:
934     case AMDIL::LOCALTRUNCSTORE_i32i16:
935     case AMDIL::LOCALTRUNCSTORE_v2i32i16:
936     case AMDIL::LOCALTRUNCSTORE_v4i32i16:
937     case AMDIL::REGIONTRUNCSTORE_i32i16:
938     case AMDIL::REGIONTRUNCSTORE_v2i32i16:
939     case AMDIL::REGIONTRUNCSTORE_v4i32i16:
940     case AMDIL::PRIVATETRUNCSTORE_i32i16:
941     case AMDIL::PRIVATETRUNCSTORE_v2i32i16:
942     case AMDIL::PRIVATETRUNCSTORE_v4i32i16:
943       BuildMI(*mBB, MI, DL, 
944           mTII->get(AMDIL::BINARY_AND_v4i32), AMDIL::R1011)
945         .addReg(AMDIL::R1011)
946         .addImm(mMFI->addi32Literal(0xFFFF));
947       break;
948     case AMDIL::GLOBALTRUNCSTORE_i64i32:
949     case AMDIL::LOCALTRUNCSTORE_i64i32:
950     case AMDIL::REGIONTRUNCSTORE_i64i32:
951     case AMDIL::PRIVATETRUNCSTORE_i64i32:
952       BuildMI(*mBB, MI, DL,
953           mTII->get(AMDIL::LLO), AMDIL::R1011)
954           .addReg(AMDIL::R1011);
955       break;
956     case AMDIL::GLOBALTRUNCSTORE_v2i64i32:
957     case AMDIL::LOCALTRUNCSTORE_v2i64i32:
958     case AMDIL::REGIONTRUNCSTORE_v2i64i32:
959     case AMDIL::PRIVATETRUNCSTORE_v2i64i32:
960       BuildMI(*mBB, MI, DL,
961           mTII->get(AMDIL::LLO_v2i64), AMDIL::R1011)
962           .addReg(AMDIL::R1011);
963       break;
964     case AMDIL::GLOBALTRUNCSTORE_f64f32:
965     case AMDIL::LOCALTRUNCSTORE_f64f32:
966     case AMDIL::REGIONTRUNCSTORE_f64f32:
967     case AMDIL::PRIVATETRUNCSTORE_f64f32:
968       BuildMI(*mBB, MI, DL, mTII->get(AMDIL::DTOF),
969           AMDIL::R1011).addReg(AMDIL::R1011);
970       break;
971     case AMDIL::GLOBALTRUNCSTORE_v2f64f32:
972     case AMDIL::LOCALTRUNCSTORE_v2f64f32:
973     case AMDIL::REGIONTRUNCSTORE_v2f64f32:
974     case AMDIL::PRIVATETRUNCSTORE_v2f64f32:
975       BuildMI(*mBB, I, DL, mTII->get(AMDIL::VEXTRACT_v2f64),
976           AMDIL::R1012).addReg(AMDIL::R1011).addImm(2);
977       BuildMI(*mBB, MI, DL, mTII->get(AMDIL::DTOF),
978           AMDIL::R1011).addReg(AMDIL::R1011);
979       BuildMI(*mBB, MI, DL, mTII->get(AMDIL::DTOF),
980           AMDIL::R1012).addReg(AMDIL::R1012);
981       BuildMI(*mBB, MI, DL, mTII->get(AMDIL::VINSERT_v2f32),
982           AMDIL::R1011).addReg(AMDIL::R1011).addReg(AMDIL::R1012)
983         .addImm(1 << 8).addImm(1 << 8);
984       break;
985   }
986 }
987   void
988 AMDILIOExpansion::expandAddressCalc(MachineInstr *MI)
989 {
990   if (!isAddrCalcInstr(MI)) {
991     return;
992   }
993   DebugLoc DL = MI->getDebugLoc();
994   switch(MI->getOpcode()) {
995     ExpandCaseToAllTruncTypes(AMDIL::PRIVATETRUNCSTORE)
996       ExpandCaseToAllTypes(AMDIL::PRIVATESTORE)
997       ExpandCaseToAllTypes(AMDIL::PRIVATELOAD)
998       ExpandCaseToAllTypes(AMDIL::PRIVATESEXTLOAD)
999       ExpandCaseToAllTypes(AMDIL::PRIVATEZEXTLOAD)
1000       ExpandCaseToAllTypes(AMDIL::PRIVATEAEXTLOAD)
1001       BuildMI(*mBB, MI, DL, mTII->get(AMDIL::ADD_i32), 
1002           AMDIL::R1010).addReg(AMDIL::R1010).addReg(AMDIL::T1);
1003     break;
1004     ExpandCaseToAllTruncTypes(AMDIL::LOCALTRUNCSTORE)
1005       ExpandCaseToAllTypes(AMDIL::LOCALLOAD)
1006       ExpandCaseToAllTypes(AMDIL::LOCALSEXTLOAD)
1007       ExpandCaseToAllTypes(AMDIL::LOCALZEXTLOAD)
1008       ExpandCaseToAllTypes(AMDIL::LOCALAEXTLOAD)
1009       ExpandCaseToAllTypes(AMDIL::LOCALSTORE)
1010       BuildMI(*mBB, MI, DL, mTII->get(AMDIL::ADD_i32), 
1011           AMDIL::R1010).addReg(AMDIL::R1010).addReg(AMDIL::T2);
1012     break;
1013     ExpandCaseToAllTypes(AMDIL::CPOOLLOAD)
1014       ExpandCaseToAllTypes(AMDIL::CPOOLSEXTLOAD)
1015       ExpandCaseToAllTypes(AMDIL::CPOOLZEXTLOAD)
1016       ExpandCaseToAllTypes(AMDIL::CPOOLAEXTLOAD)
1017       BuildMI(*mBB, MI, DL, mTII->get(AMDIL::ADD_i32), 
1018           AMDIL::R1010).addReg(AMDIL::R1010).addReg(AMDIL::SDP);
1019     break;
1020     default:
1021     return;
1022   }
1023 }
1024   void
1025 AMDILIOExpansion::expandLoadStartCode(MachineInstr *MI)
1026 {
1027   DebugLoc DL = MI->getDebugLoc();
1028   if (MI->getOperand(2).isReg()) {
1029     BuildMI(*mBB, MI, DL, mTII->get(AMDIL::ADD_i32),
1030         AMDIL::R1010).addReg(MI->getOperand(1).getReg())
1031       .addReg(MI->getOperand(2).getReg());
1032   } else {
1033     BuildMI(*mBB, MI, DL, mTII->get(AMDIL::MOVE_i32),
1034         AMDIL::R1010).addReg(MI->getOperand(1).getReg());
1035   }
1036   MI->getOperand(1).setReg(AMDIL::R1010);
1037   expandAddressCalc(MI);
1038 }
1039   void
1040 AMDILIOExpansion::emitStaticCPLoad(MachineInstr* MI, int swizzle, 
1041     int id, bool ExtFPLoad)
1042 {
1043   DebugLoc DL = MI->getDebugLoc();
1044   switch(swizzle) {
1045     default:
1046       BuildMI(*mBB, MI, DL, mTII->get(ExtFPLoad 
1047             ? AMDIL::DTOF : AMDIL::MOVE_i32), 
1048           MI->getOperand(0).getReg())
1049         .addImm(id);
1050       break;
1051     case 1:
1052     case 2:
1053     case 3:
1054       BuildMI(*mBB, MI, DL, mTII->get(ExtFPLoad 
1055             ? AMDIL::DTOF : AMDIL::MOVE_i32), AMDIL::R1001)
1056         .addImm(id);
1057       BuildMI(*mBB, MI, DL, mTII->get(AMDIL::VINSERT_v4i32),
1058           MI->getOperand(0).getReg())
1059         .addReg(MI->getOperand(0).getReg())
1060         .addReg(AMDIL::R1001)
1061         .addImm(swizzle + 1);
1062       break;
1063   };
1064 }
1065   void
1066 AMDILIOExpansion::emitCPInst(MachineInstr* MI,
1067     const Constant* C, AMDILKernelManager* KM, int swizzle, bool ExtFPLoad)
1068 {
1069   if (const ConstantFP* CFP = dyn_cast<ConstantFP>(C)) {
1070     if (CFP->getType()->isFloatTy()) {
1071       uint32_t val = (uint32_t)(CFP->getValueAPF().bitcastToAPInt()
1072           .getZExtValue());
1073       uint32_t id = mMFI->addi32Literal(val);
1074       if (!id) {
1075         const APFloat &APF = CFP->getValueAPF();
1076         union dtol_union {
1077           double d;
1078           uint64_t ul;
1079         } conv;
1080         if (&APF.getSemantics()
1081             == (const llvm::fltSemantics*)&APFloat::IEEEsingle) {
1082           float fval = APF.convertToFloat();
1083           conv.d = (double)fval;
1084         } else {
1085           conv.d = APF.convertToDouble();
1086         }
1087         id = mMFI->addi64Literal(conv.ul);
1088       }
1089       emitStaticCPLoad(MI, swizzle, id, ExtFPLoad);
1090     } else {
1091       const APFloat &APF = CFP->getValueAPF();
1092       union ftol_union {
1093         double d;
1094         uint64_t ul;
1095       } conv;
1096       if (&APF.getSemantics()
1097           == (const llvm::fltSemantics*)&APFloat::IEEEsingle) {
1098         float fval = APF.convertToFloat();
1099         conv.d = (double)fval;
1100       } else {
1101         conv.d = APF.convertToDouble();
1102       }
1103       uint32_t id = mMFI->getLongLits(conv.ul);
1104       if (!id) {
1105         id = mMFI->getIntLits((uint32_t)conv.ul);
1106       }
1107       emitStaticCPLoad(MI, swizzle, id, ExtFPLoad);
1108     }
1109   } else if (const ConstantInt* CI = dyn_cast<ConstantInt>(C)) {
1110     int64_t val = 0;
1111     if (CI) {
1112       val = CI->getSExtValue();
1113     }
1114     if (CI->getBitWidth() == 64) {
1115       emitStaticCPLoad(MI, swizzle, mMFI->addi64Literal(val), ExtFPLoad);
1116     } else {
1117       emitStaticCPLoad(MI, swizzle, mMFI->addi32Literal(val), ExtFPLoad);
1118     }
1119   } else if (const ConstantArray* CA = dyn_cast<ConstantArray>(C)) {
1120     uint32_t size = CA->getNumOperands();
1121     assert(size < 5 && "Cannot handle a constant array where size > 4");
1122     if (size > 4) {
1123       size = 4;
1124     }
1125     for (uint32_t x = 0; x < size; ++x) {
1126       emitCPInst(MI, CA->getOperand(0), KM, x, ExtFPLoad);
1127     }
1128   } else if (const ConstantAggregateZero* CAZ
1129       = dyn_cast<ConstantAggregateZero>(C)) {
1130     if (CAZ->isNullValue()) {
1131       emitStaticCPLoad(MI, swizzle, mMFI->addi32Literal(0), ExtFPLoad);
1132     }
1133   } else if (const ConstantStruct* CS = dyn_cast<ConstantStruct>(C)) {
1134     uint32_t size = CS->getNumOperands();
1135     assert(size < 5 && "Cannot handle a constant array where size > 4");
1136     if (size > 4) {
1137       size = 4;
1138     }
1139     for (uint32_t x = 0; x < size; ++x) {
1140       emitCPInst(MI, CS->getOperand(0), KM, x, ExtFPLoad);
1141     }
1142   } else if (const ConstantVector* CV = dyn_cast<ConstantVector>(C)) {
1143     // TODO: Make this handle vectors natively up to the correct
1144     // size
1145     uint32_t size = CV->getNumOperands();
1146     assert(size < 5 && "Cannot handle a constant array where size > 4");
1147     if (size > 4) {
1148       size = 4;
1149     }
1150     for (uint32_t x = 0; x < size; ++x) {
1151       emitCPInst(MI, CV->getOperand(0), KM, x, ExtFPLoad);
1152     }
1153   } else {
1154     // TODO: Do we really need to handle ConstantPointerNull?
1155     // What about BlockAddress, ConstantExpr and Undef?
1156     // How would these even be generated by a valid CL program?
1157     assert(0 && "Found a constant type that I don't know how to handle");
1158   }
1159 }
1160