Home | History | Annotate | Download | only in CellSPU
      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 
     17 class 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
     29 class 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 
     44 let 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 
     61 let 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
     71 class 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
     90 class 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
    107 class 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 
    122 let 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:
    150 class 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
    166 class 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)
    184 let 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
    194 let 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
    202 class 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 
    221 let 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
    238 class 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
    257 class 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 
    264 class 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
    272 class 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
    280 class 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 
    291 class 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
    304 class 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