Adding disassembler to the MicroBlaze backend.
[oota-llvm.git] / lib / Target / MBlaze / MBlazeInstrInfo.td
index c10f4a88064c24ad2b72abcced8ec55a1976dabc..277fb6fc0acede6e7ef4ca6d664a8ba3f1a2358f 100644 (file)
@@ -203,6 +203,11 @@ class LogicI<bits<6> op, string instr_asm, SDNode OpNode> :
                 [(set GPR:$dst, (OpNode GPR:$b, immZExt16:$c))],
                 IIAlu>;
 
+class PatCmp<bits<6> op, bits<11> flags, string instr_asm> :
+             TA<op, flags, (outs GPR:$dst), (ins GPR:$b, GPR:$c),
+                !strconcat(instr_asm, "   $dst, $b, $c"),
+                 [], IIAlu>;
+
 //===----------------------------------------------------------------------===//
 // Memory Access Instructions
 //===----------------------------------------------------------------------===//
@@ -211,6 +216,11 @@ class LoadM<bits<6> op, string instr_asm, PatFrag OpNode> :
                !strconcat(instr_asm, "   $dst, $addr"),
                [(set (i32 GPR:$dst), (OpNode xaddr:$addr))], IILoad>;
 
+class LoadW<bits<6> op, bits<11> flags, string instr_asm> :
+            TA<op, flags, (outs GPR:$dst), (ins memrr:$addr),
+               !strconcat(instr_asm, "   $dst, $addr"),
+               [], IILoad>;
+
 class LoadMI<bits<6> op, string instr_asm, PatFrag OpNode> :
              TBR<op, (outs GPR:$dst), (ins memri:$addr),
                  !strconcat(instr_asm, "   $dst, $addr"),
@@ -221,6 +231,11 @@ class StoreM<bits<6> op, string instr_asm, PatFrag OpNode> :
                 !strconcat(instr_asm, "   $dst, $addr"),
                 [(OpNode (i32 GPR:$dst), xaddr:$addr)], IIStore>;
 
+class StoreW<bits<6> op, bits<11> flags, string instr_asm> :
+             TA<op, flags, (outs), (ins GPR:$dst, memrr:$addr),
+                !strconcat(instr_asm, "   $dst, $addr"),
+                [], IIStore>;
+
 class StoreMI<bits<6> op, string instr_asm, PatFrag OpNode> :
               TBR<op, (outs), (ins GPR:$dst, memri:$addr),
                   !strconcat(instr_asm, "   $dst, $addr"),
@@ -231,10 +246,11 @@ class StoreMI<bits<6> op, string instr_asm, PatFrag OpNode> :
 //===----------------------------------------------------------------------===//
 class Branch<bits<6> op, bits<5> br, bits<11> flags, string instr_asm> :
              TA<op, flags, (outs), (ins GPR:$target),
