Support for microMIPS control instructions.
authorZoran Jovanovic <zoran.jovanovic@imgtec.com>
Thu, 19 Dec 2013 16:25:00 +0000 (16:25 +0000)
committerZoran Jovanovic <zoran.jovanovic@imgtec.com>
Thu, 19 Dec 2013 16:25:00 +0000 (16:25 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197696 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MicroMipsInstrFormats.td
lib/Target/Mips/MicroMipsInstrInfo.td
lib/Target/Mips/MipsInstrFormats.td
lib/Target/Mips/MipsInstrInfo.td
test/MC/Mips/micromips-control-instructions.s [new file with mode: 0644]

index b1c3fb808d33ca2766f3f1f48efe6331fbabf6ab..acbfd4db15def16c58f8404742267f939870da0f 100644 (file)
@@ -276,6 +276,66 @@ class BGEZAL_FM_MM<bits<5> funct> : MMArch {
   let Inst{15-0}  = offset;
 }
 
+class SYNC_FM_MM : MMArch {
+  bits<5> stype;
+
+  bits<32> Inst;
+
+  let Inst{31-26} = 0x00;
+  let Inst{25-21} = 0x0;
+  let Inst{20-16} = stype;
+  let Inst{15-6}  = 0x1ad;
+  let Inst{5-0}   = 0x3c;
+}
+
+class BRK_FM_MM : MMArch {
+  bits<10> code_1;
+  bits<10> code_2;
+  bits<32> Inst;
+  let Inst{31-26} = 0x0;
+  let Inst{25-16} = code_1;
+  let Inst{15-6}  = code_2;
+  let Inst{5-0}   = 0x07;
+}
+
+class SYS_FM_MM : MMArch {
+  bits<10> code_;
+  bits<32> Inst;
+  let Inst{31-26} = 0x0;
+  let Inst{25-16} = code_;
+  let Inst{15-6}  = 0x22b;
+  let Inst{5-0}   = 0x3c;
+}
+
+class WAIT_FM_MM : MMArch {
+  bits<32> Inst;
+
+  let Inst{31-26} = 0x00;
+  let Inst{25-16} = 0x00;
+  let Inst{15-6}  = 0x24d;
+  let Inst{5-0}   = 0x3c;
+}
+
+class ER_FM_MM<bits<10> funct> : MMArch {
+  bits<32> Inst;
+
+  let Inst{31-26} = 0x00;
+  let Inst{25-16} = 0x00;
+  let Inst{15-6}  = funct;
+  let Inst{5-0}   = 0x3c;
+}
+
+class EI_FM_MM<bits<10> funct> : MMArch {
+  bits<32> Inst;
+  bits<5> rt;
+
+  let Inst{31-26} = 0x00;
+  let Inst{25-21} = 0x00;
+  let Inst{20-16} = rt;
+  let Inst{15-6}  = funct;
+  let Inst{5-0}   = 0x3c;
+}
+
 class TEQ_FM_MM<bits<6> funct> : MMArch {
   bits<5> rs;
   bits<5> rt;
index 76463892faed17473e8c7cb95bc718bbaf760eaa..4f068dfe15c86ff244b7a93d9996640a1c1dcec9 100644 (file)
@@ -213,6 +213,16 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
   def BLTZAL_MM : MMRel, BGEZAL_FT<"bltzal", brtarget_mm, GPR32Opnd>,
                   BGEZAL_FM_MM<0x01>;
 
+  /// Control Instructions
+  def SYNC_MM    : MMRel, SYNC_FT<"sync">, SYNC_FM_MM;
+  def BREAK_MM   : MMRel, BRK_FT<"break">, BRK_FM_MM;
+  def SYSCALL_MM : MMRel, SYS_FT<"syscall">, SYS_FM_MM;
+  def WAIT_MM    : MMRel, WAIT_FT<"wait">, WAIT_FM_MM;
+  def ERET_MM    : MMRel, ER_FT<"eret">, ER_FM_MM<0x3cd>;
+  def DERET_MM   : MMRel, ER_FT<"deret">, ER_FM_MM<0x38d>;
+  def EI_MM      : MMRel, DEI_FT<"ei", GPR32Opnd>, EI_FM_MM<0x15d>;
+  def DI_MM      : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM_MM<0x11d>;
+
   /// Trap Instructions
   def TEQ_MM  : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM_MM<0x0>;
   def TGE_MM  : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM_MM<0x08>;
index 737a018c67afc7f9759bfbec17024004eaf1837e..21ee605ac024cc68b010a62a352bcaf9d3534d74 100644 (file)
@@ -401,7 +401,7 @@ class BGEZAL_FM<bits<5> funct> : StdArch {
   let Inst{15-0}  = offset;
 }
 
-class SYNC_FM {
+class SYNC_FM : StdArch {
   bits<5> stype;
 
   bits<32> Inst;
@@ -479,11 +479,21 @@ class TEQI_FM<bits<5> funct> : StdArch {
   let Inst{20-16}   = funct;
   let Inst{15-0}  = imm16;
 }
+
+class WAIT_FM : StdArch {
+  bits<32> Inst;
+
+  let Inst{31-26} = 0x10;
+  let Inst{25}    = 1;
+  let Inst{24-6}  = 0;
+  let Inst{5-0}   = 0x20;
+}
+
 //===----------------------------------------------------------------------===//
 //  System calls format <op|code_|funct>
 //===----------------------------------------------------------------------===//
 
-class SYS_FM<bits<6> funct>
+class SYS_FM<bits<6> funct> : StdArch
 {
   bits<20> code_;
   bits<32> Inst;
@@ -496,7 +506,7 @@ class SYS_FM<bits<6> funct>
 //  Break instruction format <op|code_1|funct>
 //===----------------------------------------------------------------------===//
 
-class BRK_FM<bits<6> funct>
+class BRK_FM<bits<6> funct> : StdArch
 {
   bits<10> code_1;
   bits<10> code_2;
@@ -511,7 +521,7 @@ class BRK_FM<bits<6> funct>
 //  Exception return format <Cop0|1|0|funct>
 //===----------------------------------------------------------------------===//
 
-class ER_FM<bits<6> funct>
+class ER_FM<bits<6> funct> : StdArch
 {
   bits<32> Inst;
   let Inst{31-26} = 0x10;
@@ -525,7 +535,7 @@ class ER_FM<bits<6> funct>
 //  Enable/disable interrupt instruction format <Cop0|MFMC0|rt|12|0|sc|0|0>
 //===----------------------------------------------------------------------===//
 
-class EI_FM<bits<1> sc>
+class EI_FM<bits<1> sc> : StdArch
 {
   bits<32> Inst;
   bits<5> rt;
index 12bddf069937b7a5bcc084cc05d2117f3accabeb..641f37a6fa522e8eb14308166de935f235072adc 100644 (file)
@@ -643,36 +643,32 @@ class BAL_BR_Pseudo<Instruction RealInst> :
 // Syscall
 class SYS_FT<string opstr> :
   InstSE<(outs), (ins uimm20:$code_),
-         !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI>;
+         !strconcat(opstr, "\t$code_"), [], NoItinerary, FrmI, opstr>;
 // Break
 class BRK_FT<string opstr> :
   InstSE<(outs), (ins uimm10:$code_1, uimm10:$code_2),
-         !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary, FrmOther>;
+         !strconcat(opstr, "\t$code_1, $code_2"), [], NoItinerary,
+         FrmOther, opstr>;
 
 // (D)Eret
 class ER_FT<string opstr> :
   InstSE<(outs), (ins),
-         opstr, [], NoItinerary, FrmOther>;
+         opstr, [], NoItinerary, FrmOther, opstr>;
 
 // Interrupts
 class DEI_FT<string opstr, RegisterOperand RO> :
   InstSE<(outs RO:$rt), (ins),
-         !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther>;
+         !strconcat(opstr, "\t$rt"), [], NoItinerary, FrmOther, opstr>;
 
 // Wait
 class WAIT_FT<string opstr> :
-  InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther> {
-  let Inst{31-26} = 0x10;
-  let Inst{25}    = 1;
-  let Inst{24-6}  = 0;
-  let Inst{5-0}   = 0x20;
-}
+  InstSE<(outs), (ins), opstr, [], NoItinerary, FrmOther, opstr>;
 
 // Sync
 let hasSideEffects = 1 in
-class SYNC_FT :
+class SYNC_FT<string opstr> :
   InstSE<(outs), (ins i32imm:$stype), "sync $stype", [(MipsSync imm:$stype)],
-         NoItinerary, FrmOther>;
+         NoItinerary, FrmOther, opstr>;
 
 let hasSideEffects = 1 in
 class TEQ_FT<string opstr, RegisterOperand RO> :
@@ -984,7 +980,7 @@ def SWL : StoreLeftRight<"swl", MipsSWL, GPR32Opnd, IIStore>, LW_FM<0x2a>;
 def SWR : StoreLeftRight<"swr", MipsSWR, GPR32Opnd, IIStore>, LW_FM<0x2e>;
 }
 
-def SYNC : SYNC_FT, SYNC_FM;
+def SYNC : MMRel, SYNC_FT<"sync">, SYNC_FM;
 def TEQ : MMRel, TEQ_FT<"teq", GPR32Opnd>, TEQ_FM<0x34>;
 def TGE : MMRel, TEQ_FT<"tge", GPR32Opnd>, TEQ_FM<0x30>;
 def TGEU : MMRel, TEQ_FT<"tgeu", GPR32Opnd>, TEQ_FM<0x31>;
@@ -999,17 +995,17 @@ def TLTI : MMRel, TEQI_FT<"tlti", GPR32Opnd>, TEQI_FM<0xa>;
 def TTLTIU : MMRel, TEQI_FT<"tltiu", GPR32Opnd>, TEQI_FM<0xb>;
 def TNEI : MMRel, TEQI_FT<"tnei", GPR32Opnd>, TEQI_FM<0xe>;
 
-def BREAK : BRK_FT<"break">, BRK_FM<0xd>;
-def SYSCALL : SYS_FT<"syscall">, SYS_FM<0xc>;
+def BREAK : MMRel, BRK_FT<"break">, BRK_FM<0xd>;
+def SYSCALL : MMRel, SYS_FT<"syscall">, SYS_FM<0xc>;
 def TRAP : TrapBase<BREAK>;
 
-def ERET : ER_FT<"eret">, ER_FM<0x18>;
-def DERET : ER_FT<"deret">, ER_FM<0x1f>;
+def ERET : MMRel, ER_FT<"eret">, ER_FM<0x18>;
+def DERET : MMRel, ER_FT<"deret">, ER_FM<0x1f>;
 
-def EI : DEI_FT<"ei", GPR32Opnd>, EI_FM<1>;
-def DI : DEI_FT<"di", GPR32Opnd>, EI_FM<0>;
+def EI : MMRel, DEI_FT<"ei", GPR32Opnd>, EI_FM<1>;
+def DI : MMRel, DEI_FT<"di", GPR32Opnd>, EI_FM<0>;
 
-def WAIT : WAIT_FT<"wait">;
+def WAIT : MMRel, WAIT_FT<"wait">, WAIT_FM;
 
 /// Load-linked, Store-conditional
 let Predicates = [NotInMicroMips] in {
diff --git a/test/MC/Mips/micromips-control-instructions.s b/test/MC/Mips/micromips-control-instructions.s
new file mode 100644 (file)
index 0000000..07fd777
--- /dev/null
@@ -0,0 +1,57 @@
+# RUN: llvm-mc %s -triple=mipsel -show-encoding -mattr=micromips \
+# RUN: | FileCheck -check-prefix=CHECK-EL %s
+# RUN: llvm-mc %s -triple=mips -show-encoding -mattr=micromips \
+# RUN: | FileCheck -check-prefix=CHECK-EB %s
+# Check that the assembler can handle the documented syntax
+# for control instructions.
+#------------------------------------------------------------------------------
+# microMIPS Control Instructions
+#------------------------------------------------------------------------------
+# Little endian
+#------------------------------------------------------------------------------
+# CHECK-EL:    break                      # encoding: [0x00,0x00,0x07,0x00]
+# CHECK-EL:    break 7, 0                 # encoding: [0x07,0x00,0x07,0x00]
+# CHECK-EL:    break 7, 5                 # encoding: [0x07,0x00,0x47,0x01]
+# CHECK-EL:    syscall                    # encoding: [0x00,0x00,0xfc,0x8a]
+# CHECK-EL:    syscall 13396              # encoding: [0x54,0x00,0xfc,0x8a]
+# CHECK-EL:    eret                       # encoding: [0x00,0x00,0x7c,0xf3]
+# CHECK-EL:    deret                      # encoding: [0x00,0x00,0x7c,0xe3]
+# CHECK-EL:    di                         # encoding: [0x00,0x00,0x7c,0x47]
+# CHECK-EL:    di                         # encoding: [0x00,0x00,0x7c,0x47]
+# CHECK-EL:    di  $10                    # encoding: [0x0a,0x00,0x7c,0x47]
+# CHECK-EL:    ei                         # encoding: [0x00,0x00,0x7c,0x57]
+# CHECK-EL:    ei                         # encoding: [0x00,0x00,0x7c,0x57]
+# CHECK-EL:    ei  $10                    # encoding: [0x0a,0x00,0x7c,0x57]
+# CHECK-EL:    wait                       # encoding: [0x00,0x00,0x7c,0x93]
+#------------------------------------------------------------------------------
+# Big endian
+#------------------------------------------------------------------------------
+# CHECK-EB:   break                       # encoding: [0x00,0x00,0x00,0x07]
+# CHECK-EB:   break 7, 0                  # encoding: [0x00,0x07,0x00,0x07]
+# CHECK-EB:   break 7, 5                  # encoding: [0x00,0x07,0x01,0x47]
+# CHECK-EB:   syscall                     # encoding: [0x00,0x00,0x8a,0xfc]
+# CHECK-EB:   syscall 13396               # encoding: [0x00,0x54,0x8a,0xfc]
+# CHECK-EB:   eret                        # encoding: [0x00,0x00,0xf3,0x7c]
+# CHECK-EB:   deret                       # encoding: [0x00,0x00,0xe3,0x7c]
+# CHECK-EB:   di                          # encoding: [0x00,0x00,0x47,0x7c]
+# CHECK-EB:   di                          # encoding: [0x00,0x00,0x47,0x7c]
+# CHECK-EB:   di  $10                     # encoding: [0x00,0x0a,0x47,0x7c]
+# CHECK-EB:   ei                          # encoding: [0x00,0x00,0x57,0x7c]
+# CHECK-EB:   ei                          # encoding: [0x00,0x00,0x57,0x7c]
+# CHECK-EB:   ei  $10                     # encoding: [0x00,0x0a,0x57,0x7c]
+# CHECK-EB:   wait                        # encoding: [0x00,0x00,0x93,0x7c]
+
+    break
+    break 7
+    break 7,5
+    syscall
+    syscall 0x3454
+    eret
+    deret
+    di
+    di $0
+    di $10
+    ei
+    ei $0
+    ei $10
+    wait