Final patch that completes old JIT support for Mips:

-Fix binary codes and rename operands in .td files so that automatically
generated function MipsCodeEmitter::getBinaryCodeForInstr gives correct
encoding for instructions.
-Define new class FMem for instructions that access memory.
-Define new class FFRGPR for instructions that move data between GPR and
FPU general and control registers.
-Define custom encoder methods for memory operands, and also for size
operands of ext and ins instructions.
-Only static relocation model is currently implemented.

Patch by Sasa Stankovic

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142378 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/Mips/CMakeLists.txt b/lib/Target/Mips/CMakeLists.txt
index 1b4329b..71391f3 100644
--- a/lib/Target/Mips/CMakeLists.txt
+++ b/lib/Target/Mips/CMakeLists.txt
@@ -2,6 +2,7 @@
 
 llvm_tablegen(MipsGenRegisterInfo.inc -gen-register-info)
 llvm_tablegen(MipsGenInstrInfo.inc -gen-instr-info)
+llvm_tablegen(MipsGenCodeEmitter.inc -gen-emitter)
 llvm_tablegen(MipsGenAsmWriter.inc -gen-asm-writer)
 llvm_tablegen(MipsGenDAGISel.inc -gen-dag-isel)
 llvm_tablegen(MipsGenCallingConv.inc -gen-callingconv)
diff --git a/lib/Target/Mips/Makefile b/lib/Target/Mips/Makefile
index cc4a8ae..d72693c 100644
--- a/lib/Target/Mips/Makefile
+++ b/lib/Target/Mips/Makefile
@@ -13,7 +13,7 @@
 
 # Make sure that tblgen is run, first thing.
 BUILT_SOURCES = MipsGenRegisterInfo.inc MipsGenInstrInfo.inc \
-                MipsGenAsmWriter.inc \
+                MipsGenAsmWriter.inc MipsGenCodeEmitter.inc \
                 MipsGenDAGISel.inc MipsGenCallingConv.inc \
                 MipsGenSubtargetInfo.inc
 
diff --git a/lib/Target/Mips/MipsCodeEmitter.cpp b/lib/Target/Mips/MipsCodeEmitter.cpp
index 9220d9c..23fabe3 100644
--- a/lib/Target/Mips/MipsCodeEmitter.cpp
+++ b/lib/Target/Mips/MipsCodeEmitter.cpp
@@ -105,6 +105,9 @@
     unsigned getRelocation(const MachineInstr &MI,
                            const MachineOperand &MO) const;
 
+    unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const;
+    unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const;
+    unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const;
   };
 }
 
@@ -153,6 +156,28 @@
   return Mips::reloc_mips_lo;
 }
 
+unsigned MipsCodeEmitter::getMemEncoding(const MachineInstr &MI,
+                                          unsigned OpNo) const {
+  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
+  assert(MI.getOperand(OpNo).isReg());
+  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo)) << 16;
+  return
+    (getMachineOpValue(MI, MI.getOperand(OpNo+1)) & 0xFFFF) | RegBits;
+}
+
+unsigned MipsCodeEmitter::getSizeExtEncoding(const MachineInstr &MI,
+                                          unsigned OpNo) const {
+  // size is encoded as size-1.
+  return getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
+}
+
+unsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI,
+                                          unsigned OpNo) const {
+  // size is encoded as pos+size-1.
+  return getMachineOpValue(MI, MI.getOperand(OpNo-1)) +
+         getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
+}
+
 /// getMachineOpValue - Return binary encoding of operand. If the machine
 /// operand requires relocation, record the relocation and return zero.
 unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
@@ -238,8 +263,4 @@
   return new MipsCodeEmitter(TM, JCE);
 }
 
