Generate better code for multiplies by negative constants like -4, -1, -9, etc.
[oota-llvm.git] / lib / Target / X86 / X86InstrSel.td
1 //===- X86InstrSel.td - Describe the X86 Instruction Selector -------*- C++ -*-===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file is used by the instruction selector and is used to map
11 //  LLVM instructions to a corresponding set of machine instructions
12 //
13 //
14 //===----------------------------------------------------------------------===//
15
16 include "../Target.td"
17
18   // ret br switch invoke unwind
19   // add sub mul div rem setcc (eq ne lt gt le ge)
20   // and or xor sbl sbr
21   // malloc free alloca load store
22   // getelementptr phi cast call vanext vaarg
23
24
25 class InstrSubclass<int v> {
26   int Value = v;
27 }
28
29 // provide a grouping of InstrSubclasses
30 class InstrSubclassCollection<string pre, string post, list<InstrSubclass> l> {
31   list<InstrSubclass> List = l;
32   string PreCode = pre;
33   string PostCode = post;
34 }
35
36 // virtual registers
37 let Namespace = "Virtual" in {
38   def DestReg   : Register;
39   def DestRegp1 : Register; // DestReg+1
40   def Op0Reg    : Register;
41   def Op0Regp1  : Register; // Op0Reg+1
42   def Op1Reg    : Register;
43   def Op1Regp1  : Register; // Op1Reg+1
44   def TmpReg01  : Register;
45   def TmpReg01p1: Register;
46   def TmpReg02  : Register;
47   def TmpReg02p1: Register;
48   def NullReg   : Register; // represents no register
49 }
50
51 class InstrClass<string n, string fn, string pre, string post, list<InstrSubclassCollection> l> {
52   string FunctionName = fn;
53   string InstructionName = n;
54   string PreCode = pre;
55   string PostCode = post;
56
57   // add lists of what subclasses this InstrClass supports
58   list<InstrSubclassCollection> Supports = l;
59 }
60
61
62 // helper class to build BMI instruction
63 class addedOperand<string op> {
64   string Name = op;
65 }
66
67 def MBI_Reg          : addedOperand<"Reg">;
68 def MBI_GlobalAddr   : addedOperand<"GlobalAddr">;
69 def MBI_ZImm         : addedOperand<"ZImm">;
70
71 def MBI_DirectMem    : addedOperand<"DirectMem">;
72 def MBI_RegOffset    : addedOperand<"RegOffset">;
73 def MBI_FrameRef     : addedOperand<"FrameRef">;
74 def MBI_ConstPoolRef : addedOperand<"ConstPoolRef">;
75 def MBI_CCReg        : addedOperand<"CCReg">;
76 def MBI_RegDef       : addedOperand<"RegDef">;
77 def MBI_PCDisp       : addedOperand<"PCDisp">;
78 def MBI_MReg         : addedOperand<"MReg">;
79 def MBI_SImm         : addedOperand<"SImm">;
80 def MBI_MBB          : addedOperand<"MBB">;
81 def MBI_FrameIndex   : addedOperand<"FrameIndex">;
82 def MBI_ConstPoolIdx : addedOperand<"ConstPoolIdx">;
83 def MBI_ExternSymbol : addedOperand<"ExternSymbol">;
84
85
86 class TargInstr<string n, int numops, list<addedOperand> lops> {
87
88   string Name = n; // make this a reference to the Instruction class
89   string Namespace;
90   int NumOperands = numops;
91   list<addedOperand> Params = lops; // will this work for mem-mem instrs, destination is implicitly a register
92
93 } //TargInstr
94
95
96 let Namespace = "Virtual" in {
97   // virtual instructions for creating registers
98   def CreateRegInt  : TargInstr<"CreateRegInt",0,[]>;
99   def CreateRegByte : TargInstr<"CreateRegByte",0,[]>;
100   def CreateRegShort: TargInstr<"CreateRegShort",0,[]>;
101   def CreateRegLong : TargInstr<"CreateRegLong",0,[]>;
102   
103   def CreateRegUInt  : TargInstr<"CreateRegUInt",0,[]>;
104   def CreateRegUByte : TargInstr<"CreateRegUByte",0,[]>;
105   def CreateRegUShort: TargInstr<"CreateRegUShort",0,[]>;
106   def CreateRegULong : TargInstr<"CreateRegULong",0,[]>;
107   
108   def CreateRegFloat  : TargInstr<"CreateRegFloat",0,[]>;
109   def CreateRegDouble : TargInstr<"CreateRegDouble",0,[]>;
110   def CreateRegPointer: TargInstr<"CreateRegPointer",0,[]>;
111   
112   def NullInstr       : TargInstr<"NullInstruction",0,[]>; // ignored
113 }
114
115 class TargInstrSet<InstrClass c, string pre, string post, list<InstrSubclass>  l,  list<TargInstr>  targs, list<list<string>> r> {
116   InstrClass Class = c;
117
118   list<InstrSubclass> List = l;
119   list<TargInstr> Instructions = targs;
120   list< list<string> > Operands = r; // generalized for all operand types
121
122   string PreCode = pre;
123   string PostCode = post;
124 }
125
126
127
128 // --------------------------------------------------------------------
129 // Begin architecture-specific information
130 // --------------------------------------------------------------------
131
132 include "X86RegisterInfo.td"
133 include "X86InstrSelInfo.td"
134
135
136 // set up the subclasses of instructions
137 // value is what the subclass's case value
138 def cByte  : InstrSubclass<1>;
139 def cInt   : InstrSubclass<2>;
140 def cShort : InstrSubclass<3>;
141 def cFP    : InstrSubclass<4>;
142 def cLong  : InstrSubclass<5>;
143
144 def EQ     : InstrSubclass<1>;
145 def NE     : InstrSubclass<2>;
146 def LT     : InstrSubclass<3>;
147 def GE     : InstrSubclass<4>;
148 def GT     : InstrSubclass<5>;
149 def LE     : InstrSubclass<6>;
150
151 def True   : InstrSubclass<1>;
152 def False  : InstrSubclass<0>;
153
154 def NegOne : InstrSubclass<-1>;
155 def PosOne : InstrSubclass<1>;
156 def Cons   :InstrSubclass<2>;
157 def Other  : InstrSubclass<0>;
158
159 def Regular: InstrSubclass<0>;
160 def Zero   : InstrSubclass<0>;
161
162 def NoOps  : InstrSubclass<0>;
163 def Ops    : InstrSubclass<1>;
164
165 def Signed   : InstrSubclass<0>;
166 def Unsigned : InstrSubclass<1>;
167
168 def SuccessorIsNextBB : InstrSubclass<0>;
169 def SuccessorIsNotNextBB: InstrSubclass<1>;
170
171 def Cond: InstrSubclass<0>;
172 def Uncond: InstrSubclass<1>;
173
174 def ConstTwo: InstrSubclass<2>;
175 def ConstNotTwo: InstrSubclass<3>;
176
177 def Reg: InstrSubclass<6>;
178
179
180 // group subclasses, specify how to determine instruction subclass
181 def OperandSize: InstrSubclassCollection<"unsigned OperandSize = getClassB(Op0Val->getType());","", [cByte, cShort, cInt, cFP, cLong]>;
182 def Conditional: InstrSubclassCollection<"unsigned Conditional;", "", [EQ, NE, LT, GE, GT, LE]>;
183 def SpecialCase: InstrSubclassCollection<"unsigned SpecialCase;", "", [True, False]>;
184
185 //TODO write funcs for separating out special cases
186 def AddSpecialCases: InstrSubclassCollection<"Subclasses AddSpecialCases = Other;", "", [NegOne,PosOne,Cons,Other]>;
187 def SubSpecialCases: InstrSubclassCollection<"unsigned SubSpecialCases = Other;", "", [NegOne,PosOne,Cons,Other]>;
188 def XorSpecialCases: InstrSubclassCollection<"unsigned XorSpecialCases = Other;","", [NegOne,Other]>;
189
190
191
192 // Instruction subclasses, as defined in llvm/Instructions.h:
193 // iTerminators.h : ReturnInst, BranchInst, SwitchInst, InvokeInst, UnwindInst
194 // iPHINode.h     : PHINode, 
195 // iOperators.h   : SetCondInst, 
196 // iMemory.h      : AllocationInst, MallocInst, AllocaInst, FreeInst, LoadInst, StoreInst, GetElementPtrInst, 
197 // iOther.h       : CastInst, CallInst, ShiftInst, VANextInst, VAArgInst, 
198 // InstrTypes.h   : TerminatorInst, BinaryOperator
199
200 // general classes of LLVM instructions, and the subclass sets that apply to them
201 def add : InstrClass<"BinaryOperator","Add","","",[AddSpecialCases, OperandSize]>;
202 def sub : InstrClass<"BinaryOperator","Sub","","",[SubSpecialCases, OperandSize]>;
203 // def mul : InstrClass<"BinaryOperator","Mul","","",[OperandSize]>;
204 // def div : InstrClass<"BinaryOperator","Div","","",[OperandSize]>;
205 // def rem : InstrClass<"BinaryOperator","Rem","","",[OperandSize]>;
206 def logic_and : InstrClass<"BinaryOperator","And","","",[OperandSize]>;
207 def logic_or  : InstrClass<"BinaryOperator","Or","","",[OperandSize]>;
208 def logic_xor : InstrClass<"BinaryOperator","Xor","","",[XorSpecialCases, OperandSize]>;
209 // //def mov : InstrClass<"ShiftInst","Mov","","",[OperandSize]>;
210
211 // def setcc: InstrClass<"SetCondInst","SetCondInst","","",[OperandSize]>;
212 // def branch  : InstrClass<"BranchInst","BranchInst","","",[Conditional]>;
213
214 // def retrn : InstrClass<"ReturnInst","ReturnInst","","",[]>;
215
216 // definition of machine instructions for instruction subclasses
217
218
219 // ADD
220
221 def ADD_Other_cByte     : TargInstrSet<add,"","",[Other,cByte],[CreateRegByte,ADDrr8],[["EAX"],["EAX","Op0Reg","Op1Reg"]]>;
222 def ADD_Other_cShort    : TargInstrSet<add,"","",[Other,cShort],[ADDrr16],[["DestReg","Op0Reg","Op1Reg"]]>;
223 def ADD_Other_cInt      : TargInstrSet<add,"","",[Other,cInt],[ADDrr32],[["DestReg","Op0Reg","Op1Reg"]]>;
224 def ADD_Other_cLong     : TargInstrSet<add,"","",[Other,cLong],[ADDrr32,ADCrr32],[["DestReg","Op0Reg","Op1Reg"],["DestReg","Op0Reg","Op1Reg"]]>;
225 def ADD_Other_cFP       : TargInstrSet<add,"","",[Other,cFP],[FpADD],[["DestReg","Op0Reg","Op1Reg"]]>;
226 def ADD_Constant_cByte  : TargInstrSet<add,"","",[Cons,cByte],[ADDri8],[["DestReg","Op0Reg","Op1Reg"]]>;
227 def ADD_Constant_cShort :TargInstrSet<add,"","",[Cons,cShort],[ADDri16],[["DestReg","Op0Reg","Op1Reg"]]>;
228 def ADD_Constant_cInt   :TargInstrSet<add,"","",[Cons,cInt],[ADDri32],[["DestReg","Op0Reg","Op1Reg"]]>;
229 def ADD_PosOne_cByte    : TargInstrSet<add,"","",[PosOne,cByte],[INCr8],[["DestReg","Op0Reg"]]>;
230 def ADD_PosOne_cShort   : TargInstrSet<add,"","",[PosOne,cShort],[INCr16],[["DestReg","Op0Reg"]]>;
231 def ADD_PosOne_cInt     : TargInstrSet<add,"","",[PosOne,cInt],[INCr32],[["DestReg","Op0Reg"]]>;
232 def ADD_NegOne_cByte    : TargInstrSet<add,"","",[NegOne,cByte],[DECr8],[["DestReg","Op0Reg"]]>;
233 def ADD_NegOne_cShort   : TargInstrSet<add,"","",[NegOne,cShort],[DECr16],[["DestReg","Op0Reg"]]>;
234 def ADD_NegOne_cInt     : TargInstrSet<add,"","",[NegOne,cInt],[DECr32],[["DestReg","Op0Reg"]]>;
235
236
237 // SUBTRACT
238
239 def SUB_Other_cByte     : TargInstrSet<sub,"","",[Other,cByte],[CreateRegByte,SUBrr8],[["EAX"],["EAX","Op0Reg","Op1Reg"]]>;
240 def SUB_Other_cShort    : TargInstrSet<sub,"","",[Other,cShort],[SUBrr16],[["DestReg","Op0Reg","Op1Reg"]]>;
241 def SUB_Other_cInt      : TargInstrSet<sub,"","",[Other,cInt],[SUBrr32],[["DestReg","Op0Reg","Op1Reg"]]>;
242 def SUB_Other_cLong     : TargInstrSet<sub,"","",[Other,cLong],[SUBrr32,SUBrr32],[["DestReg","Op0Reg","Op1Reg"],["DestReg","Op0Reg","Op1Reg"]]>;
243 def SUB_Other_cFP       : TargInstrSet<sub,"","",[Other,cFP],[FpSUB],[["DestReg","Op0Reg","Op1Reg"]]>;
244 def SUB_Constant_cByte  : TargInstrSet<sub,"","",[Cons,cByte],[SUBri8],[["DestReg","Op0Reg","Op1Reg"]]>;
245 def SUB_Constant_cShort :TargInstrSet<sub,"","",[Cons,cShort],[SUBri16],[["DestReg","Op0Reg","Op1Reg"]]>;
246 def SUB_Constant_cInt   :TargInstrSet<sub,"","",[Cons,cInt],[SUBri32],[["DestReg","Op0Reg","Op1Reg"]]>;
247 def SUB_PosOne_cByte    : TargInstrSet<sub,"","",[PosOne,cByte],[DECr8],[["DestReg","Op0Reg"]]>;
248 def SUB_PosOne_cShort   : TargInstrSet<sub,"","",[PosOne,cShort],[DECr16],[["DestReg","Op0Reg"]]>;
249 def SUB_PosOne_cInt     : TargInstrSet<sub,"","",[PosOne,cInt],[DECr32],[["DestReg","Op0Reg"]]>;
250 def SUB_NegOne_cByte    : TargInstrSet<sub,"","",[NegOne,cByte],[INCr8],[["DestReg","Op0Reg"]]>;
251 def SUB_NegOne_cShort   : TargInstrSet<sub,"","",[NegOne,cShort],[INCr16],[["DestReg","Op0Reg"]]>;
252 def SUB_NegOne_cInt     : TargInstrSet<sub,"","",[NegOne,cInt],[INCr32],[["DestReg","Op0Reg"]]>;
253
254
255 // def SHIFT_S_L_Const_Byte     : 
256 // def SHIFT_S_L_Const_Short    : 
257 // def SHIFT_S_L_Const_Int      : 
258 // def SHIFT_S_L_Const_SHLDIR32 : 
259 // def SHIFT_S_L_Reg_Byte       : 
260 // def SHIFT_S_L_Reg_Short      : 
261 // def SHIFT_S_L_Reg_Int        : 
262 // def SHIFT_S_R_Const_Byte     : 
263 // def SHIFT_S_R_Const_Short    :
264 // def SHIFT_S_R_Const_Int      : 
265 // def SHIFT_S_R_Const_SHRDIR32 : 
266 // def SHIFT_S_R_Reg_Byte       : 
267 // def SHIFT_S_R_Reg_Short      : 
268 // def SHIFT_S_R_Reg_Int        : 
269 // def SHIFT_U_L_Const_Byte     : 
270 // def SHIFT_U_L_Const_Short    : 
271 // def SHIFT_U_L_Const_Int      : 
272 // def SHIFT_U_L_Const_SHLDIR32 : 
273 // def SHIFT_U_L_Reg_Byte       : 
274 // def SHIFT_U_L_Reg_Short      : 
275 // def SHIFT_U_L_Reg_Int        : 
276 // def SHIFT_U_R_Const_Byte     : 
277 // def SHIFT_U_R_Const_Short    : 
278 // def SHIFT_U_R_Const_Int      : 
279 // def SHIFT_U_R_Const_SHRDIR32 : 
280 // def SHIFT_U_R_Reg_Byte       : 
281 // def SHIFT_U_R_Reg_Short      : 
282 // def SHIFT_U_R_Reg_Int        : 
283
284
285 // def CMP_i_Byte  : TargInstrSet<setcc,"","",[Constant,cByte],[CMPri8],[["DestReg","Op0Reg","Op1Val"]]>;
286 // def CMP_i_Short : TargInstrSet<setcc,"","",[Constant,cShort],[CMPri16],[["DestReg","Op0Reg","Op1Val"]]>;
287 // def CMP_i_Int   : TargInstrSet<setcc,"","",[Constant,cInt],[CMPri32],[["DestReg","Op0Reg","Op1Val"]]>;
288 // //def CMP_i_Long  : // not supported
289 // def CMP_z_Byte  : TargInstrSet<setcc,"ConstantInt *CI = dyn_cast<ConstantInt>(Op1); uint64_t Op1v = cast<ConstantInt>(CI)->getRawValue(); Op1v &= (1ULL << (8 << Class)) - 1;","",[Zero,cByte],[TESTrr8],[["DestReg","Op0Reg","Op0Reg"]]>;
290 // def CMP_z_Short : TargInstrSet<setcc,"ConstantInt *CI = dyn_cast<ConstantInt>(Op1); uint64_t Op1v = cast<ConstantInt>(CI)->getRawValue(); Op1v &= (1ULL << (8 << Class)) - 1;","",[Zero,cShort],[TESTrr16],[["DestReg","Op0Reg","Op0Reg"]]>;
291 // def CMP_z_Int   : TargInstrSet<setcc,"ConstantInt *CI = dyn_cast<ConstantInt>(Op1); uint64_t Op1v = cast<ConstantInt>(CI)->getRawValue(); Op1v &= (1ULL << (8 << Class)) - 1;","",[Zero,cInt],[TESTrr32],[["DestReg","Op0Reg","Op0Reg"]]>;
292 // //def CMP_z_Long  : // not supported
293 // def CMP_r_Byte  : TargInstrSet<setcc,"","",[Regular,cByte],[CMPrr8],[["NullReg","Op0Reg","Op1Reg"]]>;
294 // def CMP_r_Short : TargInstrSet<setcc,"","",[Regular,cShort],[CMPrr16],[["NullReg","Op0Reg","Op1Reg"]]>;
295 // def CMP_r_Int   : TargInstrSet<setcc,"","",[Regular,cInt],[CMPrr32],[["NullReg","Op0Reg","Op1Reg"]]>;
296 // //def CMP_r_Long  : // two cases of long, depending on num of operands
297 // def CMP_r_FP    : TargInstrSet<setcc,"","",[Regular,cFP],[FpUCOM,FNSTSWr8,SAHF],[["NullReg","Op0Reg","Op1Reg"],["NullReg"],["NullReg"]]>;
298
299
300 // def RET_NoOps    : TargInstrSet<retrn,"","",[NoOps],[FP_REG_KILL,RET],[["NullReg"],["NullReg"]]>;
301 // def RET_Op_Byte  : TargInstrSet<retrn,"promote32(X86::EAX, ValueRecord(Op0Reg, Op0Val->getType()));","",[Ops,cByte],[IMPLICIT_USE],[["NullReg","EAX","ESP"]]>;
302 // def RET_Op_Short : TargInstrSet<retrn,"promote32(X86::EAX, ValueRecord(Op0Reg, Op0Val->getType()));","",[Ops,cShort],[IMPLICIT_USE],[["NullReg","EAX","ESP"]]>;
303 // def RET_Op_Int   : TargInstrSet<retrn,"promote32(X86::EAX, ValueRecord(Op0Reg, Op0Val->getType()));","",[Ops,cInt],[IMPLICIT_USE],[["NullReg","EAX","ESP"]]>;
304 // def RET_Op_FP    : TargInstrSet<retrn,"","",[Ops,cFP],[FpSETRESULT,IMPLICIT_USE],[["NullReg","Op0Reg"],["NullReg","STO","ESP"]]>;
305 // def RET_Op_Long  : TargInstrSet<retrn,"","",[Ops,cLong],[MOVrr32,MOVrr32,IMPLICIT_USE],[["EAX","Op0Reg"],["EDX","Op0Reg+1"],["NullReg","EAX","EDX","ESP"]]>;
306
307
308 // def BR_Uncond    : TargInstrSet<branch,"","",[Uncond],[FP_REG_KILL,JMP],[["NullReg"],["NullReg","I.getSuccessor(0);"]]>;
309 // def BR_Cond_S_EQ : 
310 // def BR_Cond_S_NE
311 // def BR_Cond_S_B
312 // def BR_Cond_S_AE
313 // def BR_Cond_S_A
314 // def BR_Cond_S_BE
315 // def BR_Cond_U_EQ
316 // def BR_Cond_U_NE
317 // def BR_Cond_U_LT
318 // def BR_Cond_U_GE
319 // def BR_Cond_U_GT
320 // def BR_Cond_U_LE
321 // def BR_Cond_U_S
322 // def BR_Cond_U_NS
323
324
325 // def CALL_Byte
326 // def CALL_Short
327 // def CALL_Int
328 // def CALL_Long
329 // def CALL_FP
330
331
332 def AND_Byte  : TargInstrSet<logic_and,"","",[cByte],[ANDrr8],[["DestReg","Op0Reg","Op1Reg"]]>;
333 def AND_Short : TargInstrSet<logic_and,"","",[cShort],[ANDrr16],[["DestReg","Op0Reg","Op1Reg"]]>;
334 def AND_Int   : TargInstrSet<logic_and,"","",[cInt],[ANDrr32],[["DestReg","Op0Reg","Op1Reg"]]>;
335 def AND_Long  : TargInstrSet<logic_and,"","",[cLong],[ANDrr32,ANDrr32],[["DestReg","Op0Reg","Op1Reg"],["DestReg+1","Op0Reg+1","Op1Reg+1"]]>;
336
337
338 def OR_Byte  : TargInstrSet<logic_or,"","",[cByte],[ORrr8],[["DestReg","Op0Reg","Op1Reg"]]>;
339 def OR_Short : TargInstrSet<logic_or,"","",[cShort],[ORrr16],[["DestReg","Op0Reg","Op1Reg"]]>;
340 def OR_Int   : TargInstrSet<logic_or,"","",[cInt],[ORrr32],[["DestReg","Op0Reg","Op1Reg"]]>;
341 def OR_Long  : TargInstrSet<logic_or,"","",[cLong],[ORrr32,ORrr32],[["DestReg","Op0Reg","Op1Reg"],["DestReg+1","Op0Reg+1","Op1Reg+1"]]>;
342
343
344 def XOR_NegOne_Byte : TargInstrSet<logic_xor,"","",[NegOne,cByte],[NOTr8],[["DestReg","Op0Reg"]]>;
345 def XOR_NegOne_Short: TargInstrSet<logic_xor,"","",[NegOne,cShort],[NOTr16],[["DestReg","Op0Reg"]]>;
346 def XOR_NegOne_Int  : TargInstrSet<logic_xor,"","",[NegOne,cInt],[NOTr32],[["DestReg","Op0Reg"]]>;
347 //def XOR_NegOne_Long :  // not supported (treat as regular long XOR)
348 def XOR_Other_Byte  : TargInstrSet<logic_xor,"","",[Other,cByte],[XORrr8],[["DestReg","Op0Reg","Op1Reg"]]>;
349 def XOR_Other_Short : TargInstrSet<logic_xor,"","",[Other,cByte],[XORrr16],[["DestReg","Op0Reg","Op1Reg"]]>;
350 def XOR_Other_Int   : TargInstrSet<logic_xor,"","",[Other,cByte],[XORrr32],[["DestReg","Op0Reg","Op1Reg"]]>;
351 def XOR_Other_Long  : TargInstrSet<logic_xor,"","",[Other,cLong],[XORrr32,XORrr32],[["DestReg","Op0Reg","Op1Reg"],["DestReg+1","Op0Reg+1","Op1Reg+1"]]>;
352
353
354
355 // // TODO support for arbitrary values as operand arguments
356 // //      or make ConstantInt versions as well-known variables
357 // // ConstantInt, unsigned Val
358 // def MUL_ConstTwo_Byte     : TargInstrSet<mul,"ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1)); unsigned Val = (unsigned)CI->getRawValue(); unsigned Shift = ExactLog2(Val);","",[ConstTwo,cByte],[SHLir32],[["DestReg","Op0Reg","Shift-1"]]>;
359 // def MUL_ConstTwo_Short    : TargInstrSet<mul,"ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1)); unsigned Val = (unsigned)CI->getRawValue(); unsigned Shift = ExactLog2(Val);","",[ConstTwo,cShort],[SHLir32],[["DestReg","Op0Reg","Shift-1"]]>;
360 // def MUL_ConstTwo_Int      : TargInstrSet<mul,"ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1)); unsigned Val = (unsigned)CI->getRawValue(); unsigned Shift = ExactLog2(Val);","",[ConstTwo,cInt],[SHLir32],[["DestReg","Op0Reg","Shift-1"]]>;
361 // def MUL_ConstNotTwo_Byte  : TargInstrSet<mul,"","",[ConstNotTwo,cByte],[CreateRegByte,MOVir8,MOVrr8,MULr8,MOVrr8],[["tmpReg"],["tmpReg","ConstRHS"],["AL","Op0Reg"],["NullReg","Op1Reg"],["DestReg","AL"]]>; //TODO fixme, define ConstRHS
362 // def MUL_ConstNotTwo_Short : TargInstrSet<mul,"","",[ConstNotTwo,cShort],[IMULri16],[["DestReg","Op0Reg","Val"]]>;
363 // def MUL_ConstNotTwo_Int   : TargInstrSet<mul,"","",[ConstNotTwo,cInt],[IMULri32],[["DestReg","Op0Reg","Val"]]>;
364 // //def MUL_ConstNotTwo_Long  :
365 // //def MUL_ConstNotTwo_FP    :
366 // def MUL_Reg_Byte          : TargInstrSet<mul,"","",[Reg,cByte],[MOVrr8,MULr8,MOVrr8],[["AL","Op0Reg"],["NullReg","Op1Reg"],["DestReg","AL"]]>;
367 // def MUL_Reg_Short         : TargInstrSet<mul,"","",[Reg,cShort],[IMULrr16],[["DestReg","Op0Reg","Op1Reg"]]>;
368 // def MUL_Reg_Int           : TargInstrSet<mul,"","",[Reg,cInt],[IMULrr32],[["DestReg","Op0Reg","Op1Reg"]]>;
369 // //def MUL_Reg_Long          : // not supported (assert)
370 // def MUL_Reg_FP            : TargInstrSet<mul,"","",[Reg,cFP],[FpMUL],[["DestReg","Op0Reg","Op1Reg"]]>;
371
372 // def STO_Byte
373 // def STO_Short
374 // def STO_Int
375 // def STO_FP
376 // def STO_Long
377
378
379 // DIVREM
380
381 // CAST
382
383 // PHI
384
385 // LOAD ARGS TO VIRTUAL REGS
386
387 // COPY CONSTANT
388
389 //TODO
390 //  handling various operand options
391 //  allowing for arbitrary code or operand arguments
392 //  generate skeletons for selector function
393 //