-                 !strconcat(instr_asm, "   $target"),
-                 [], IIBranch> {
+                !strconcat(instr_asm, "   $target"),
+                [], IIBranch> {
   let rd = 0x0;
   let ra = br;
+  let Form = FCCR;
 }
 
 class BranchI<bits<6> op, bits<5> br, string instr_asm> :
@@ -243,25 +259,26 @@ class BranchI<bits<6> op, bits<5> br, string instr_asm> :
                  [], IIBranch> {
   let rd = 0;
   let ra = br;
+  let Form = FCCI;
 }
 
 //===----------------------------------------------------------------------===//
 // Branch and Link Instructions
 //===----------------------------------------------------------------------===//
 class BranchL<bits<6> op, bits<5> br, bits<11> flags, string instr_asm> :
-              TA<op, flags, (outs), (ins GPR:$target),
-                 !strconcat(instr_asm, "   r15, $target"),
+              TA<op, flags, (outs), (ins GPR:$link, GPR:$target),
+                 !strconcat(instr_asm, "   $link, $target"),
                  [], IIBranch> {
-  let rd = 15;
   let ra = br;
+  let Form = FRCR;
 }
 
 class BranchLI<bits<6> op, bits<5> br, string instr_asm> :
-               TB<op, (outs), (ins calltarget:$target),
-                  !strconcat(instr_asm, "   r15, $target"),
+               TB<op, (outs), (ins GPR:$link, calltarget:$target),
+                  !strconcat(instr_asm, "   $link, $target"),
                   [], IIBranch> {
-  let rd = 15;
   let ra = br;
+  let Form = FRCI;
 }
 
 //===----------------------------------------------------------------------===//
@@ -274,6 +291,7 @@ class BranchC<bits<6> op, bits<5> br, bits<11> flags, string instr_asm,
                  !strconcat(instr_asm, "   $a, $b, $offset"),
                  [], IIBranch> {
   let rd = br;
+  let Form = FCRR;
 }
 
 class BranchCI<bits<6> op, bits<5> br, string instr_asm, PatFrag cond_op> :
@@ -281,6 +299,7 @@ class BranchCI<bits<6> op, bits<5> br, string instr_asm, PatFrag cond_op> :
                   !strconcat(instr_asm, "   $a, $offset"),
                   [], IIBranch> {
   let rd = br;
+  let Form = FCRI;
 }
 
 //===----------------------------------------------------------------------===//
@@ -295,6 +314,9 @@ let isCommutable = 1, isAsCheapAsAMove = 1 in {
   def AND    :  Logic<0x21, 0x000, "and    ", and>;
   def OR     :  Logic<0x20, 0x000, "or     ", or>;
   def XOR    :  Logic<0x22, 0x000, "xor    ", xor>;
+  def PCMPBF : PatCmp<0x20, 0x400, "pcmpbf ">;
+  def PCMPEQ : PatCmp<0x23, 0x400, "pcmpeq ">;
+  def PCMPNE : PatCmp<0x22, 0x400, "pcmpne ">;
 }
 
 let isAsCheapAsAMove = 1 in {
@@ -364,7 +386,10 @@ let Predicates=[HasMul] in {
 let canFoldAsLoad = 1, isReMaterializable = 1 in {
   def LBU  :  LoadM<0x30, "lbu    ", zextloadi8>;
   def LHU  :  LoadM<0x31, "lhu    ", zextloadi16>;
-  def LW   :  LoadM<0x32, "lw     ", load>;
+
+  def LW   :  LoadW<0x32, 0x0, "lw     ">;
+  def LWR  :  LoadW<0x32, 0x2, "lwr    ">;
+  def LWX  :  LoadW<0x32, 0x4, "lwx    ">;
 
   def LBUI : LoadMI<0x38, "lbui   ", zextloadi8>;
   def LHUI : LoadMI<0x39, "lhui   ", zextloadi16>;
@@ -373,7 +398,10 @@ let canFoldAsLoad = 1, isReMaterializable = 1 in {
 
   def SB  :  StoreM<0x34, "sb     ", truncstorei8>;
   def SH  :  StoreM<0x35, "sh     ", truncstorei16>;
-  def SW  :  StoreM<0x36, "sw     ", store>;
+
+  def SW  :  StoreW<0x36, 0x0, "sw     ">;
+  def SWR :  StoreW<0x36, 0x2, "swr    ">;
+  def SWX :  StoreW<0x36, 0x4, "swx    ">;
 
   def SBI : StoreMI<0x3C, "sbi    ", truncstorei8>;
   def SHI : StoreMI<0x3D, "shi    ", truncstorei16>;
@@ -383,13 +411,12 @@ let canFoldAsLoad = 1, isReMaterializable = 1 in {
 // MBlaze branch instructions
 //===----------------------------------------------------------------------===//
 
-let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1, 
-    Form = FI in {
+let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
   def BRI    :  BranchI<0x2E, 0x00, "bri    ">;
   def BRAI   :  BranchI<0x2E, 0x08, "brai   ">;
 }
 
-let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, Form = FRI in {
+let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
   def BEQI   : BranchCI<0x2F, 0x00, "beqi   ", seteq>;
   def BNEI   : BranchCI<0x2F, 0x01, "bnei   ", setne>;
   def BLTI   : BranchCI<0x2F, 0x02, "blti   ", setlt>;
@@ -399,13 +426,12 @@ let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, Form = FRI in {
 }
 
 let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1,
-    isBarrier = 1, Form = FR in {
+    isBarrier = 1 in {
   def BR     :   Branch<0x26, 0x00, 0x000, "br     ">;
   def BRA    :   Branch<0x26, 0x08, 0x000, "bra    ">;
 }
 
-let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1,
-    Form = FRR in {
+let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1 in {
   def BEQ    :  BranchC<0x27, 0x00, 0x000, "beq    ", seteq>;
   def BNE    :  BranchC<0x27, 0x01, 0x000, "bne    ", setne>;
   def BLT    :  BranchC<0x27, 0x02, 0x000, "blt    ", setlt>;
@@ -415,13 +441,12 @@ let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1,
 }
 
 let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1,
-    isBarrier = 1, Form = FI in {
+    isBarrier = 1 in {
   def BRID   :  BranchI<0x2E, 0x10, "brid   ">;
   def BRAID  :  BranchI<0x2E, 0x18, "braid  ">;
 }
 
-let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1,
-    Form = FRI in {
+let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1 in {
   def BEQID  : BranchCI<0x2F, 0x10, "beqid  ", seteq>;
   def BNEID  : BranchCI<0x2F, 0x11, "bneid  ", setne>;
   def BLTID  : BranchCI<0x2F, 0x12, "bltid  ", setlt>;
@@ -430,14 +455,14 @@ let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1,
   def BGEID  : BranchCI<0x2F, 0x15, "bgeid  ", setge>;
 }
 
-let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, Form = FR,
+let isBranch = 1, isIndirectBranch = 1, isTerminator = 1,
     hasDelaySlot = 1, hasCtrlDep = 1, isBarrier = 1 in {
   def BRD    :   Branch<0x26, 0x10, 0x000, "brd    ">;
   def BRAD   :   Branch<0x26, 0x18, 0x000, "brad   ">;
 }
 
 let isBranch = 1, isIndirectBranch = 1, isTerminator = 1,
-    hasDelaySlot = 1, hasCtrlDep = 1, Form = FRR in {
+    hasDelaySlot = 1, hasCtrlDep = 1 in {
   def BEQD   :  BranchC<0x27, 0x10, 0x000, "beqd   ", seteq>;
   def BNED   :  BranchC<0x27, 0x11, 0x000, "bned   ", setne>;
   def BLTD   :  BranchC<0x27, 0x12, 0x000, "bltd   ", setlt>;
@@ -446,7 +471,7 @@ let isBranch = 1, isIndirectBranch = 1, isTerminator = 1,
   def BGED   :  BranchC<0x27, 0x15, 0x000, "bged   ", setge>;
 }
 
-let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isBarrier = 1, Form = FI,
+let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isBarrier = 1,
     Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12],
     Uses = [R1,R5,R6,R7,R8,R9,R10] in {
   def BRLID  : BranchLI<0x2E, 0x14, "brlid  ">;
@@ -454,7 +479,7 @@ let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isBarrier = 1, Form = FI,
 }
 
 let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isIndirectBranch = 1,
-    isBarrier = 1, Form = FR,
+    isBarrier = 1,
     Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12],
     Uses = [R1,R5,R6,R7,R8,R9,R10] in {
   def BRLD   : BranchL<0x26, 0x14, 0x000, "brld   ">;
@@ -462,10 +487,34 @@ let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isIndirectBranch = 1,
 }
 
 let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1,
-    hasCtrlDep=1, rd=0x10, imm16=0x8, Form=FR in {
-  def RTSD   : TB<0x2D, (outs), (ins GPR:$target),
-                  "rtsd      $target, 8",
-                  [(MBlazeRet GPR:$target)],
+    hasCtrlDep=1, rd=0x10, Form=FCRI in {
+  def RTSD   : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm),
+                  "rtsd      $target, $imm",
+                  [], 
+                  IIBranch>;
+}
+
+let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1,
+    hasCtrlDep=1, rd=0x11, Form=FCRI in {
+  def RTID   : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm),
+                  "rtsd      $target, $imm",
+                  [], 
+                  IIBranch>;
+}
+
+let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1,
+    hasCtrlDep=1, rd=0x12, Form=FCRI in {
+  def RTBD   : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm),
+                  "rtsd      $target, $imm",
+                  [], 
+                  IIBranch>;
+}
+
+let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1,
+    hasCtrlDep=1, rd=0x14, Form=FCRI in {
+  def RTED   : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm),
+                  "rtsd      $target, $imm",
+                  [], 
                   IIBranch>;
 }
 
@@ -474,7 +523,7 @@ let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1,
 //===----------------------------------------------------------------------===//
 
 let neverHasSideEffects = 1 in {
-  def NOP :  MBlazeInst< 0x20, FRRR, (outs), (ins), "nop    ", [], IIAlu>;
+  def NOP :  MBlazeInst< 0x20, FC, (outs), (ins), "nop    ", [], IIAlu>;
 }
 
 let usesCustomInserter = 1 in {
@@ -519,6 +568,38 @@ let opcode=0x08 in {
                     [(set GPR:$dst, iaddr:$addr)], IIAlu>;
 }
 
+//===----------------------------------------------------------------------===//
+// Misc. instructions
+//===----------------------------------------------------------------------===//
+def MFS : MBlazeInst<0x25, FPseudo, (outs), (ins), "mfs", [], IIAlu> {
+}
+
+def MTS : MBlazeInst<0x25, FPseudo, (outs), (ins), "mts", [], IIAlu> {
+}
+
+def MSRSET : MBlazeInst<0x25, FPseudo, (outs), (ins), "msrset", [], IIAlu> {
+}
+
+def MSRCLR : MBlazeInst<0x25, FPseudo, (outs), (ins), "msrclr", [], IIAlu> {
+}
+
+let rd=0x0, Form=FCRR in {
+  def WDC  : TA<0x24, 0x64, (outs), (ins GPR:$a, GPR:$b), 
+                "wdc       $a, $b", [], IIAlu>;
+  def WDCF : TA<0x24, 0x74, (outs), (ins GPR:$a, GPR:$b),
+                "wdc.flush $a, $b", [], IIAlu>;
+  def WDCC : TA<0x24, 0x66, (outs), (ins GPR:$a, GPR:$b),
+                "wdc.clear $a, $b", [], IIAlu>;
+  def WIC  : TA<0x24, 0x68, (outs), (ins GPR:$a, GPR:$b),
+                "wic       $a, $b", [], IIAlu>;
+}
+
+def BRK  :  Branch<0x26, 0x0C, 0x000, "brk    ">;
+def BRKI : BranchI<0x2E, 0x0C, "brki   ">;
+
+def IMM : MBlazeInst<0x2C, FCCI, (outs), (ins simm16:$imm), 
+                     "imm       $imm", [], IIAlu>;
+
 //===----------------------------------------------------------------------===//
 //  Arbitrary patterns that map to one or more instructions
 //===----------------------------------------------------------------------===//
@@ -536,9 +617,14 @@ def : Pat<(sext_inreg GPR:$src, i16), (SEXT16 GPR:$src)>;
 def : Pat<(sext_inreg GPR:$src, i8),  (SEXT8 GPR:$src)>;
 
 // Call
-def : Pat<(MBlazeJmpLink (i32 tglobaladdr:$dst)), (BRLID tglobaladdr:$dst)>;
-def : Pat<(MBlazeJmpLink (i32 texternalsym:$dst)),(BRLID texternalsym:$dst)>;
-def : Pat<(MBlazeJmpLink GPR:$dst), (BRLD GPR:$dst)>;
+def : Pat<(MBlazeJmpLink (i32 tglobaladdr:$dst)),
+          (BRLID (i32 R15), tglobaladdr:$dst)>;
+
+def : Pat<(MBlazeJmpLink (i32 texternalsym:$dst)),
+          (BRLID (i32 R15), texternalsym:$dst)>;
+
+def : Pat<(MBlazeJmpLink GPR:$dst),
+          (BRLD (i32 R15), GPR:$dst)>;
 
 // Shift Instructions
 def : Pat<(shl GPR:$L, GPR:$R), (ShiftL GPR:$L, GPR:$R)>;
@@ -613,6 +699,9 @@ def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R),
                     (i32 GPR:$T), (i32 GPR:$F), SETULE),
           (Select_CC GPR:$T, GPR:$F, (CMPU GPR:$L, GPR:$R), 6)>;
 
+// Ret instructions
+def : Pat<(MBlazeRet GPR:$target), (RTSD GPR:$target, 0x8)>;
+
 // BR instructions
 def : Pat<(br bb:$T), (BRID bb:$T)>;
 def : Pat<(brind GPR:$T), (BRD GPR:$T)>;
@@ -660,6 +749,10 @@ def : Pat<(extloadi16 iaddr:$src), (i32 (LHUI iaddr:$src))>;
 def : Pat<(extloadi8  xaddr:$src), (i32 (LBU xaddr:$src))>;
 def : Pat<(extloadi16 xaddr:$src), (i32 (LHU xaddr:$src))>;
 
+// 32-bit load and store
+def : Pat<(store (i32 GPR:$dst), xaddr:$addr), (SW GPR:$dst, xaddr:$addr)>;
+def : Pat<(load xaddr:$addr), (i32 (LW xaddr:$addr))>;
+
 // Peepholes
 def : Pat<(store (i32 0), iaddr:$dst), (SWI (i32 R0), iaddr:$dst)>;