-unsigned MipsCodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const {
- // this function will be automatically generated by the CodeEmitterGenerator
- // using TableGen
- return 0;
-}
+#include "MipsGenCodeEmitter.inc"
diff --git a/lib/Target/Mips/MipsCondMov.td b/lib/Target/Mips/MipsCondMov.td
index 9c4798a..1a3f194 100644
--- a/lib/Target/Mips/MipsCondMov.td
+++ b/lib/Target/Mips/MipsCondMov.td
@@ -16,6 +16,8 @@
                    bits<6> func, string instr_asm> :
   FFR<0x11, func, fmt, (outs DRC:$fd), (ins DRC:$fs, CRC:$rt, DRC:$F),
       !strconcat(instr_asm, "\t$fd, $fs, $rt"), []> {
+  bits<5> rt;
+  let ft = rt;
   let Constraints = "$F = $fd";
 }
 
@@ -116,8 +118,8 @@
 def MOVT_I64 : CondMovFPInt<CPU64Regs, MipsCMovFP_T, 1, "movt">,
                Requires<[HasMips64]>;
 
-def MOVF_I   : CondMovFPInt<CPURegs, MipsCMovFP_F, 1, "movf">;
-def MOVF_I64 : CondMovFPInt<CPU64Regs, MipsCMovFP_F, 1, "movf">,
+def MOVF_I   : CondMovFPInt<CPURegs, MipsCMovFP_F, 0, "movf">;
+def MOVF_I64 : CondMovFPInt<CPU64Regs, MipsCMovFP_F, 0, "movf">,
                Requires<[HasMips64]>;
 
 def MOVT_S : CondMovFPFP<FGR32, MipsCMovFP_T, 16, 1, "movt.s">;
diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td
index 78846a2..62cee12 100644
--- a/lib/Target/Mips/MipsInstrFPU.td
+++ b/lib/Target/Mips/MipsInstrFPU.td
@@ -76,14 +76,16 @@
 // FP load.
 class FPLoad<bits<6> op, string opstr, PatFrag FOp, RegisterClass RC,
              Operand MemOpnd>:
-  FFI<op, (outs RC:$ft), (ins MemOpnd:$base),
-      !strconcat(opstr, "\t$ft, $base"), [(set RC:$ft, (FOp addr:$base))]>;
+  FMem<op, (outs RC:$ft), (ins MemOpnd:$addr),
+      !strconcat(opstr, "\t$ft, $addr"), [(set RC:$ft, (FOp addr:$addr))],
+      IILoad>;
 
 // FP store.
 class FPStore<bits<6> op, string opstr, PatFrag FOp, RegisterClass RC,
               Operand MemOpnd>:
