1//==== SPUInstrFormats.td - Cell SPU Instruction Formats ---*- tablegen -*-===// 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 10//===----------------------------------------------------------------------===// 11// 12// Cell SPU instruction formats. Note that these are notationally similar to 13// PowerPC, like "A-Form". But the sizes of operands and fields differ. 14 15// This was kiped from the PPC instruction formats (seemed like a good idea...) 16 17class SPUInstr<dag OOL, dag IOL, string asmstr, InstrItinClass itin> 18 : Instruction { 19 field bits<32> Inst; 20 21 let Namespace = "SPU"; 22 let OutOperandList = OOL; 23 let InOperandList = IOL; 24 let AsmString = asmstr; 25 let Itinerary = itin; 26} 27 28// RR Format 29class RRForm<bits<11> opcode, dag OOL, dag IOL, string asmstr, 30 InstrItinClass itin, list<dag> pattern> 31 : SPUInstr<OOL, IOL, asmstr, itin> { 32 bits<7> RA; 33 bits<7> RB; 34 bits<7> RT; 35 36 let Pattern = pattern; 37 38 let Inst{0-10} = opcode; 39 let Inst{11-17} = RB; 40 let Inst{18-24} = RA; 41 let Inst{25-31} = RT; 42} 43 44let RB = 0 in { 45 // RR Format, where RB is zeroed (dont care): 46 class RRForm_1<bits<11> opcode, dag OOL, dag IOL, string asmstr, 47 InstrItinClass itin, list<dag> pattern> 48 : RRForm<opcode, OOL, IOL, asmstr, itin, pattern> 49 { } 50 51 let RA = 0 in { 52 // RR Format, where RA and RB are zeroed (dont care): 53 // Used for reads from status control registers (see FPSCRRr32) 54 class RRForm_2<bits<11> opcode, dag OOL, dag IOL, string asmstr, 55 InstrItinClass itin, list<dag> pattern> 56 : RRForm<opcode, OOL, IOL, asmstr, itin, pattern> 57 { } 58 } 59} 60 61let RT = 0 in { 62 // RR Format, where RT is zeroed (don't care), or as the instruction handbook 63 // says, "RT is a false target." Used in "Halt if" instructions 64 class RRForm_3<bits<11> opcode, dag OOL, dag IOL, string asmstr, 65 InstrItinClass itin, list<dag> pattern> 66 : RRForm<opcode, OOL, IOL, asmstr, itin, pattern> 67 { } 68} 69 70// RRR Format 71class RRRForm<bits<4> opcode, dag OOL, dag IOL, string asmstr, 72 InstrItinClass itin, list<dag> pattern> 73 : SPUInstr<OOL, IOL, asmstr, itin> 74{ 75 bits<7> RA; 76 bits<7> RB; 77 bits<7> RC; 78 bits<7> RT; 79 80 let Pattern = pattern; 81 82 let Inst{0-3} = opcode; 83 let Inst{4-10} = RT; 84 let Inst{11-17} = RB; 85 let Inst{18-24} = RA; 86 let Inst{25-31} = RC; 87} 88 89// RI7 Format 90class RI7Form<bits<11> opcode, dag OOL, dag IOL, string asmstr, 91 InstrItinClass itin, list<dag> pattern> 92 : SPUInstr<OOL, IOL, asmstr, itin> 93{ 94 bits<7> i7; 95 bits<7> RA; 96 bits<7> RT; 97 98 let Pattern = pattern; 99 100 let Inst{0-10} = opcode; 101 let Inst{11-17} = i7; 102 let Inst{18-24} = RA; 103 let Inst{25-31} = RT; 104} 105 106// CVTIntFp Format 107class CVTIntFPForm<bits<10> opcode, dag OOL, dag IOL, string asmstr, 108 InstrItinClass itin, list<dag> pattern> 109 : SPUInstr<OOL, IOL, asmstr, itin> 110{ 111 bits<7> RA; 112 bits<7> RT; 113 114 let Pattern = pattern; 115 116 let Inst{0-9} = opcode; 117 let Inst{10-17} = 0; 118 let Inst{18-24} = RA; 119 let Inst{25-31} = RT; 120} 121 122let RA = 0 in { 123 class BICondForm<bits<11> opcode, dag OOL, dag IOL, string asmstr, list<dag> pattern> 124 : RRForm<opcode, OOL, IOL, asmstr, BranchResolv, pattern> 125 { } 126 127 let RT = 0 in { 128 // Branch instruction format (without D/E flag settings) 129 class BRForm<bits<11> opcode, dag OOL, dag IOL, string asmstr, 130 InstrItinClass itin, list<dag> pattern> 131 : RRForm<opcode, OOL, IOL, asmstr, itin, pattern> 132 { } 133 134 class BIForm<bits<11> opcode, string asmstr, list<dag> pattern> 135 : RRForm<opcode, (outs), (ins R32C:$func), asmstr, BranchResolv, 136 pattern> 137 { } 138 139 let RB = 0 in { 140 // Return instruction (bi, branch indirect), RA is zero (LR): 141 class RETForm<string asmstr, list<dag> pattern> 142 : BRForm<0b00010101100, (outs), (ins), asmstr, BranchResolv, 143 pattern> 144 { } 145 } 146 } 147} 148 149// Branch indirect external data forms: 150class BISLEDForm<bits<2> DE_flag, string asmstr, list<dag> pattern> 151 : SPUInstr<(outs), (ins indcalltarget:$func), asmstr, BranchResolv> 152{ 153 bits<7> Rcalldest; 154 155 let Pattern = pattern; 156 157 let Inst{0-10} = 0b11010101100; 158 let Inst{11} = 0; 159 let Inst{12-13} = DE_flag; 160 let Inst{14-17} = 0b0000; 161 let Inst{18-24} = Rcalldest; 162 let Inst{25-31} = 0b0000000; 163} 164 165// RI10 Format 166class RI10Form<bits<8> opcode, dag OOL, dag IOL, string asmstr, 167 InstrItinClass itin, list<dag> pattern> 168 : SPUInstr<OOL, IOL, asmstr, itin> 169{ 170 bits<10> i10; 171 bits<7> RA; 172 bits<7> RT; 173 174 let Pattern = pattern; 175 176 let Inst{0-7} = opcode; 177 let Inst{8-17} = i10; 178 let Inst{18-24} = RA; 179 let Inst{25-31} = RT; 180} 181 182// RI10 Format, where the constant is zero (or effectively ignored by the 183// SPU) 184let i10 = 0 in { 185 class RI10Form_1<bits<8> opcode, dag OOL, dag IOL, string asmstr, 186 InstrItinClass itin, list<dag> pattern> 187 : RI10Form<opcode, OOL, IOL, asmstr, itin, pattern> 188 { } 189} 190 191// RI10 Format, where RT is ignored. 192// This format is used primarily by the Halt If ... Immediate set of 193// instructions 194let RT = 0 in { 195 class RI10Form_2<bits<8> opcode, dag OOL, dag IOL, string asmstr, 196 InstrItinClass itin, list<dag> pattern> 197 : RI10Form<opcode, OOL, IOL, asmstr, itin, pattern> 198 { } 199} 200 201// RI16 Format 202class RI16Form<bits<9> opcode, dag OOL, dag IOL, string asmstr, 203 InstrItinClass itin, list<dag> pattern> 204 : SPUInstr<OOL, IOL, asmstr, itin> 205{ 206 bits<16> i16; 207 bits<7> RT; 208 209 let Pattern = pattern; 210 211 let Inst{0-8} = opcode; 212 let Inst{9-24} = i16; 213 let Inst{25-31} = RT; 214} 215 216// Specialized version of the RI16 Format for unconditional branch relative and 217// branch absolute, branch and set link. Note that for branch and set link, the 218// link register doesn't have to be $lr, but this is actually hard coded into 219// the instruction pattern. 220 221let RT = 0 in { 222 class UncondBranch<bits<9> opcode, dag OOL, dag IOL, string asmstr, 223 list<dag> pattern> 224 : RI16Form<opcode, OOL, IOL, asmstr, BranchResolv, pattern> 225 { } 226 227 class BranchSetLink<bits<9> opcode, dag OOL, dag IOL, string asmstr, 228 list<dag> pattern> 229 : RI16Form<opcode, OOL, IOL, asmstr, BranchResolv, pattern> 230 { } 231} 232 233//===----------------------------------------------------------------------===// 234// Specialized versions of RI16: 235//===----------------------------------------------------------------------===// 236 237// RI18 Format 238class RI18Form<bits<7> opcode, dag OOL, dag IOL, string asmstr, 239 InstrItinClass itin, list<dag> pattern> 240 : SPUInstr<OOL, IOL, asmstr, itin> 241{ 242 bits<18> i18; 243 bits<7> RT; 244 245 let Pattern = pattern; 246 247 let Inst{0-6} = opcode; 248 let Inst{7-24} = i18; 249 let Inst{25-31} = RT; 250} 251 252//===----------------------------------------------------------------------===// 253// Instruction formats for intrinsics: 254//===----------------------------------------------------------------------===// 255 256// RI10 Format for v8i16 intrinsics 257class RI10_Int_v8i16<bits<8> opcode, string opc, InstrItinClass itin, 258 Intrinsic IntID> : 259 RI10Form<opcode, (outs VECREG:$rT), (ins s10imm:$val, VECREG:$rA), 260 !strconcat(opc, " $rT, $rA, $val"), itin, 261 [(set (v8i16 VECREG:$rT), (IntID (v8i16 VECREG:$rA), 262 i16ImmSExt10:$val))] >; 263 264class RI10_Int_v4i32<bits<8> opcode, string opc, InstrItinClass itin, 265 Intrinsic IntID> : 266 RI10Form<opcode, (outs VECREG:$rT), (ins s10imm:$val, VECREG:$rA), 267 !strconcat(opc, " $rT, $rA, $val"), itin, 268 [(set (v4i32 VECREG:$rT), (IntID (v4i32 VECREG:$rA), 269 i32ImmSExt10:$val))] >; 270 271// RR Format for v8i16 intrinsics 272class RR_Int_v8i16<bits<11> opcode, string opc, InstrItinClass itin, 273 Intrinsic IntID> : 274 RRForm<opcode, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 275 !strconcat(opc, " $rT, $rA, $rB"), itin, 276 [(set (v8i16 VECREG:$rT), (IntID (v8i16 VECREG:$rA), 277 (v8i16 VECREG:$rB)))] >; 278 279// RR Format for v4i32 intrinsics 280class RR_Int_v4i32<bits<11> opcode, string opc, InstrItinClass itin, 281 Intrinsic IntID> : 282 RRForm<opcode, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), 283 !strconcat(opc, " $rT, $rA, $rB"), itin, 284 [(set (v4i32 VECREG:$rT), (IntID (v4i32 VECREG:$rA), 285 (v4i32 VECREG:$rB)))] >; 286 287//===----------------------------------------------------------------------===// 288// Pseudo instructions, like call frames: 289//===----------------------------------------------------------------------===// 290 291class Pseudo<dag OOL, dag IOL, string asmstr, list<dag> pattern> 292 : SPUInstr<OOL, IOL, asmstr, NoItinerary> { 293 let OutOperandList = OOL; 294 let InOperandList = IOL; 295 let AsmString = asmstr; 296 let Pattern = pattern; 297 let Inst{31-0} = 0; 298} 299 300//===----------------------------------------------------------------------===// 301// Branch hint formats 302//===----------------------------------------------------------------------===// 303// For hbrr and hbra 304class HBI16Form<bits<7> opcode, dag IOL, string asmstr> 305 : Instruction { 306 field bits<32> Inst; 307 bits<16>i16; 308 bits<9>RO; 309 310 let Namespace = "SPU"; 311 let InOperandList = IOL; 312 let OutOperandList = (outs); //no output 313 let AsmString = asmstr; 314 let Itinerary = BranchHints; 315 316 let Inst{0-6} = opcode; 317 let Inst{7-8} = RO{8-7}; 318 let Inst{9-24} = i16; 319 let Inst{25-31} = RO{6-0}; 320} 321