//==== SPUInstrFormats.td - Cell SPU Instruction Formats ---*- tablegen -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // // Cell SPU instruction formats. Note that these are notationally similar to // PowerPC, like "A-Form". But the sizes of operands and fields differ. // This was kiped from the PPC instruction formats (seemed like a good idea...) class SPUInstr<dag OOL, dag IOL, string asmstr, InstrItinClass itin> : Instruction { field bits<32> Inst; let Namespace = "SPU"; let OutOperandList = OOL; let InOperandList = IOL; let AsmString = asmstr; let Itinerary = itin; } // RR Format class RRForm<bits<11> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : SPUInstr<OOL, IOL, asmstr, itin> { bits<7> RA; bits<7> RB; bits<7> RT; let Pattern = pattern; let Inst{0-10} = opcode; let Inst{11-17} = RB; let Inst{18-24} = RA; let Inst{25-31} = RT; } let RB = 0 in { // RR Format, where RB is zeroed (dont care): class RRForm_1<bits<11> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : RRForm<opcode, OOL, IOL, asmstr, itin, pattern> { } let RA = 0 in { // RR Format, where RA and RB are zeroed (dont care): // Used for reads from status control registers (see FPSCRRr32) class RRForm_2<bits<11> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : RRForm<opcode, OOL, IOL, asmstr, itin, pattern> { } } } let RT = 0 in { // RR Format, where RT is zeroed (don't care), or as the instruction handbook // says, "RT is a false target." Used in "Halt if" instructions class RRForm_3<bits<11> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : RRForm<opcode, OOL, IOL, asmstr, itin, pattern> { } } // RRR Format class RRRForm<bits<4> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : SPUInstr<OOL, IOL, asmstr, itin> { bits<7> RA; bits<7> RB; bits<7> RC; bits<7> RT; let Pattern = pattern; let Inst{0-3} = opcode; let Inst{4-10} = RT; let Inst{11-17} = RB; let Inst{18-24} = RA; let Inst{25-31} = RC; } // RI7 Format class RI7Form<bits<11> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : SPUInstr<OOL, IOL, asmstr, itin> { bits<7> i7; bits<7> RA; bits<7> RT; let Pattern = pattern; let Inst{0-10} = opcode; let Inst{11-17} = i7; let Inst{18-24} = RA; let Inst{25-31} = RT; } // CVTIntFp Format class CVTIntFPForm<bits<10> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : SPUInstr<OOL, IOL, asmstr, itin> { bits<7> RA; bits<7> RT; let Pattern = pattern; let Inst{0-9} = opcode; let Inst{10-17} = 0; let Inst{18-24} = RA; let Inst{25-31} = RT; } let RA = 0 in { class BICondForm<bits<11> opcode, dag OOL, dag IOL, string asmstr, list<dag> pattern> : RRForm<opcode, OOL, IOL, asmstr, BranchResolv, pattern> { } let RT = 0 in { // Branch instruction format (without D/E flag settings) class BRForm<bits<11> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : RRForm<opcode, OOL, IOL, asmstr, itin, pattern> { } class BIForm<bits<11> opcode, string asmstr, list<dag> pattern> : RRForm<opcode, (outs), (ins R32C:$func), asmstr, BranchResolv, pattern> { } let RB = 0 in { // Return instruction (bi, branch indirect), RA is zero (LR): class RETForm<string asmstr, list<dag> pattern> : BRForm<0b00010101100, (outs), (ins), asmstr, BranchResolv, pattern> { } } } } // Branch indirect external data forms: class BISLEDForm<bits<2> DE_flag, string asmstr, list<dag> pattern> : SPUInstr<(outs), (ins indcalltarget:$func), asmstr, BranchResolv> { bits<7> Rcalldest; let Pattern = pattern; let Inst{0-10} = 0b11010101100; let Inst{11} = 0; let Inst{12-13} = DE_flag; let Inst{14-17} = 0b0000; let Inst{18-24} = Rcalldest; let Inst{25-31} = 0b0000000; } // RI10 Format class RI10Form<bits<8> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : SPUInstr<OOL, IOL, asmstr, itin> { bits<10> i10; bits<7> RA; bits<7> RT; let Pattern = pattern; let Inst{0-7} = opcode; let Inst{8-17} = i10; let Inst{18-24} = RA; let Inst{25-31} = RT; } // RI10 Format, where the constant is zero (or effectively ignored by the // SPU) let i10 = 0 in { class RI10Form_1<bits<8> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : RI10Form<opcode, OOL, IOL, asmstr, itin, pattern> { } } // RI10 Format, where RT is ignored. // This format is used primarily by the Halt If ... Immediate set of // instructions let RT = 0 in { class RI10Form_2<bits<8> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : RI10Form<opcode, OOL, IOL, asmstr, itin, pattern> { } } // RI16 Format class RI16Form<bits<9> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : SPUInstr<OOL, IOL, asmstr, itin> { bits<16> i16; bits<7> RT; let Pattern = pattern; let Inst{0-8} = opcode; let Inst{9-24} = i16; let Inst{25-31} = RT; } // Specialized version of the RI16 Format for unconditional branch relative and // branch absolute, branch and set link. Note that for branch and set link, the // link register doesn't have to be $lr, but this is actually hard coded into // the instruction pattern. let RT = 0 in { class UncondBranch<bits<9> opcode, dag OOL, dag IOL, string asmstr, list<dag> pattern> : RI16Form<opcode, OOL, IOL, asmstr, BranchResolv, pattern> { } class BranchSetLink<bits<9> opcode, dag OOL, dag IOL, string asmstr, list<dag> pattern> : RI16Form<opcode, OOL, IOL, asmstr, BranchResolv, pattern> { } } //===----------------------------------------------------------------------===// // Specialized versions of RI16: //===----------------------------------------------------------------------===// // RI18 Format class RI18Form<bits<7> opcode, dag OOL, dag IOL, string asmstr, InstrItinClass itin, list<dag> pattern> : SPUInstr<OOL, IOL, asmstr, itin> { bits<18> i18; bits<7> RT; let Pattern = pattern; let Inst{0-6} = opcode; let Inst{7-24} = i18; let Inst{25-31} = RT; } //===----------------------------------------------------------------------===// // Instruction formats for intrinsics: //===----------------------------------------------------------------------===// // RI10 Format for v8i16 intrinsics class RI10_Int_v8i16<bits<8> opcode, string opc, InstrItinClass itin, Intrinsic IntID> : RI10Form<opcode, (outs VECREG:$rT), (ins s10imm:$val, VECREG:$rA), !strconcat(opc, " $rT, $rA, $val"), itin, [(set (v8i16 VECREG:$rT), (IntID (v8i16 VECREG:$rA), i16ImmSExt10:$val))] >; class RI10_Int_v4i32<bits<8> opcode, string opc, InstrItinClass itin, Intrinsic IntID> : RI10Form<opcode, (outs VECREG:$rT), (ins s10imm:$val, VECREG:$rA), !strconcat(opc, " $rT, $rA, $val"), itin, [(set (v4i32 VECREG:$rT), (IntID (v4i32 VECREG:$rA), i32ImmSExt10:$val))] >; // RR Format for v8i16 intrinsics class RR_Int_v8i16<bits<11> opcode, string opc, InstrItinClass itin, Intrinsic IntID> : RRForm<opcode, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), !strconcat(opc, " $rT, $rA, $rB"), itin, [(set (v8i16 VECREG:$rT), (IntID (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))] >; // RR Format for v4i32 intrinsics class RR_Int_v4i32<bits<11> opcode, string opc, InstrItinClass itin, Intrinsic IntID> : RRForm<opcode, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), !strconcat(opc, " $rT, $rA, $rB"), itin, [(set (v4i32 VECREG:$rT), (IntID (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))] >; //===----------------------------------------------------------------------===// // Pseudo instructions, like call frames: //===----------------------------------------------------------------------===// class Pseudo<dag OOL, dag IOL, string asmstr, list<dag> pattern> : SPUInstr<OOL, IOL, asmstr, NoItinerary> { let OutOperandList = OOL; let InOperandList = IOL; let AsmString = asmstr; let Pattern = pattern; let Inst{31-0} = 0; } //===----------------------------------------------------------------------===// // Branch hint formats //===----------------------------------------------------------------------===// // For hbrr and hbra class HBI16Form<bits<7> opcode, dag IOL, string asmstr> : Instruction { field bits<32> Inst; bits<16>i16; bits<9>RO; let Namespace = "SPU"; let InOperandList = IOL; let OutOperandList = (outs); //no output let AsmString = asmstr; let Itinerary = BranchHints; let Inst{0-6} = opcode; let Inst{7-8} = RO{8-7}; let Inst{9-24} = i16; let Inst{25-31} = RO{6-0}; }