-  FFI<op, (outs), (ins RC:$ft, MemOpnd:$base),
-      !strconcat(opstr, "\t$ft, $base"), [(store RC:$ft, addr:$base)]>;
+  FMem<op, (outs), (ins RC:$ft, MemOpnd:$addr),
+      !strconcat(opstr, "\t$ft, $addr"), [(store RC:$ft, addr:$addr)],
+      IIStore>;
 
 // Instructions that convert an FP value to 32-bit fixed point.
 multiclass FFR1_W_M<bits<6> funct, string opstr> {
@@ -158,22 +160,28 @@
 // stores, and moves between floating-point and integer registers.
 // When defining instructions, we reference all 32-bit registers,
 // regardless of register aliasing.
-let fd = 0 in {
-  /// Move Control Registers From/To CPU Registers
-  def CFC1  : FFR<0x11, 0x0, 0x2, (outs CPURegs:$rt), (ins CCR:$fs),
+
+class FFRGPR<bits<5> _fmt, dag outs, dag ins, string asmstr, list<dag> pattern>:
+             FFR<0x11, 0x0, _fmt, outs, ins, asmstr, pattern> {
+  bits<5> rt;
+  let ft = rt;
+  let fd = 0;
+}
+
+/// Move Control Registers From/To CPU Registers
+def CFC1  : FFRGPR<0x2, (outs CPURegs:$rt), (ins CCR:$fs),
                   "cfc1\t$rt, $fs", []>;
 
-  def CTC1  : FFR<0x11, 0x0, 0x6, (outs CCR:$rt), (ins CPURegs:$fs),
-                  "ctc1\t$fs, $rt", []>;
+def CTC1  : FFRGPR<0x6, (outs CCR:$fs), (ins CPURegs:$rt),
+                  "ctc1\t$rt, $fs", []>;
 
-  def MFC1  : FFR<0x11, 0x00, 0x00, (outs CPURegs:$rt), (ins FGR32:$fs),
+def MFC1  : FFRGPR<0x00, (outs CPURegs:$rt), (ins FGR32:$fs),
                   "mfc1\t$rt, $fs",
                   [(set CPURegs:$rt, (bitconvert FGR32:$fs))]>;
 
-  def MTC1  : FFR<0x11, 0x00, 0x04, (outs FGR32:$fs), (ins CPURegs:$rt),
+def MTC1  : FFRGPR<0x04, (outs FGR32:$fs), (ins CPURegs:$rt),
                   "mtc1\t$rt, $fs",
                   [(set FGR32:$fs, (bitconvert CPURegs:$rt))]>;
-}
 
 def FMOV_S   : FFR1<0x6, 16, "mov", "s", FGR32, FGR32>;
 def FMOV_D32 : FFR1<0x6, 17, "mov", "d", AFGR64, AFGR64>,
@@ -203,7 +211,7 @@
 }
 
 /// Floating-point Aritmetic
-defm FADD : FFR2P_M<0x10, "add", fadd, 1>;
+defm FADD : FFR2P_M<0x00, "add", fadd, 1>;
 defm FDIV : FFR2P_M<0x03, "div", fdiv>;
 defm FMUL : FFR2P_M<0x02, "mul", fmul, 1>;
 defm FSUB : FFR2P_M<0x01, "sub", fsub>;
@@ -218,12 +226,16 @@
 
 /// Floating Point Branch of False/True (Likely)
 let isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in
-  class FBRANCH<PatLeaf op, string asmstr> : FFI<0x11, (outs),
-        (ins brtarget:$dst), !strconcat(asmstr, "\t$dst"),
-        [(MipsFPBrcond op, bb:$dst)]>;
+  class FBRANCH<bits<1> nd, bits<1> tf, PatLeaf op, string asmstr> :
+      FFI<0x11, (outs), (ins brtarget:$dst), !strconcat(asmstr, "\t$dst"),
+        [(MipsFPBrcond op, bb:$dst)]> {
+  let Inst{20-18} = 0;
+  let Inst{17} = nd;
+  let Inst{16} = tf;
+}
 
-def BC1F  : FBRANCH<MIPS_BRANCH_F,  "bc1f">;
-def BC1T  : FBRANCH<MIPS_BRANCH_T,  "bc1t">;
+def BC1F  : FBRANCH<0, 0, MIPS_BRANCH_F,  "bc1f">;
+def BC1T  : FBRANCH<0, 1, MIPS_BRANCH_T,  "bc1t">;
 
 //===----------------------------------------------------------------------===//
 // Floating Point Flag Conditions
@@ -249,11 +261,11 @@
 
 /// Floating Point Compare
 let Defs=[FCR31] in {
-  def FCMP_S32 : FCC<0x0, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc),
+  def FCMP_S32 : FCC<0x10, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc),
                      "c.$cc.s\t$fs, $ft",
                      [(MipsFPCmp FGR32:$fs, FGR32:$ft, imm:$cc)]>;
 
-  def FCMP_D32 : FCC<0x1, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc),
+  def FCMP_D32 : FCC<0x11, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc),
                      "c.$cc.d\t$fs, $ft",
                      [(MipsFPCmp AFGR64:$fs, AFGR64:$ft, imm:$cc)]>,
                      Requires<[NotFP64bit]>;
diff --git a/lib/Target/Mips/MipsInstrFormats.td b/lib/Target/Mips/MipsInstrFormats.td
index 6dd82c8..e1725fa 100644
--- a/lib/Target/Mips/MipsInstrFormats.td
+++ b/lib/Target/Mips/MipsInstrFormats.td
@@ -21,30 +21,55 @@
 //
 //===----------------------------------------------------------------------===//
 
+// Format specifies the encoding used by the instruction.  This is part of the
+// ad-hoc solution used to emit machine instruction encodings by our machine
+// code emitter.
+class Format<bits<4> val> {
+  bits<4> Value = val;
+}
+
+def Pseudo    : Format<0>;
+def FrmR      : Format<1>;
+def FrmI      : Format<2>;
+def FrmJ      : Format<3>;
+def FrmFR     : Format<4>;
+def FrmFI     : Format<5>;
+def FrmOther  : Format<6>; // Instruction w/ a custom format
+
 // Generic Mips Format
 class MipsInst<dag outs, dag ins, string asmstr, list<dag> pattern,
-               InstrItinClass itin>: Instruction
+               InstrItinClass itin, Format f>: Instruction
 {
   field bits<32> Inst;
+  Format Form = f;
 
   let Namespace = "Mips";
 
-  bits<6> opcode;
+  bits<6> Opcode = 0;
 
-  // Top 5 bits are the 'opcode' field
-  let Inst{31-26} = opcode;
+  // Top 6 bits are the 'opcode' field
+  let Inst{31-26} = Opcode;
 
-  dag OutOperandList = outs;
-  dag InOperandList  = ins;
+  let OutOperandList = outs;
+  let InOperandList  = ins;
 
   let AsmString   = asmstr;
   let Pattern     = pattern;
   let Itinerary   = itin;
+
+  //
+  // Attributes specific to Mips instructions...
+  //
+  bits<4> FormBits = Form.Value;
+
+  // TSFlags layout should be kept in sync with MipsInstrInfo.h.
+  let TSFlags{3-0}   = FormBits;
 }
 
 // Mips Pseudo Instructions Format
 class MipsPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>:
-      MipsInst<outs, ins, asmstr, pattern, IIPseudo> {
+      MipsInst<outs, ins, asmstr, pattern, IIPseudo, Pseudo> {
+  let isCodeGenOnly = 1;
   let isPseudo = 1;
 }
 
@@ -54,7 +79,7 @@
 
 class FR<bits<6> op, bits<6> _funct, dag outs, dag ins, string asmstr,
          list<dag> pattern, InstrItinClass itin>:
-      MipsInst<outs, ins, asmstr, pattern, itin>
+      MipsInst<outs, ins, asmstr, pattern, itin, FrmR>
 {
   bits<5>  rd;
   bits<5>  rs;
@@ -62,7 +87,7 @@
   bits<5>  shamt;
   bits<6>  funct;
 
-  let opcode = op;
+  let Opcode = op;
   let funct  = _funct;
 
   let Inst{25-21} = rs;
@@ -77,13 +102,13 @@
 //===----------------------------------------------------------------------===//
 
 class FI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
-         InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin>
+         InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin, FrmI>
 {
   bits<5>  rt;
   bits<5>  rs;
   bits<16> imm16;
 
-  let opcode = op;
+  let Opcode = op;
 
   let Inst{25-21} = rs;
   let Inst{20-16} = rt;
@@ -92,13 +117,13 @@
 
 class CBranchBase<bits<6> op, dag outs, dag ins, string asmstr,
                   list<dag> pattern, InstrItinClass itin>:
-  MipsInst<outs, ins, asmstr, pattern, itin>
+  MipsInst<outs, ins, asmstr, pattern, itin, FrmI>
 {
   bits<5>  rs;
   bits<5>  rt;
   bits<16> imm16;
 
-  let opcode = op;
+  let Opcode = op;
 
   let Inst{25-21} = rs;
   let Inst{20-16} = rt;
@@ -110,11 +135,11 @@
 //===----------------------------------------------------------------------===//
 
 class FJ<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
-         InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin>
+         InstrItinClass itin>: MipsInst<outs, ins, asmstr, pattern, itin, FrmJ>
 {
   bits<26> addr;
 
-  let opcode = op;
+  let Opcode = op;
 
   let Inst{25-0} = addr;
 }
@@ -138,7 +163,7 @@
 
 class FFR<bits<6> op, bits<6> _funct, bits<5> _fmt, dag outs, dag ins,
           string asmstr, list<dag> pattern> :
-          MipsInst<outs, ins, asmstr, pattern, NoItinerary>
+          MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmFR>
 {
   bits<5>  fd;
   bits<5>  fs;
@@ -146,7 +171,7 @@
   bits<5>  fmt;
   bits<6>  funct;
 
-  let opcode = op;
+  let Opcode = op;
   let funct  = _funct;
   let fmt    = _fmt;
 
@@ -162,13 +187,13 @@
 //===----------------------------------------------------------------------===//
 
 class FFI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern>:
-          MipsInst<outs, ins, asmstr, pattern, NoItinerary>
+          MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmFI>
 {
   bits<5>  ft;
   bits<5>  base;
   bits<16> imm16;
 
-  let opcode = op;
+  let Opcode = op;
 
   let Inst{25-21} = base;
   let Inst{20-16} = ft;
@@ -180,14 +205,14 @@
 //===----------------------------------------------------------------------===//
 
 class FCC<bits<5> _fmt, dag outs, dag ins, string asmstr, list<dag> pattern> :
-          MipsInst<outs, ins, asmstr, pattern, NoItinerary>
+          MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmOther>
 {
   bits<5>  fs;
   bits<5>  ft;
   bits<4>  cc;
   bits<5>  fmt;
 
-  let opcode = 0x11;
+  let Opcode = 0x11;
   let fmt    = _fmt;
 
   let Inst{25-21} = fmt;
@@ -201,14 +226,14 @@
 
 class FCMOV<bits<1> _tf, dag outs, dag ins, string asmstr,
             list<dag> pattern> :
-  MipsInst<outs, ins, asmstr, pattern, NoItinerary>
+  MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmOther>
 {
   bits<5>  rd;
   bits<5>  rs;
   bits<3>  cc;
   bits<1>  tf;
 
-  let opcode = 0;
+  let Opcode = 0;
   let tf = _tf;
 
   let Inst{25-21} = rs;
@@ -222,7 +247,7 @@
 
 class FFCMOV<bits<5> _fmt, bits<1> _tf, dag outs, dag ins, string asmstr,
              list<dag> pattern> :
-  MipsInst<outs, ins, asmstr, pattern, NoItinerary>
+  MipsInst<outs, ins, asmstr, pattern, NoItinerary, FrmOther>
 {
   bits<5>  fd;
   bits<5>  fs;
@@ -230,7 +255,7 @@
   bits<5>  fmt;
   bits<1>  tf;
 
-  let opcode = 17;
+  let Opcode = 17;
   let fmt = _fmt;
   let tf = _tf;
 
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index ed49dec..fd99b13 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -153,6 +153,7 @@
 def mem : Operand<i32> {
   let PrintMethod = "printMemOperand";
   let MIOperandInfo = (ops CPURegs, simm16);
+  let EncoderMethod = "getMemEncoding";
 }
 
 def mem64 : Operand<i64> {
@@ -163,6 +164,17 @@
 def mem_ea : Operand<i32> {
   let PrintMethod = "printMemOperandEA";
   let MIOperandInfo = (ops CPURegs, simm16);
+  let EncoderMethod = "getMemEncoding";
+}
+
+// size operand of ext instruction
+def size_ext : Operand<i32> {
+  let EncoderMethod = "getSizeExtEncoding";
+}
+
+// size operand of ins instruction
+def size_ins : Operand<i32> {
+  let EncoderMethod = "getSizeInsEncoding";
 }
 
 // Transformation Function - get the lower 16 bits.
@@ -269,14 +281,14 @@
 // Arithmetic and logical instructions with 2 register operands.
 class ArithLogicI<bits<6> op, string instr_asm, SDNode OpNode,
                   Operand Od, PatLeaf imm_type, RegisterClass RC> :
-  FI<op, (outs RC:$rt), (ins RC:$rs, Od:$i),
-     !strconcat(instr_asm, "\t$rt, $rs, $i"),
-     [(set RC:$rt, (OpNode RC:$rs, imm_type:$i))], IIAlu>;
+  FI<op, (outs RC:$rt), (ins RC:$rs, Od:$imm16),
+     !strconcat(instr_asm, "\t$rt, $rs, $imm16"),
+     [(set RC:$rt, (OpNode RC:$rs, imm_type:$imm16))], IIAlu>;
 
 class ArithOverflowI<bits<6> op, string instr_asm, SDNode OpNode,
                      Operand Od, PatLeaf imm_type, RegisterClass RC> :
-  FI<op, (outs RC:$rt), (ins RC:$rs, Od:$i),
-     !strconcat(instr_asm, "\t$rt, $rs, $i"), [], IIAlu>;
+  FI<op, (outs RC:$rt), (ins RC:$rs, Od:$imm16),
+     !strconcat(instr_asm, "\t$rt, $rs, $imm16"), [], IIAlu>;
 
 // Arithmetic Multiply ADD/SUB
 let rd = 0, shamt = 0, Defs = [HI, LO], Uses = [HI, LO] in
@@ -323,16 +335,23 @@
 
 // Load Upper Imediate
 class LoadUpper<bits<6> op, string instr_asm>:
-  FI<op, (outs CPURegs:$rt), (ins uimm16:$imm),
-     !strconcat(instr_asm, "\t$rt, $imm"), [], IIAlu> {
+  FI<op, (outs CPURegs:$rt), (ins uimm16:$imm16),
+     !strconcat(instr_asm, "\t$rt, $imm16"), [], IIAlu> {
   let rs = 0;
 }
 
+class FMem<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern,
+          InstrItinClass itin>: FFI<op, outs, ins, asmstr, pattern> {
+  bits<21> addr;
+  let Inst{25-21} = addr{20-16};
+  let Inst{15-0}  = addr{15-0};
+}
+
 // Memory Load/Store
 let canFoldAsLoad = 1 in
 class LoadM<bits<6> op, string instr_asm, PatFrag OpNode, RegisterClass RC,
             Operand MemOpnd, bit Pseudo>:
-  FI<op, (outs RC:$rt), (ins MemOpnd:$addr),
+  FMem<op, (outs RC:$rt), (ins MemOpnd:$addr),
      !strconcat(instr_asm, "\t$rt, $addr"),
      [(set RC:$rt, (OpNode addr:$addr))], IILoad> {
   let isPseudo = Pseudo;
@@ -340,7 +359,7 @@
 
 class StoreM<bits<6> op, string instr_asm, PatFrag OpNode, RegisterClass RC,
              Operand MemOpnd, bit Pseudo>:
-  FI<op, (outs), (ins RC:$rt, MemOpnd:$addr),
+  FMem<op, (outs), (ins RC:$rt, MemOpnd:$addr),
      !strconcat(instr_asm, "\t$rt, $addr"),
      [(OpNode RC:$rt, addr:$addr)], IIStore> {
   let isPseudo = Pseudo;
@@ -384,9 +403,9 @@
 
 // Conditional Branch
 class CBranch<bits<6> op, string instr_asm, PatFrag cond_op, RegisterClass RC>:
-  CBranchBase<op, (outs), (ins RC:$rs, RC:$rt, brtarget:$offset),
-              !strconcat(instr_asm, "\t$rs, $rt, $offset"),
-              [(brcond (i32 (cond_op RC:$rs, RC:$rt)), bb:$offset)], IIBranch> {
+  CBranchBase<op, (outs), (ins RC:$rs, RC:$rt, brtarget:$imm16),
+              !strconcat(instr_asm, "\t$rs, $rt, $imm16"),
+              [(brcond (i32 (cond_op RC:$rs, RC:$rt)), bb:$imm16)], IIBranch> {
   let isBranch = 1;
   let isTerminator = 1;
   let hasDelaySlot = 1;
@@ -394,9 +413,9 @@
 
 class CBranchZero<bits<6> op, bits<5> _rt, string instr_asm, PatFrag cond_op,
                   RegisterClass RC>:
-  CBranchBase<op, (outs), (ins RC:$rs, brtarget:$offset),
-              !strconcat(instr_asm, "\t$rs, $offset"),
-              [(brcond (i32 (cond_op RC:$rs, 0)), bb:$offset)], IIBranch> {
+  CBranchBase<op, (outs), (ins RC:$rs, brtarget:$imm16),
+              !strconcat(instr_asm, "\t$rs, $imm16"),
+              [(brcond (i32 (cond_op RC:$rs, 0)), bb:$imm16)], IIBranch> {
   let rt = _rt;
   let isBranch = 1;
   let isTerminator = 1;
@@ -415,9 +434,9 @@
 
 class SetCC_I<bits<6> op, string instr_asm, PatFrag cond_op, Operand Od,
               PatLeaf imm_type, RegisterClass RC>:
-  FI<op, (outs CPURegs:$rd), (ins RC:$rs, Od:$i),
-     !strconcat(instr_asm, "\t$rd, $rs, $i"),
-     [(set CPURegs:$rd, (cond_op RC:$rs, imm_type:$i))],
+  FI<op, (outs CPURegs:$rt), (ins RC:$rs, Od:$imm16),
+     !strconcat(instr_asm, "\t$rt, $rs, $imm16"),
+     [(set CPURegs:$rt, (cond_op RC:$rs, imm_type:$imm16))],
      IIAlu>;
 
 // Unconditional branch
@@ -454,10 +473,8 @@
   }
 
   class BranchLink<string instr_asm>:
-    FI<0x1, (outs), (ins CPURegs:$rs, brtarget:$target, variable_ops),
-       !strconcat(instr_asm, "\t$rs, $target"), [], IIBranch> {
-    let rt = 0;
-  }
+    FI<0x1, (outs), (ins CPURegs:$rs, brtarget:$imm16, variable_ops),
+       !strconcat(instr_asm, "\t$rs, $imm16"), [], IIBranch>;
 }
 
 // Mul, Div
@@ -509,7 +526,7 @@
 }
 
 class EffectiveAddress<string instr_asm> :
-  FI<0x09, (outs CPURegs:$rt), (ins mem_ea:$addr),
+  FMem<0x09, (outs CPURegs:$rt), (ins mem_ea:$addr),
      instr_asm, [(set CPURegs:$rt, addr:$addr)], IIAlu>;
 
 // Count Leading Ones/Zeros in Word
@@ -533,7 +550,7 @@
 
 // Sign Extend in Register.
 class SignExtInReg<bits<5> sa, string instr_asm, ValueType vt>:
-  FR<0x3f, 0x20, (outs CPURegs:$rd), (ins CPURegs:$rt),
+  FR<0x1f, 0x20, (outs CPURegs:$rd), (ins CPURegs:$rt),
      !strconcat(instr_asm, "\t$rd, $rt"),
      [(set CPURegs:$rd, (sext_inreg CPURegs:$rt, vt))], NoItinerary> {
   let rs = 0;
@@ -711,20 +728,22 @@
 
 let hasSideEffects = 1 in
 def SYNC : MipsInst<(outs), (ins i32imm:$stype), "sync $stype",
-                    [(MipsSync imm:$stype)], NoItinerary>
+                    [(MipsSync imm:$stype)], NoItinerary, FrmOther>
 {
-  let opcode = 0;
+  bits<5> stype;
+  let Opcode = 0;
   let Inst{25-11} = 0;
+  let Inst{10-6} = stype;
   let Inst{5-0} = 15;
 }
 
 /// Load-linked, Store-conditional
 let mayLoad = 1 in
-  def LL    : FI<0x30, (outs CPURegs:$dst), (ins mem:$addr),
-              "ll\t$dst, $addr", [], IILoad>;
-let mayStore = 1, Constraints = "$src = $dst" in
-  def SC    : FI<0x38, (outs CPURegs:$dst), (ins CPURegs:$src, mem:$addr),
-              "sc\t$src, $addr", [], IIStore>;
+  def LL    : FMem<0x30, (outs CPURegs:$rt), (ins mem:$addr),
+              "ll\t$rt, $addr", [], IILoad>;
+let mayStore = 1, Constraints = "$rt = $dst" in
+  def SC    : FMem<0x38, (outs CPURegs:$dst), (ins CPURegs:$rt, mem:$addr),
+              "sc\t$rt, $addr", [], IIStore>;
 
 /// Jump and Branch Instructions
 def J       : JumpFJ<0x02, "j">;
@@ -736,15 +755,17 @@
 def BNE     : CBranch<0x05, "bne", setne, CPURegs>;
 def BGEZ    : CBranchZero<0x01, 1, "bgez", setge, CPURegs>;
 def BGTZ    : CBranchZero<0x07, 0, "bgtz", setgt, CPURegs>;
-def BLEZ    : CBranchZero<0x07, 0, "blez", setle, CPURegs>;
+def BLEZ    : CBranchZero<0x06, 0, "blez", setle, CPURegs>;
 def BLTZ    : CBranchZero<0x01, 0, "bltz", setlt, CPURegs>;
 
-def BGEZAL  : BranchLink<"bgezal">;
-def BLTZAL  : BranchLink<"bltzal">;
+let rt=0x11 in
+  def BGEZAL  : BranchLink<"bgezal">;
+let rt=0x10 in
+  def BLTZAL  : BranchLink<"bltzal">;
 
 let isReturn=1, isTerminator=1, hasDelaySlot=1,
-    isBarrier=1, hasCtrlDep=1, rs=0, rt=0, shamt=0 in
-  def RET : FR <0x00, 0x02, (outs), (ins CPURegs:$target),
+    isBarrier=1, hasCtrlDep=1, rd=0, rt=0, shamt=0 in
+  def RET : FR <0x00, 0x08, (outs), (ins CPURegs:$target),
                 "jr\t$target", [(MipsRet CPURegs:$target)], IIBranch>;
 
 /// Multiply and Divide Instructions.
@@ -799,14 +820,14 @@
 def RDHWR : ReadHardware;
 
 def EXT : ExtIns<0, "ext", (outs CPURegs:$rt),
-                 (ins CPURegs:$rs, uimm16:$pos, uimm16:$sz),
+                 (ins CPURegs:$rs, uimm16:$pos, size_ext:$sz),
                  [(set CPURegs:$rt,
                    (MipsExt CPURegs:$rs, immZExt5:$pos, immZExt5:$sz))],
                  NoItinerary>;
 
 let Constraints = "$src = $rt" in
 def INS : ExtIns<4, "ins", (outs CPURegs:$rt),
-                 (ins CPURegs:$rs, uimm16:$pos, uimm16:$sz, CPURegs:$src),
+                 (ins CPURegs:$rs, uimm16:$pos, size_ins:$sz, CPURegs:$src),
                  [(set CPURegs:$rt,
                    (MipsIns CPURegs:$rs, immZExt5:$pos, immZExt5:$sz,
                     CPURegs:$src))],