[llvm] r319609 - [ARC] Add instruction subset for the ARC backend.

Tatyana Krasnukha via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 1 21:25:18 PST 2017


Author: tkrasnukha
Date: Fri Dec  1 21:25:17 2017
New Revision: 319609

URL: http://llvm.org/viewvc/llvm-project?rev=319609&view=rev
Log:
[ARC] Add instruction subset for the ARC backend.

Reviewers: petecoup, kparzysz

Reviewed By: petecoup

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D37983

Added:
    llvm/trunk/test/MC/Disassembler/ARC/compact.txt
Modified:
    llvm/trunk/lib/Target/ARC/ARCInstrFormats.td
    llvm/trunk/lib/Target/ARC/ARCInstrInfo.td
    llvm/trunk/lib/Target/ARC/Disassembler/ARCDisassembler.cpp
    llvm/trunk/lib/Target/ARC/InstPrinter/ARCInstPrinter.cpp
    llvm/trunk/test/MC/Disassembler/ARC/alu.txt
    llvm/trunk/test/MC/Disassembler/ARC/misc.txt

Modified: llvm/trunk/lib/Target/ARC/ARCInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARC/ARCInstrFormats.td?rev=319609&r1=319608&r2=319609&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARC/ARCInstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARC/ARCInstrFormats.td Fri Dec  1 21:25:17 2017
@@ -17,18 +17,23 @@ class Encoding64 {
 }
 
 // Address operands
-def immU6 : Operand<i32>, PatLeaf<(imm), [{
-    return isUInt<6>(N->getSExtValue()); }]> {
+
+class immU<int BSz> : Operand<i32>, PatLeaf<(imm),
+    "\n    return isUInt<"#BSz#">(N->getSExtValue());"> {
 }
 
-def immS12 : Operand<i32>, PatLeaf<(imm), [{
-    return isInt<12>(N->getSExtValue()); }]> {
-  let DecoderMethod = "DecodeS12Operand";
+def immU6 : immU<6>;
+
+class immS<int BSz> : Operand<i32>, PatLeaf<(imm),
+    "\n    return isInt<"#BSz#">(N->getSExtValue());"> {
+  let DecoderMethod = "DecodeSignedOperand<"#BSz#">";
 }
 
-def immS9 : Operand<i32>, PatLeaf<(imm), [{
-    return isInt<9>(N->getSExtValue()); }]> {
-  let DecoderMethod = "DecodeS9Operand";
+// e.g. s3 field may encode the signed integers values -1 .. 6
+// using binary codes 111, 000, 001, 010, 011, 100, 101, and 110, respectively
+class immC<int BSz> : Operand<i32>, PatLeaf<(imm),
+    "\n    return isInt<"#BSz#">(N->getSExtValue());"> {
+  let DecoderMethod = "DecodeFromCyclicRange<"#BSz#">";
 }
 
 def MEMii : Operand<i32> {
@@ -36,7 +41,7 @@ def MEMii : Operand<i32> {
 }
 
 def MEMrs9 : Operand<iAny> {
-  let MIOperandInfo = (ops GPR32:$B, immS9:$S9);
+  let MIOperandInfo = (ops GPR32:$B, immS<9>:$S9);
   let PrintMethod = "printMemOperandRI";
   let DecoderMethod = "DecodeMEMrs9";
 }
@@ -47,6 +52,10 @@ def MEMrlimm : Operand<iAny> {
   let DecoderMethod = "DecodeMEMrlimm";
 }
 
+def GPR32Reduced : Operand<iAny> {
+  let DecoderMethod = "DecodeGBR32ShortRegister";
+}
+
 class InstARC<int sz, dag outs, dag ins, string asmstr, list<dag> pattern>
     : Instruction, Encoding64 {
 
@@ -153,7 +162,6 @@ class F32_BR1_BL_COND<dag outs, dag ins,
   let Inst{17} = 0;
 }
 
-
 // BRcc targets have limited 9-bit range.  These are for compare and branch
 // in single instruction.  Their targets are 2-byte aligned.  They also use
 // a different (3-bit) set of condition codes.
@@ -464,6 +472,342 @@ class F32_ST_LIMM<bit di, bits<2> zz, da
   let DecoderMethod = "DecodeStLImmInstruction";
 }
 
+// Compact Move/Load.
+// |10|9|8|7|6|5|4|3|2|1|0|
+// |      |h    |   |i|H  |
+class F16_COMPACT<bits<1> i, dag outs, dag ins,
+                 string asmstr> :
+  InstARC<2, outs, ins, asmstr, []> {
+
+  bits<5> h;
+
+  let Inst{15-11} = 0b01000;
+  let Inst{7-5} = h{2-0};
+  let Inst{2} = i;
+  let Inst{1-0} = h{4-3};  
+}
+
+// Compact Load/Add/Sub.
+class F16_LD_ADD_SUB<dag outs, dag ins, string asmstr> :
+  InstARC<2, outs, ins, asmstr, []> {
+
+  bits<3> b;  
+  let Inst{15-11} = 0b01001;
+  let Inst{10-8} = b;
+}
+
+class F16_LD_SUB<bit i, string asmstr> :
+  F16_LD_ADD_SUB<(outs GPR32:$a), (ins GPR32:$b, GPR32:$c),
+  asmstr> {
+
+  bits<3> a;
+  bits<3> c;
+
+  let Inst{7-5} = c;
+  let Inst{4} = i;
+  let Inst{3} = 0;
+  let Inst{2-0} = a;
+}
+
+class F16_ADD :
+  F16_LD_ADD_SUB<(outs GPR32:$r), (ins GPR32:$b, immU<6>:$u6),
+  "add_s\t$r, $b, $u6"> {
+  
+  bit r;
+  bits<6> u6;
+  
+  let Inst{7} = r;
+  let Inst{6-4} = u6{5-3};
+  let Inst{3} = 1;
+  let Inst{2-0} = u6{2-0};
+}
+
+// Compact Load/Store.
+class F16_LD_ST_1<dag outs, dag ins, string asmstr> :
+  InstARC<2, outs, ins, asmstr, []> {
+
+  let Inst{15-11} = 0b01010;
+}
+
+class F16_LD_ST_s11<bit i, string asmstr> :
+  F16_LD_ST_1<(outs), (ins immS<11>:$s11), asmstr> {
+
+  bits<11> s11;
+
+  let Inst{10-5} = s11{10-5};
+  let Inst{4} = i;
+  let Inst{3} = 0;
+  let Inst{2-0} = s11{4-2};
+  let s11{1-0} = 0b00;
+}
+
+class F16_LDI_u7 :
+  F16_LD_ST_1<(outs GPR32:$b), (ins immU<7>:$u7),
+  "ldi_s\t$b, [$u7]"> {
+
+  bits<3> b;
+  bits<7> u7;
+  
+  let Inst{10-8} = b;
+  let Inst{7-4} = u7{6-3};
+  let Inst{3} = 1;
+  let Inst{2-0} = u7{2-0};
+}
+
+// Indexed Jump or Execute.
+class F16_JLI_EI<bit i, string asmstr> :
+  InstARC<2, (outs), (ins immU<10>:$u10),
+  !strconcat(asmstr, "\t$u10"), []> {
+
+  bits<10> u10;
+  
+  let Inst{15-11} = 0b01011;
+  let Inst{10} = i;
+  let Inst{9-0} = u10;
+}
+
+// Load/Add Register-Register.
+class F16_LD_ADD_RR<bits<2> i, string asmstr> :
+  InstARC<2, (outs GPR32:$a), (ins GPR32:$b, GPR32:$c),
+  asmstr, []> {
+
+  bits<3> a;
+  bits<3> b; 
+  bits<3> c;
+ 
+  let Inst{15-11} = 0b01100;
+  let Inst{10-8} = b;
+  let Inst{7-5} = c;
+  let Inst{4-3} = i;
+  let Inst{2-0} = a;
+}
+
+// Load/Add GP-Relative.
+class F16_GP_LD_ADD<bits<2> i, dag ins, string asmstr> :
+  InstARC<2, (outs), ins, asmstr, []> {
+ 
+  let Inst{15-11} = 0b11001;
+  let Inst{10-9} = i;
+}
+
+// Add/Sub/Shift Register-Immediate.
+// |10|9|8|7|6|5|4|3|2|1|0|
+// |b     |c    |i  |u    |
+class F16_ADD_IMM<bits<2> i, string asmstr> :
+  InstARC<2, (outs GPR32:$c), (ins GPR32:$b, immU<3>:$u3),
+  !strconcat(asmstr, "\t$c, $b, $u3"), []> {
+
+  bits<3> b;
+  bits<3> c;
+  bits<3> u3;
+  
+  let Inst{15-11} = 0b01101;
+  let Inst{10-8} = b;
+  let Inst{7-5} = c;
+  let Inst{4-3} = i;
+  let Inst{2-0} = u3;
+}
+
+// Dual Register Operations.
+// |10|9|8|7|6|5|4|3|2|1|0|
+// |b/s   |h    |i    |H  |
+class F16_OP_HREG<bits<3> i, dag outs, dag ins, string asmstr> :
+  InstARC<2, outs, ins, asmstr, []> {
+
+  bits<3> b_s3;
+  bits<5> h;
+
+  let Inst{15-11} = 0b01110;
+  let Inst{10-8} = b_s3;
+  let Inst{7-5} = h{2-0};
+  let Inst{4-2} = i;
+  let Inst{1-0} = h{4-3};
+}
+
+class F16_OP_HREG30<bits<3> i, dag outs, dag ins, string asmstr> :
+  F16_OP_HREG<i, outs, ins, asmstr> {
+    
+  bits<5> LImmReg = 0b11110;  
+  let Inst{7-5} = LImmReg{2-0};
+  let Inst{1-0} = LImmReg{4-3};
+}
+
+class F16_OP_HREG_LIMM<bits<3> i, dag outs, dag ins, string asmstr> :
+  F16_OP_HREG30<i, outs, ins, asmstr> {
+
+  bits<32> LImm;
+  let Inst{47-16} = LImm;
+  let Size = 6;
+}
+
+// General compact DOP format.
+class F16_GEN_DOP_BASE<bits<5> i, dag outs, dag ins, string asmstr> :
+  InstARC<2, outs, ins, asmstr, []> {
+
+  bits<3> b;
+  bits<3> c;
+  let Inst{15-11} = 0b01111;
+  let Inst{10-8} = b;
+  let Inst{7-5} = c;
+  let Inst{4-0} = i;
+}
+
+class F16_GEN_DOP<bits<5> i, string asmstr> :
+  F16_GEN_DOP_BASE<i, (outs GPR32:$b), (ins GPR32:$c),
+  !strconcat(asmstr, "\t$b, $b, $c")>;
+
+class F16_GEN_DOP_NODST<bits<5> i, string asmstr> :
+  F16_GEN_DOP_BASE<i, (outs), (ins GPR32:$b, GPR32:$c),
+  !strconcat(asmstr, "\t$b, $c")>;
+
+class F16_GEN_DOP_SINGLESRC<bits<5> i, string asmstr> :
+  F16_GEN_DOP_BASE<i, (outs GPR32:$b), (ins GPR32:$c),
+  !strconcat(asmstr, "\t$b, $c")>;
+
+class F16_GEN_SOP_BASE<bits<3> i, dag outs, dag ins, string asmstr> :
+  F16_GEN_DOP_BASE<0b00000, outs, ins, asmstr> {
+
+  let c = i;
+}
+
+class F16_GEN_SOP<bits<3> i, string asmstr> :
+  F16_GEN_SOP_BASE<i, (outs), (ins GPR32:$b), asmstr>;
+
+class F16_GEN_ZOP<bits<3> i, string asmstr> :
+  F16_GEN_SOP_BASE<0b111, (outs), (ins), asmstr> {
+
+  let b = i;
+}
+
+// Compact Load/Store with Offset Format.
+class F16_LD_ST_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
+  InstARC<2, outs, ins, !strconcat(asmstr, "\t$c, [$b, $off]"), []> {
+
+  bits<3> b;
+  bits<3> c;
+  let Inst{15-11} = opc;
+  let Inst{10-8} = b;
+  let Inst{7-5} = c;
+}
+
+class F16_LD_ST_WORD_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
+  F16_LD_ST_OFF<opc, outs, ins, asmstr> {
+
+  bits<7> off;
+  let Inst{4-0} = off{6-2};
+  let off{1-0} = 0b00;
+}
+
+class F16_LD_ST_HALF_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
+  F16_LD_ST_OFF<opc, outs, ins, asmstr> {
+
+  bits<6> off;
+  let Inst{4-0} = off{5-1};
+  let off{0} = 0b0;
+}
+
+class F16_LD_ST_BYTE_OFF<bits<5> opc, dag outs, dag ins, string asmstr> :
+  F16_LD_ST_OFF<opc, outs, ins, asmstr> {
+
+  bits<5> off;
+  let Inst{4-0} = off;
+}
+
+// Shift/Subtract/Bit Immediate.
+// |10|9|8|7|6|5|4|3|2|1|0|
+// |b     |i    |u        |
+class F16_SH_SUB_BIT<bits<3> i, string asmstr> :
+  InstARC<2, (outs), (ins GPR32:$b, immU<5>:$u5), asmstr, []> {
+
+  bits<3> b;
+  bits<5> u5;
+  
+  let Inst{15-11} = 0b10111;
+  let Inst{10-8} = b;
+  let Inst{7-5} = i;
+  let Inst{4-0} = u5;
+}
+
+class F16_SH_SUB_BIT_DST<bits<3> i, string asmstr> :
+  F16_SH_SUB_BIT<i, !strconcat(asmstr, "\t$b, $b, $u5")>;
+
+// 16-bit stack-based operations.
+// |10|9|8|7|6|5|4|3|2|1|0|
+// |b     |i    |u        |
+class F16_SP_OPS<bits<3> i,
+  dag outs, dag ins, string asmstr> :
+  InstARC<2, outs, ins, asmstr, []> {
+
+  bits<3> fieldB;
+  bits<5> fieldU;
+
+  let Inst{15-11} = 0b11000;
+  let Inst{10-8} = fieldB;
+  let Inst{7-5} = i;
+  let Inst{4-0} = fieldU;
+}
+
+class F16_SP_OPS_u7_aligned<bits<3> i,
+  dag outs, dag ins, string asmstr> :
+  F16_SP_OPS<i, outs, ins, asmstr> {
+
+  bits<3> b3;
+  bits<7> u7;
+  
+  let fieldB = b3;
+  let fieldU = u7{6-2};
+  let u7{1-0} = 0b00;
+}
+
+class F16_SP_OPS_bconst<bits<3> b, string asmop> :
+  F16_SP_OPS_u7_aligned<0b101,
+  (outs), (ins immU<7>:$u7),
+  !strconcat(asmop, "\t%sp, %sp, $u7")> {
+  
+  let fieldB = b;
+}
+
+class F16_SP_OPS_uconst<bits<3> i,
+  dag outs, dag ins, string asmop> :
+  F16_SP_OPS_u7_aligned<i, outs, ins,
+  !strconcat(asmop, "\t$b3")> {
+  
+  let fieldU = 0b00001;
+}
+
+class F16_SP_OPS_buconst<bits<3> i, string asmop> :
+  F16_SP_OPS_u7_aligned<i, (outs), (ins),
+    !strconcat(asmop, "\t%blink")> {
+  
+  let fieldB = 0x000;
+  let fieldU = 0b10001;
+}
+
+class F16_SP_LD<bits<3> i, string asmop> : F16_SP_OPS_u7_aligned<i,
+                         (outs GPR32Reduced:$b3), (ins immU<7>:$u7),
+                         !strconcat(asmop, "\t$b3, [%sp, $u7]")>;
+
+class F16_SP_ST<bits<3> i, string asmop> : F16_SP_OPS_u7_aligned<i,
+                         (outs), (ins GPR32Reduced:$b3, immU<7>:$u7),
+                         !strconcat(asmop, "\t$b3, [%sp, $u7]")>;
+
+// Compact MOV/ADD/CMP Immediate Format.
+class F16_OP_IMM<bits<5> opc, dag outs, dag ins, string asmstr> :
+  InstARC<2, outs, ins, asmstr, []> {
+
+  bits<3> b;
+  let Inst{15-11} = opc;
+  let Inst{10-8} = b;
+}
+
+class F16_OP_U7<bit i, string asmstr> :
+  F16_OP_IMM<0b11100, (outs GPR32:$b), (ins immU<7>:$u7), asmstr> {
+
+  bits<7> u7;
+  let Inst{7} = i;
+  let Inst{6-0} = u7;
+}
+
 // Special types for different instruction operands.
 def cmovpred : Operand<i32>, PredicateOp,
                ComplexPattern<i32, 2, "SelectCMOVPred"> {
@@ -481,28 +825,67 @@ def brccond : Operand<i32> {
   let PrintMethod = "printBRCCPredicateOperand";
 }
 
-// Branch targets of different offset sizes.
-def btarget : Operand<OtherVT> {
+// Branch/call targets of different offset sizes.
+class BCTarget<ValueType vt> : Operand<vt> {
   let OperandType = "OPERAND_PCREL";
 }
 
-def btargetS9 : Operand<OtherVT> {
-  let OperandType = "OPERAND_PCREL";
-  let DecoderMethod = "DecodeBranchTargetS9";
+def btarget : BCTarget<OtherVT>;
+
+class BCTargetSigned<ValueType vt, int BSz> : BCTarget<vt> {
+  let DecoderMethod = "DecodeBranchTargetS<"#BSz#">";
 }
 
-def btargetS21 : Operand<OtherVT> {
-  let OperandType = "OPERAND_PCREL";
-  let DecoderMethod = "DecodeBranchTargetS21";
+class BranchTargetS<int BSz> : BCTargetSigned<OtherVT, BSz>;
+def btargetS7 : BranchTargetS<7>;
+def btargetS8 : BranchTargetS<8>;
+def btargetS9 : BranchTargetS<9>;
+def btargetS10 : BranchTargetS<10>;
+def btargetS13 : BranchTargetS<13>;
+def btargetS21 : BranchTargetS<21>;
+def btargetS25 : BranchTargetS<25>;
+
+class CallTargetS<int BSz> : BCTargetSigned<i32, BSz>;
+def calltargetS25: CallTargetS<25>;
+
+// Compact Branch on Compare Register with Zero.
+class F16_BCC_REG<bit i, string asmstr> :
+  InstARC<2, (outs), (ins GPR32:$b, btargetS8:$s8),
+  !strconcat(asmstr, "\t$b, 0, $s8"), []> {
+
+  bits<3> b;
+  bits<8> s8;
+
+  let Inst{15-11} = 0b11101;
+  let Inst{10-8} = b;
+  let Inst{7} = i;
+  let Inst{6-0} = s8{7-1};
+  let s8{0} = 0b0;
 }
 
-def btargetS25 : Operand<OtherVT> {
-  let OperandType = "OPERAND_PCREL";
-  let DecoderMethod = "DecodeBranchTargetS25";
+// Compact Branch Conditionally Format.
+class F16_BCC<bits<2> i, dag ins, string asmstr> :
+  InstARC<2, (outs), ins, asmstr, []> {
+
+  let Inst{15-11} = 0b11110;
+  let Inst{10-9} = i;
 }
 
-def calltargetS25: Operand<i32> {
-  let OperandType = "OPERAND_PCREL";
-  let DecoderMethod = "DecodeBranchTargetS25";
+class F16_BCC_s10<bits<2> i, string asmstr> :
+  F16_BCC<i, (ins btargetS10:$s),
+  !strconcat(asmstr, "\t$s")> {
+
+  bits<10> s;
+  let Inst{8-0} = s{9-1};
+  let s{0} = 0b0;
 }
 
+class F16_BCC_s7<bits<3> i, string asmstr> :
+  F16_BCC<0b11, (ins btargetS7:$s),
+  !strconcat(asmstr, "\t$s")> {
+
+  bits<7> s;
+  let Inst{8-6} = i;
+  let Inst{5-0} = s{6-1};
+  let s{0} = 0b0;
+}

Modified: llvm/trunk/lib/Target/ARC/ARCInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARC/ARCInstrInfo.td?rev=319609&r1=319608&r2=319609&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARC/ARCInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARC/ARCInstrInfo.td Fri Dec  1 21:25:17 2017
@@ -117,7 +117,7 @@ def STB_FAR : PseudoInstARC<(outs), (ins
 // multiclass.  These classes do not contain Selection DAG patterns.
 //===----------------------------------------------------------------------===//
 
-// Generic 3 operand binary instructions (i.e., add, r0, r1, r2).
+// Generic 3 operand binary instructions (i.e., add r0, r1, r2).
 multiclass ArcBinaryInst<bits<5> major, bits<6> mincode,
                        string opasm> {
   // 3 register variant.
@@ -140,7 +140,7 @@ multiclass ArcBinaryInst<bits<5> major,
   // 2 matched-register with signed 12-bit immediate variant (add r0, r0, -1).
   def _rrs12 : F32_DOP_RS12<major, mincode, 0,
                             (outs GPR32:$B),
-                            (ins GPR32:$in, immS12:$S12),
+                            (ins GPR32:$in, immS<12>:$S12),
                             !strconcat(opasm, "\t$B, $in, $S12"),
                             []>
   { let Constraints = "$B = $in"; }
@@ -194,6 +194,9 @@ multiclass MultiPat<SDPatternOperator In
 // Definitions for 3 operand binary instructions.
 defm ADD : ArcBinaryGEN4Inst<0b000000, "add">;
 defm SUB : ArcBinaryGEN4Inst<0b000010, "sub">;
+defm SUB1 : ArcBinaryGEN4Inst<0b010111, "sub1">;
+defm SUB2 : ArcBinaryGEN4Inst<0b011000, "sub2">;
+defm SUB3 : ArcBinaryGEN4Inst<0b011001, "sub3">;
 defm OR  : ArcBinaryGEN4Inst<0b000101, "or">;
 defm AND : ArcBinaryGEN4Inst<0b000100, "and">;
 defm XOR : ArcBinaryGEN4Inst<0b000111, "xor">;
@@ -206,6 +209,7 @@ defm ROR : ArcBinaryEXT5Inst<0b000011, "
 defm MPY  : ArcBinaryGEN4Inst<0b011010, "mpy">;
 defm MPYM : ArcBinaryGEN4Inst<0b011011, "mpym">;
 defm MPYMU : ArcBinaryGEN4Inst<0b011100, "mpymu">;
+defm SETEQ : ArcBinaryGEN4Inst<0b111000, "seteq">;
 
 // Patterns for 3 operand binary instructions.
 defm : MultiPat<add, ADD_rrr, ADD_rru6, ADD_rrlimm>;
@@ -223,7 +227,6 @@ defm : MultiPat<mul, MPY_rrr, MPY_rru6,
 defm : MultiPat<mulhs, MPYM_rrr, MPYM_rru6, MPYM_rrlimm>;
 defm : MultiPat<mulhu, MPYMU_rrr, MPYMU_rru6, MPYMU_rrlimm>;
 
-
 // ---------------------------------------------------------------------------
 // Unary Instruction definitions.
 // ---------------------------------------------------------------------------
@@ -248,9 +251,9 @@ defm : MultiPat<cmp, CMP_rr, CMP_ru6, CM
 // ---------------------------------------------------------------------------
 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
 def MOV_rs12 : F32_DOP_RS12<0b00100, 0b001010, 0,
-                 (outs GPR32:$B), (ins immS12:$S12),
+                 (outs GPR32:$B), (ins immS<12>:$S12),
                  "mov\t$B, $S12",
-                 [(set GPR32:$B, immS12:$S12)]>;
+                 [(set GPR32:$B, immS<12>:$S12)]>;
 }
 
 def MOV_rr : F32_DOP_RR<0b00100, 0b001010, 0,
@@ -288,96 +291,463 @@ def : Pat<(ARCGAWrapper tjumptable:$addr
 // ---------------------------------------------------------------------------
 
 // Branch instructions
-let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
-// Unconditional branch.
-def BR : F32_BR0_UCOND_FAR<(outs), (ins btargetS25:$S25),
-                  "b\t$S25", [(br bb:$S25)]>;
-
-let Uses=[STATUS32] in {
-// Conditional branch.
-def Bcc : F32_BR0_COND<(outs), (ins btargetS21:$S21, ccond:$cc),
-                    "b$cc\t$S21", []>;
-}
-
-// Compare and branch (limited range).
-def BRcc_rr  : F32_BR1_BCC<(outs),
-                           (ins btargetS9:$S9, GPR32:$B, GPR32:$C, brccond:$cc),
-                           "br$cc\t$B, $C, $S9", 0, []>;
-def BRcc_ru6 : F32_BR1_BCC<(outs),
-                           (ins btargetS9:$S9, GPR32:$B, immU6:$C, brccond:$cc),
-                           "br$cc\t$B, $C, $S9", 1, []>;
-
-// Pseudo compare and branch.
-// After register allocation, this can expand into either a limited range
-// Compare and branch (BRcc), or into CMP + Bcc.
-// At worst, this expands into 2 4-byte instructions.
-def BRcc_rr_p : PseudoInstARC<(outs),
-                              (ins btarget:$T, GPR32:$B, GPR32:$C, ccond:$cc),
-                              "pbr$cc\t$B, $C, $T", 
-                              [(ARCbrcc bb:$T, i32:$B, i32:$C, imm32:$cc)]>
-                              { let Size = 8; }
-
-def BRcc_ru6_p : PseudoInstARC<(outs),
-                               (ins btarget:$T, GPR32:$B, i32imm:$C, ccond:$cc),
-                               "pbr$cc\t$B, $C, $T",
-                               [(ARCbrcc bb:$T, i32:$B, immU6:$C, imm32:$cc)]>
-                               { let Size = 8; }
-}
+let isBranch = 1, isTerminator = 1 in {
+
+  // Unconditional branch.
+  let isBarrier = 1 in
+  def BR : F32_BR0_UCOND_FAR<(outs), (ins btargetS25:$S25),
+                             "b\t$S25", [(br bb:$S25)]>;
+
+  let Uses=[STATUS32] in
+  // Conditional branch.
+  def Bcc : F32_BR0_COND<(outs), (ins btargetS21:$S21, ccond:$cc),
+                         "b$cc\t$S21", []>;
+
+  // Compare and branch (limited range).
+  def BRcc_rr  : F32_BR1_BCC<(outs),
+                             (ins btargetS9:$S9, GPR32:$B, GPR32:$C, brccond:$cc),
+                             "br$cc\t$B, $C, $S9", 0, []>;
+  def BRcc_ru6 : F32_BR1_BCC<(outs),
+                             (ins btargetS9:$S9, GPR32:$B, immU6:$C, brccond:$cc),
+                             "br$cc\t$B, $C, $S9", 1, []>;
+
+  // Pseudo compare and branch.
+  // After register allocation, this can expand into either a limited range
+  // Compare and branch (BRcc), or into CMP + Bcc.
+  // At worst, this expands into 2 4-byte instructions.
+  def BRcc_rr_p : PseudoInstARC<(outs),
+                                (ins btarget:$T, GPR32:$B, GPR32:$C, ccond:$cc),
+                                "pbr$cc\t$B, $C, $T", 
+                                [(ARCbrcc bb:$T, i32:$B, i32:$C, imm32:$cc)]>
+                                { let Size = 8; }
+
+  def BRcc_ru6_p : PseudoInstARC<(outs),
+                                 (ins btarget:$T, GPR32:$B, i32imm:$C, ccond:$cc),
+                                 "pbr$cc\t$B, $C, $T",
+                                 [(ARCbrcc bb:$T, i32:$B, immU6:$C, imm32:$cc)]>
+                                 { let Size = 8; }
+} // let isBranch, isTerminator
 
 // Indirect, unconditional Jump.
-let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
+let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in
 def J :  F32_DOP_RR<0b00100, 0b100000, 0,
                (outs), (ins GPR32:$C),
                "j\t[$C]", [(brind i32:$C)]>;
-}
 
 // Call instructions.
-let isCall = 1, Defs = [BLINK], Uses = [SP] in {
-// Direct unconditional call.
-def BL : F32_BR1_BL_UCOND_FAR<(outs), (ins calltargetS25:$S25),
-                    "bl\t$S25", [(ARCBranchLink tglobaladdr:$S25)]>;
-
-// Indirect unconditional call.
-let isIndirectBranch = 1, Defs = [BLINK], Uses = [SP] in {
-def JL : F32_DOP_RR<0b00100, 0b100010, 0, (outs), (ins GPR32:$C),
-                   "jl\t[$C]", [(ARCJumpLink i32:$C)]>;
-}
-}
+let isCall = 1, isBarrier = 1, Defs = [BLINK], Uses = [SP] in {
+  // Direct unconditional call.
+  def BL : F32_BR1_BL_UCOND_FAR<(outs), (ins calltargetS25:$S25),
+                      "bl\t$S25", [(ARCBranchLink tglobaladdr:$S25)]>;
+
+  // Indirect unconditional call.
+  let isIndirectBranch = 1 in
+  def JL : F32_DOP_RR<0b00100, 0b100010, 0, (outs), (ins GPR32:$C),
+                     "jl\t[$C]", [(ARCJumpLink i32:$C)]>;
+} // let isCall, isBarrier, Defs, Uses
 
 // Pattern to generate BL instruction.
 def : Pat<(ARCBranchLink texternalsym:$dst), (BL texternalsym:$dst)>;
 
 // Return from call.
-let isReturn = 1, isTerminator = 1, isBarrier = 1  in {
+let isReturn = 1, isTerminator = 1, isBarrier = 1  in
 // This is a specialized 2-byte instruction that doesn't generalize
 // to any larger 2-byte class, so go ahead and define it here.
 def J_S_BLINK : InstARC<2, (outs), (ins), "j_s\t[%blink]", [(ret)]> {
   let Inst{15-0} = 0b0111111011100000;
 }
-}
 
 //----------------------------------------------------------------------------
-// Load/Store instructions.
+// Compact stack-based operations.
 //----------------------------------------------------------------------------
 
 // 2-byte push/pop blink instructions commonly used for prolog/epilog
 // generation.  These 2 instructions are actually specialized 2-byte
 // format instructions that aren't generalized to a larger 2-byte
 // class, so we might as well have them here.
-let Uses = [BLINK], Defs = [SP] in {
-def PUSH_S_BLINK : InstARC<2, (outs), (ins),
-                             "push_s\t%blink", []> {
-  let Inst{15-0} = 0b1100000011110001;
+let Uses = [BLINK], Defs = [SP] in
+def PUSH_S_BLINK : F16_SP_OPS_buconst<0b111, "push_s">;
+
+let Defs = [BLINK, SP] in
+def POP_S_BLINK : F16_SP_OPS_buconst<0b110, "pop_s">;
+
+def PUSH_S_r : F16_SP_OPS_uconst<0b110,
+  (outs), (ins GPR32Reduced:$b3), "push_s">;
+def POP_S_r : F16_SP_OPS_uconst<0b111,
+  (outs GPR32Reduced:$b3), (ins), "pop_s">;
+
+def SP_SUB_SP_S : F16_SP_OPS_bconst<0b001, "sub_s">;
+def SP_ADD_SP_S : F16_SP_OPS_bconst<0b000, "add_s">;
+def SP_ADD_S : F16_SP_OPS_u7_aligned<0b100,
+                (outs GPR32Reduced:$b3), (ins immU<7>:$u7),
+                "add_s\t$b3, %sp, $u7">;
+
+def SP_LD_S : F16_SP_LD<0b000, "ld_s">;
+def SP_LDB_S : F16_SP_LD<0b001, "ldb_s">;
+def SP_ST_S : F16_SP_ST<0b010, "st_s">;
+def SP_STB_S : F16_SP_ST<0b011, "stb_s">;
+
+def LEAVE_S : F16_SP_OPS<0b110,
+  (outs), (ins immU<7>:$u7), "leave_s\t$u7"> {
+
+  bits<7> u7;
+  
+  let fieldB = u7{6-4};
+  let fieldU{4-1} = u7{3-0};
+  let fieldU{0} = 0b0;
+}
+
+def ENTER_S : F16_SP_OPS<0b111,
+  (outs), (ins immU<6>:$u6), "enter_s\t$u6"> {
+
+  bits<6> u6;
+  
+  let fieldB{2} = 0;
+  let fieldB{1-0} = u6{5-4};
+  let fieldU{4-1} = u6{3-0};
+  let fieldU{0} = 0b0;
 }
+
+//----------------------------------------------------------------------------
+// Compact Move/Load instructions.
+//----------------------------------------------------------------------------
+class COMPACT_MOV_S :
+  F16_COMPACT<0b0, (outs GPR32:$g), (ins GPR32:$h),
+          "mov_s\t$g, $h"> {  
+  let DecoderMethod = "DecodeMoveHRegInstruction";
 }
 
-let Defs = [BLINK, SP] in {
-def POP_S_BLINK : InstARC<2, (outs), (ins),
-                             "pop_s\t%blink", []> {
-  let Inst{15-0} = 0b1100000011010001;
+def COMPACT_MOV_S_limm : COMPACT_MOV_S {
+  bits<32> LImm;  
+  let Inst{47-16} = LImm;
+
+  bits<5> LImmReg = 0b11110;  
+  let Inst{7-5} = LImmReg{2-0};
+  let Inst{1-0} = LImmReg{4-3};
+
+  let Size = 6;  
 }
+
+def COMPACT_MOV_S_hreg : COMPACT_MOV_S;
+
+def COMPACT_LD_S :
+  F16_COMPACT<0b1, (outs GPR32:$r), (ins GPR32:$h, immU<5>:$u5),
+          "ld_s\t$r, [$h, $u5]"> {
+  bits<5> u5;
+  bits<2> r;
+
+  let Inst{10} = u5{4};
+  let Inst{9-8} = r;
+  let Inst{4-3} = u5{3-2};
+  let u5{1-0} = 0b00;
 }
 
+//----------------------------------------------------------------------------
+// Compact Load/Add/Sub.
+//----------------------------------------------------------------------------
+def LD_S_AS_rrr : F16_LD_SUB<0b0, "ld_s.as\t$a, [$b, $c]">;
+def SUB_S_rrr : F16_LD_SUB<0b1, "sub_s\t$a, $b, $c">;
+def ADD_S_rru6 : F16_ADD;
+
+//----------------------------------------------------------------------------
+// Compact Load/Store.
+//----------------------------------------------------------------------------
+def LD_S_s11 : F16_LD_ST_s11<0b0, "ld_s\t%r1, [%gp, $s11]">;
+def ST_S_s11 : F16_LD_ST_s11<0b1, "st_s\t%r0, [%gp, $s11]">;
+def LDI_S_u7 : F16_LDI_u7;
+
+//----------------------------------------------------------------------------
+// Indexed Jump or Execute.
+//----------------------------------------------------------------------------
+def JLI_S : F16_JLI_EI<0, "jli_s">;
+def EI_S : F16_JLI_EI<1, "ei_s">;
+
+//----------------------------------------------------------------------------
+// Load/Add Register-Register.
+//----------------------------------------------------------------------------
+def LD_S_rrr : F16_LD_ADD_RR<0b00, "ld_s\t$a, [$b, $c]">;
+def LDB_S_rrr : F16_LD_ADD_RR<0b01, "ldb_s\t$a, [$b, $c]">;
+def LDH_S_rrr : F16_LD_ADD_RR<0b10, "ldh_s\t$a, [$b, $c]">;
+def ADD_S_rrr : F16_LD_ADD_RR<0b11, "add_s\t$a, $b, $c">;
+
+//----------------------------------------------------------------------------
+// Load/Add GP-Relative.
+//----------------------------------------------------------------------------
+def GP_LD_S : F16_GP_LD_ADD<0b00, (ins immS<11>:$s),
+  "ld_s\t%r0, [%gp, $s]"> {
+
+  bits<11> s;
+  let Inst{8-0} = s{10-2};
+  let s{1-0} = 0b00;
+}
+
+def GP_LDB_S : F16_GP_LD_ADD<0b01, (ins immS<9>:$s),
+  "ldb_s\t%r0, [%gp, $s]"> {
+
+  bits<9> s;
+  let Inst{8-0} = s{8-0};
+}
+
+def GP_LDH_S : F16_GP_LD_ADD<0b10, (ins immS<10>:$s),
+  "ldh_s\t%r0, [%gp, $s]"> {
+
+  bits<10> s;
+  let Inst{8-0} = s{9-1};
+  let s{0} = 0b0;
+}
+
+def GP_ADD_S : F16_GP_LD_ADD<0b11, (ins immS<11>:$s),
+  "add_s\t%r0, %gp, $s"> {
+
+  bits<11> s;
+  let Inst{8-0} = s{10-2};
+  let s{1-0} = 0b00;
+}
+
+//----------------------------------------------------------------------------
+// Load PCL-Relative.
+//----------------------------------------------------------------------------
+def PCL_LD : InstARC<2, (outs GPR32:$b), (ins immU<10>:$u10),
+ "ld_s\t$b, [%pcl, $u10]", []> {
+ 
+  bits<3> b; 
+  bits<10> u10; 
+
+  let Inst{15-11} = 0b11010;
+  let Inst{10-8} = b;
+  let Inst{7-0} = u10{9-2};
+  let u10{1-0} = 0b00;
+}
+
+let isBranch = 1 in {
+  //----------------------------------------------------------------------------
+  // Branch on Compare Register with Zero.
+  //----------------------------------------------------------------------------
+  def BREQ_S : F16_BCC_REG<0b0, "breq_s">;
+  def BRNE_S : F16_BCC_REG<0b1, "brne_s">;
+
+  //----------------------------------------------------------------------------
+  // Branch Conditionally.
+  //----------------------------------------------------------------------------
+  let isBarrier = 1 in
+  def B_S : F16_BCC_s10<0b00, "b_s">;
+
+  def BEQ_S : F16_BCC_s10<0b01, "beq_s">;
+  def BNE_S : F16_BCC_s10<0b10, "bne_s">;
+  def BGT_S : F16_BCC_s7<0b000, "bgt_s">;
+  def BGE_S : F16_BCC_s7<0b001, "bge_s">;
+  def BLT_S : F16_BCC_s7<0b010, "blt_s">;
+  def BLE_S : F16_BCC_s7<0b011, "ble_s">;
+  def BHI_S : F16_BCC_s7<0b100, "bhi_s">;
+  def BHS_S : F16_BCC_s7<0b101, "bhs_s">;
+  def BLO_S : F16_BCC_s7<0b110, "blo_s">;
+  def BLS_S : F16_BCC_s7<0b111, "bls_s">;
+} // let isBranch
+
+def BL_S :
+  InstARC<2, (outs), (ins btargetS13:$s13), "bl_s\t$s13", []> {
+
+  let Inst{15-11} = 0b11111;
+  
+  bits<13> s13;
+  let Inst{10-0} = s13{12-2};
+  let s13{1-0} = 0b00;
+  
+  let isCall = 1;
+  let isBarrier = 1;
+}
+
+//----------------------------------------------------------------------------
+// Add/Sub/Shift Register-Immediate.
+//----------------------------------------------------------------------------
+def ADD_S_ru3 : F16_ADD_IMM<0b00,"add_s">;
+def SUB_S_ru3 : F16_ADD_IMM<0b01,"sub_s">;
+def ASL_S_ru3 : F16_ADD_IMM<0b10,"asl_s">;
+def ASR_S_ru3 : F16_ADD_IMM<0b11,"asr_s">;
+
+//----------------------------------------------------------------------------
+// Shift/Subtract/Bit Immediate.
+//----------------------------------------------------------------------------
+def ASL_S_ru5 : F16_SH_SUB_BIT_DST<0b000,"asl_s">;
+def LSR_S_ru5 : F16_SH_SUB_BIT_DST<0b001,"lsr_s">;
+def ASR_S_ru5 : F16_SH_SUB_BIT_DST<0b010,"asr_s">;
+def SUB_S_ru5 : F16_SH_SUB_BIT_DST<0b011,"sub_s">;
+def BSET_S_ru5 : F16_SH_SUB_BIT_DST<0b100,"bset_s">;
+def BCLR_S_ru5 : F16_SH_SUB_BIT_DST<0b101,"bclr_s">;
+def BMSK_S_ru5 : F16_SH_SUB_BIT_DST<0b110,"bmsk_s">;
+def BTST_S_ru5 : F16_SH_SUB_BIT<0b111, "btst_s\t$b, $u5">;
+
+//----------------------------------------------------------------------------
+// Dual Register Operations.
+//----------------------------------------------------------------------------
+def ADD_S_rlimm :
+  F16_OP_HREG_LIMM<0b000, (outs GPR32:$b_s3), (ins i32imm:$LImm),
+          !strconcat("add_s", "\t$b_s3, $b_s3, $LImm")>;
+
+def ADD_S_rr :
+  F16_OP_HREG<0b000, (outs GPR32:$b_s3), (ins GPR32:$h),
+          !strconcat("add_s", "\t$b_s3, $b_s3, $h")>;
+
+def ADD_S_rs3 :
+  F16_OP_HREG<0b001, (outs GPR32:$h), (ins immC<3>:$b_s3),
+          !strconcat("add_s", "\t$h, $h, $b_s3")>;
+
+def ADD_S_limms3 :
+  F16_OP_HREG_LIMM<0b001, (outs), (ins immC<3>:$b_s3, i32imm:$LImm),
+          !strconcat("add_s", "\t0, $LImm, $b_s3")>;
+
+def MOV_S_NE_rlimm :
+  F16_OP_HREG_LIMM<0b111, (outs GPR32:$b_s3), (ins i32imm:$LImm),
+          !strconcat("mov_s.ne", "\t$b_s3, $LImm")>;
+
+def MOV_S_NE_rr :
+  F16_OP_HREG<0b111,(outs GPR32:$b_s3), (ins GPR32:$h),
+          !strconcat("mov_s.ne", "\t$b_s3, $h")>;
+
+def MOV_S_rs3 :
+  F16_OP_HREG<0b011, (outs GPR32:$h), (ins immC<3>:$b_s3),
+          !strconcat("mov_s", "\t$h, $b_s3")>;
+
+def MOV_S_s3 :
+  F16_OP_HREG30<0b011, (outs), (ins immC<3>:$b_s3),
+          !strconcat("mov_s", "\t0, $b_s3")>;
+
+def CMP_S_rlimm :
+  F16_OP_HREG_LIMM<0b100, (outs GPR32:$b_s3), (ins i32imm:$LImm),
+          !strconcat("cmp_s", "\t$b_s3, $LImm")>;
+
+def CMP_S_rr :
+  F16_OP_HREG<0b100, (outs GPR32:$b_s3), (ins GPR32:$h),
+          !strconcat("cmp_s", "\t$b_s3, $h")>;
+
+def CMP_S_rs3 :
+  F16_OP_HREG<0b101, (outs GPR32:$h), (ins immC<3>:$b_s3),
+          !strconcat("cmp_s", "\t$h, $b_s3")>;
+
+def CMP_S_limms3 :
+  F16_OP_HREG_LIMM<0b101, (outs), (ins immC<3>:$b_s3, i32imm:$LImm),
+          !strconcat("cmp_s", "\t$LImm, $b_s3")>;
+
+//----------------------------------------------------------------------------
+// Compact MOV/ADD/CMP Immediate instructions.
+//----------------------------------------------------------------------------
+def MOV_S_u8 :
+  F16_OP_IMM<0b11011, (outs GPR32:$b), (ins immU<8>:$u8),
+          !strconcat("mov_s", "\t$b, $u8")> {
+  bits<8> u8;
+  let Inst{7-0} = u8;
+}
+
+def ADD_S_u7 :
+  F16_OP_U7<0b0, !strconcat("add_s", "\t$b, $b, $u7")>;
+
+def CMP_S_u7 :
+  F16_OP_U7<0b1, !strconcat("cmp_s", "\t$b, $u7")>;
+
+//----------------------------------------------------------------------------
+// Compact Load/Store instructions with offset.
+//----------------------------------------------------------------------------
+def LD_S_OFF :
+  F16_LD_ST_WORD_OFF<0x10, (outs GPR32:$c), (ins GPR32:$b, immU<7>:$off),
+  "ld_s">;
+
+def LDB_S_OFF :
+  F16_LD_ST_BYTE_OFF<0x11, (outs GPR32:$c), (ins GPR32:$b, immU<5>:$off),
+  "ldb_s">;
+
+class F16_LDH_OFF<bits<5> opc, string asmstr> :
+  F16_LD_ST_HALF_OFF<opc, (outs GPR32:$c), (ins GPR32:$b, immU<6>:$off),
+  asmstr>;
+
+def LDH_S_OFF : F16_LDH_OFF<0x12, "ldh_s">;
+def LDH_S_X_OFF : F16_LDH_OFF<0x13, "ldh_s.x">;
+
+def ST_S_OFF :
+  F16_LD_ST_WORD_OFF<0x14, (outs), (ins GPR32:$c, GPR32:$b, immU<7>:$off),
+  "st_s">;
+
+def STB_S_OFF :
+  F16_LD_ST_BYTE_OFF<0x15, (outs), (ins GPR32:$c, GPR32:$b, immU<5>:$off),
+  "stb_s">;
+
+def STH_S_OFF :
+  F16_LD_ST_HALF_OFF<0x16, (outs), (ins GPR32:$c, GPR32:$b, immU<6>:$off),
+  "sth_s">;
+
+//----------------------------------------------------------------------------
+// General compact instructions.
+//----------------------------------------------------------------------------
+def GEN_SUB_S : F16_GEN_DOP<0x02, "sub_s">;
+def GEN_AND_S : F16_GEN_DOP<0x04, "and_s">;
+def GEN_OR_S : F16_GEN_DOP<0x05, "or_s">;
+def GEN_BIC_S : F16_GEN_DOP<0x06, "bic_s">;
+def GEN_XOR_S : F16_GEN_DOP<0x07, "xor_s">;
+def GEN_MPYW_S : F16_GEN_DOP<0x09, "mpyw_s">;
+def GEN_MPYUW_S : F16_GEN_DOP<0x0a, "mpyuw_s">;
+def GEN_TST_S : F16_GEN_DOP_NODST<0x0b, "tst_s">;
+def GEN_MPY_S : F16_GEN_DOP<0x0c, "mpy_s">;
+def GEN_SEXB_S : F16_GEN_DOP_SINGLESRC<0x0d, "sexb_s">;
+def GEN_SEXH_S : F16_GEN_DOP_SINGLESRC<0x0e, "sexh_s">;
+def GEN_EXTB_S : F16_GEN_DOP_SINGLESRC<0x0f, "extb_s">;
+def GEN_EXTH_S : F16_GEN_DOP_SINGLESRC<0x10, "exth_s">;
+def GEN_ABS_S : F16_GEN_DOP_SINGLESRC<0x11, "abs_s">;
+def GEN_NOT_S : F16_GEN_DOP_SINGLESRC<0x12, "not_s">;
+def GEN_NEG_S : F16_GEN_DOP_SINGLESRC<0x13, "neg_s">;
+def GEN_ADD1_S : F16_GEN_DOP<0x14, "add1_s">;
+def GEN_ADD2_S : F16_GEN_DOP<0x15, "add2_s">;
+def GEN_ADD3_S : F16_GEN_DOP<0x16, "add3_s">;
+def GEN_ASL_S : F16_GEN_DOP<0x18, "asl_s">;
+def GEN_LSR_S : F16_GEN_DOP<0x19, "lsr_s">;
+def GEN_ASR_S : F16_GEN_DOP<0x1a, "asr_s">;
+def GEN_AS1L_S : F16_GEN_DOP_SINGLESRC<0x1b, "asl_s">;
+def GEN_AS1R_S : F16_GEN_DOP_SINGLESRC<0x1c, "asr_s">;
+def GEN_LS1R_S : F16_GEN_DOP_SINGLESRC<0x1d, "lsr_s">;
+def GEN_TRAP_S : F16_GEN_DOP_BASE<0x1e, (outs), (ins immU6:$u6),
+  "trap_s\t$u6"> {
+
+  bits<6> u6;
+  let b = u6{5-3};
+  let c = u6{2-0};
+}
+
+def GEN_BRK_S : F16_GEN_DOP_BASE<0x1f, (outs), (ins),
+  "brk_s"> {
+
+  let b = 0b111;
+  let c = 0b111;
+}
+
+let isBarrier = 1 in {
+  let isBranch = 1 in {
+    def GEN_J_S : F16_GEN_SOP<0x0, "j_s\t[$b]">;
+    def GEN_J_S_D : F16_GEN_SOP<0x1, "j_s.d\t[$b]">;
+  } // let isBranch
+
+  let isCall = 1 in {
+    def GEN_JL_S : F16_GEN_SOP<0x2, "jl_s\t[$b]">;
+    def GEN_JL_S_D : F16_GEN_SOP<0x3, "jl_s.d\t[$b]">;
+  } // let isCall
+} // let isBarrier
+
+def GEN_SUB_S_NE : F16_GEN_SOP<0x6, "sub_s.ne\t$b, $b, $b">;
+
+def GEN_NOP_S : F16_GEN_ZOP<0x0, "nop_s">;
+def GEN_UNIMP_S : F16_GEN_ZOP<0x1, "unimp_s">;
+def GEN_SWI_S : F16_GEN_ZOP<0x2, "swi_s">;
+
+let isReturn = 1, isTerminator = 1 in {
+  def GEN_JEQ_S : F16_GEN_ZOP<0x4, "jeq_s\t[%blink]">;
+  def GEN_JNE_S : F16_GEN_ZOP<0x5, "jne_s\t[%blink]">;
+  let isBarrier = 1 in {
+    //def GEN_J_S_BLINK : F16_GEN_ZOP<0x6, "j_s\t[%blink]">;
+    def GEN_J_S_D_BLINK : F16_GEN_ZOP<0x7, "j_s.d\t[%blink]">;
+  } // let isBarrier
+} // let isReturn, isTerminator
+
+//----------------------------------------------------------------------------
+// Load/Store instructions.
+//----------------------------------------------------------------------------
+
 // Load instruction variants:
 // Control bits: x, aa, di, zz
 // x - sign extend.
@@ -412,7 +782,7 @@ multiclass ArcLdInst<bits<2> zz, string
 
   def _AB_rs9 : F32_LD_RS9<0, 0b10, 0, zz,
                       (outs GPR32:$addrout, GPR32:$A),
-                      (ins GPR32:$B, immS9:$S9),
+                      (ins GPR32:$B, immS<9>:$S9),
                       !strconcat(asmop, ".ab\t$A, [$B,$S9]"), []>
     { let Constraints = "$addrout = $B"; }
   }
@@ -472,7 +842,7 @@ multiclass ArcStInst<bits<2> zz, string
                          !strconcat(asmop, "\t$C, [$addr]"), []>;
 
   def _AW_rs9 : F32_ST_RS9<0b01, 0, zz, (outs GPR32:$addrout),
-                      (ins GPR32:$C, GPR32:$B, immS9:$S9),
+                      (ins GPR32:$C, GPR32:$B, immS<9>:$S9),
                       !strconcat(asmop, ".aw\t$C, [$B,$S9]"), []>
     { let Constraints = "$addrout = $B"; }
   }

Modified: llvm/trunk/lib/Target/ARC/Disassembler/ARCDisassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARC/Disassembler/ARCDisassembler.cpp?rev=319609&r1=319608&r2=319609&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARC/Disassembler/ARCDisassembler.cpp (original)
+++ llvm/trunk/lib/Target/ARC/Disassembler/ARCDisassembler.cpp Fri Dec  1 21:25:17 2017
@@ -67,6 +67,15 @@ static bool readInstruction64(ArrayRef<u
   return true;
 }
 
+static bool readInstruction48(ArrayRef<uint8_t> Bytes, uint64_t Address,
+                              uint64_t &Size, uint64_t &Insn) {
+  Size = 6;
+  Insn = ((uint64_t)Bytes[0] << 0) | ((uint64_t)Bytes[1] << 8) |
+         ((uint64_t)Bytes[2] << 32) | ((uint64_t)Bytes[3] << 40) |
+         ((uint64_t)Bytes[4] << 16) | ((uint64_t)Bytes[5] << 24);
+  return true;
+}
+
 static bool readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
                               uint64_t &Size, uint32_t &Insn) {
   Size = 2;
@@ -74,32 +83,33 @@ static bool readInstruction16(ArrayRef<u
   return true;
 }
 
-static MCDisassembler::DecodeStatus DecodeS12Operand(MCInst &, unsigned,
-                                                     uint64_t, const void *);
-
-static MCDisassembler::DecodeStatus DecodeS9Operand(MCInst &, unsigned,
-                                                    uint64_t, const void *);
+template <unsigned B>
+static DecodeStatus DecodeSignedOperand(MCInst &Inst, unsigned InsnS,
+                                        uint64_t Address = 0,
+                                        const void *Decoder = nullptr);
 
-static MCDisassembler::DecodeStatus
-DecodeBranchTargetS9(MCInst &, unsigned, uint64_t, const void *);
+template <unsigned B>
+static DecodeStatus DecodeFromCyclicRange(MCInst &Inst, unsigned InsnS,
+                                        uint64_t Address = 0,
+                                        const void *Decoder = nullptr);
 
-static MCDisassembler::DecodeStatus
-DecodeBranchTargetS21(MCInst &, unsigned, uint64_t, const void *);
+template <unsigned B>
+static DecodeStatus DecodeBranchTargetS(MCInst &Inst, unsigned InsnS,
+                                        uint64_t Address, const void *Decoder);
 
-static MCDisassembler::DecodeStatus
-DecodeBranchTargetS25(MCInst &, unsigned, uint64_t, const void *);
+static DecodeStatus DecodeMEMrs9(MCInst &, unsigned, uint64_t, const void *);
 
-static MCDisassembler::DecodeStatus DecodeMEMrs9(MCInst &, unsigned, uint64_t,
-                                                 const void *);
+static DecodeStatus DecodeLdLImmInstruction(MCInst &, uint64_t, uint64_t,
+                                            const void *);
 
-static MCDisassembler::DecodeStatus
-DecodeLdLImmInstruction(MCInst &, uint64_t, uint64_t, const void *);
+static DecodeStatus DecodeStLImmInstruction(MCInst &, uint64_t, uint64_t,
+                                            const void *);
 
-static MCDisassembler::DecodeStatus
-DecodeStLImmInstruction(MCInst &, uint64_t, uint64_t, const void *);
+static DecodeStatus DecodeLdRLImmInstruction(MCInst &, uint64_t, uint64_t,
+                                             const void *);
 
-static MCDisassembler::DecodeStatus
-DecodeLdRLImmInstruction(MCInst &, uint64_t, uint64_t, const void *);
+static DecodeStatus DecodeMoveHRegInstruction(MCInst &Inst, uint64_t, uint64_t,
+                                              const void *);
 
 static const uint16_t GPR32DecoderTable[] = {
     ARC::R0,  ARC::R1,    ARC::R2,  ARC::R3,   ARC::R4,  ARC::R5,  ARC::R6,
@@ -115,11 +125,22 @@ static DecodeStatus DecodeGPR32RegisterC
     DEBUG(dbgs() << "Not a GPR32 register.");
     return MCDisassembler::Fail;
   }
+
   unsigned Reg = GPR32DecoderTable[RegNo];
   Inst.addOperand(MCOperand::createReg(Reg));
   return MCDisassembler::Success;
 }
 
+static DecodeStatus DecodeGBR32ShortRegister(MCInst &Inst, unsigned RegNo,
+                                               uint64_t Address,
+                                               const void *Decoder) {
+  // Enumerates registers from ranges [r0-r3],[r12-r15].
+  if (RegNo > 3)
+    RegNo += 8; // 4 for r12, etc...
+
+  return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
+}
+
 #include "ARCGenDisassemblerTables.inc"
 
 static unsigned decodeCField(unsigned Insn) {
@@ -135,8 +156,8 @@ static unsigned decodeAField(unsigned In
   return fieldFromInstruction(Insn, 0, 6);
 }
 
-static MCDisassembler::DecodeStatus
-DecodeMEMrs9(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Dec) {
+static DecodeStatus DecodeMEMrs9(MCInst &Inst, unsigned Insn, uint64_t Address,
+                                 const void *Dec) {
   // We have the 9-bit immediate in the low bits, 6-bit register in high bits.
   unsigned S9 = Insn & 0x1ff;
   unsigned R = (Insn & (0x7fff & ~0x1ff)) >> 9;
@@ -145,49 +166,59 @@ DecodeMEMrs9(MCInst &Inst, unsigned Insn
   return MCDisassembler::Success;
 }
 
-static MCDisassembler::DecodeStatus DecodeS9Operand(MCInst &Inst,
-                                                    unsigned InsnS9,
-                                                    uint64_t Address,
-                                                    const void *Decoder) {
-  Inst.addOperand(MCOperand::createImm(SignExtend32<9>(0x1ff & InsnS9)));
-  return MCDisassembler::Success;
-}
-
-static MCDisassembler::DecodeStatus DecodeS12Operand(MCInst &Inst,
-                                                     unsigned InsnS12,
-                                                     uint64_t Address,
-                                                     const void *Decoder) {
-  Inst.addOperand(MCOperand::createImm(SignExtend32<12>(0xfff & InsnS12)));
-  return MCDisassembler::Success;
-}
+static bool DecodeSymbolicOperand(MCInst &Inst, uint64_t Address,
+                                  uint64_t Value, const void *Decoder) {
+  static const uint64_t atLeast = 2;
+  // TODO: Try to force emitter to use MCDisassembler* instead of void*.
+  auto Disassembler = static_cast<const MCDisassembler *>(Decoder);
+  return (nullptr != Disassembler &&
+          Disassembler->tryAddingSymbolicOperand(Inst, Value, Address, true, 0,
+                                                 atLeast));
+}
+
+static void DecodeSymbolicOperandOff(MCInst &Inst, uint64_t Address,
+                                     uint64_t Offset, const void *Decoder) {
+  uint64_t nextAddress = Address + Offset;
+
+  if (!DecodeSymbolicOperand(Inst, Address, nextAddress, Decoder))
+    Inst.addOperand(MCOperand::createImm(Offset));
+}
+
+template <unsigned B>
+static DecodeStatus DecodeBranchTargetS(MCInst &Inst, unsigned InsnS,
+                                        uint64_t Address, const void *Decoder) {
 
-static MCDisassembler::DecodeStatus DecodeBranchTargetS9(MCInst &Inst,
-                                                         unsigned S,
-                                                         uint64_t Address,
-                                                         const void *Decoder) {
-  Inst.addOperand(MCOperand::createImm(SignExtend32<9>(S)));
+  static_assert(B > 0, "field is empty");
+  DecodeSymbolicOperandOff(Inst, Address, SignExtend32<B>(InsnS), Decoder);
   return MCDisassembler::Success;
 }
 
-static MCDisassembler::DecodeStatus DecodeBranchTargetS21(MCInst &Inst,
-                                                          unsigned S,
-                                                          uint64_t Address,
-                                                          const void *Decoder) {
-  Inst.addOperand(MCOperand::createImm(SignExtend32<21>(S)));
+template <unsigned B>
+static DecodeStatus DecodeSignedOperand(MCInst &Inst, unsigned InsnS,
+                                        uint64_t /*Address*/,
+                                        const void * /*Decoder*/) {
+
+  static_assert(B > 0, "field is empty");
+  Inst.addOperand(MCOperand::createImm(
+      SignExtend32<B>(maskTrailingOnes<decltype(InsnS)>(B) & InsnS)));
   return MCDisassembler::Success;
 }
 
-static MCDisassembler::DecodeStatus DecodeBranchTargetS25(MCInst &Inst,
-                                                          unsigned S,
-                                                          uint64_t Address,
-                                                          const void *Decoder) {
-  Inst.addOperand(MCOperand::createImm(SignExtend32<25>(S)));
+template <unsigned B>
+static DecodeStatus DecodeFromCyclicRange(MCInst &Inst, unsigned InsnS,
+                                          uint64_t /*Address*/,
+                                          const void * /*Decoder*/) {
+
+  static_assert(B > 0, "field is empty");
+  const unsigned max = (1u << B) - 1;
+  Inst.addOperand(
+      MCOperand::createImm(InsnS < max ? static_cast<int>(InsnS) : -1));
   return MCDisassembler::Success;
 }
 
-static MCDisassembler::DecodeStatus
-DecodeStLImmInstruction(MCInst &Inst, uint64_t Insn, uint64_t Address,
-                        const void *Decoder) {
+static DecodeStatus DecodeStLImmInstruction(MCInst &Inst, uint64_t Insn,
+                                            uint64_t Address,
+                                            const void *Decoder) {
   unsigned SrcC, DstB, LImm;
   DstB = decodeBField(Insn);
   if (DstB != 62) {
@@ -202,9 +233,9 @@ DecodeStLImmInstruction(MCInst &Inst, ui
   return MCDisassembler::Success;
 }
 
-static MCDisassembler::DecodeStatus
-DecodeLdLImmInstruction(MCInst &Inst, uint64_t Insn, uint64_t Address,
-                        const void *Decoder) {
+static DecodeStatus DecodeLdLImmInstruction(MCInst &Inst, uint64_t Insn,
+                                            uint64_t Address,
+                                            const void *Decoder) {
   unsigned DstA, SrcB, LImm;
   DEBUG(dbgs() << "Decoding LdLImm:\n");
   SrcB = decodeBField(Insn);
@@ -220,9 +251,9 @@ DecodeLdLImmInstruction(MCInst &Inst, ui
   return MCDisassembler::Success;
 }
 
-static MCDisassembler::DecodeStatus
-DecodeLdRLImmInstruction(MCInst &Inst, uint64_t Insn, uint64_t Address,
-                         const void *Decoder) {
+static DecodeStatus DecodeLdRLImmInstruction(MCInst &Inst, uint64_t Insn,
+                                             uint64_t Address,
+                                             const void *Decoder) {
   unsigned DstA, SrcB;
   DEBUG(dbgs() << "Decoding LdRLimm\n");
   DstA = decodeAField(Insn);
@@ -237,9 +268,37 @@ DecodeLdRLImmInstruction(MCInst &Inst, u
   return MCDisassembler::Success;
 }
 
-MCDisassembler::DecodeStatus ARCDisassembler::getInstruction(
-    MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address,
-    raw_ostream &vStream, raw_ostream &cStream) const {
+static DecodeStatus DecodeMoveHRegInstruction(MCInst &Inst, uint64_t Insn,
+                                              uint64_t Address,
+                                              const void *Decoder) {
+  DEBUG(dbgs() << "Decoding MOV_S h-register\n");
+  using Field = decltype(Insn);
+  Field h = fieldFromInstruction(Insn, 5, 3) |
+            (fieldFromInstruction(Insn, 0, 2) << 3);
+  Field g = fieldFromInstruction(Insn, 8, 3) |
+            (fieldFromInstruction(Insn, 3, 2) << 3);
+
+  auto DecodeRegisterOrImm = [&Inst, Address, Decoder](Field RegNum,
+                                                       Field Value) {
+    if (30 == RegNum) {
+      Inst.addOperand(MCOperand::createImm(Value));
+      return MCDisassembler::Success;
+    }
+
+    return DecodeGPR32RegisterClass(Inst, RegNum, Address, Decoder);
+  };
+
+  if (MCDisassembler::Success != DecodeRegisterOrImm(g, 0))
+    return MCDisassembler::Fail;
+
+  return DecodeRegisterOrImm(h, Insn >> 16u);
+}
+
+DecodeStatus ARCDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
+                                             ArrayRef<uint8_t> Bytes,
+                                             uint64_t Address,
+                                             raw_ostream &vStream,
+                                             raw_ostream &cStream) const {
   MCDisassembler::DecodeStatus Result;
   if (Bytes.size() < 2) {
     Size = 0;
@@ -262,9 +321,9 @@ MCDisassembler::DecodeStatus ARCDisassem
         return Fail;
       Result =
           decodeInstruction(DecoderTable64, Instr, Insn64, Address, this, STI);
-      if (Result == MCDisassembler::Success) {
+      if (Success == Result) {
         DEBUG(dbgs() << "Successfully decoded 64-bit instruction.");
-        return MCDisassembler::Success;
+        return Result;
       }
       DEBUG(dbgs() << "Not a 64-bit instruction, falling back to 32-bit.");
     }
@@ -274,15 +333,28 @@ MCDisassembler::DecodeStatus ARCDisassem
     }
     // Calling the auto-generated decoder function.
     return decodeInstruction(DecoderTable32, Instr, Insn32, Address, this, STI);
-  }
+  } else {
+    if (Bytes.size() >= 6) {
+      // Attempt to treat as instr. with limm data.
+      uint64_t Insn48;
+      if (!readInstruction48(Bytes, Address, Size, Insn48))
+        return Fail;
+      Result =
+          decodeInstruction(DecoderTable48, Instr, Insn48, Address, this, STI);
+      if (Success == Result) {
+        DEBUG(dbgs() << "Successfully decoded 16-bit instruction with limm.");
+        return Result;
+      }
+      DEBUG(dbgs() << "Not a 16-bit instruction with limm, try without it.");
+    }
 
-  // 16-bit instruction.
-  uint32_t Insn16;
-  if (!readInstruction16(Bytes, Address, Size, Insn16)) {
-    return Fail;
+    uint32_t Insn16;
+    if (!readInstruction16(Bytes, Address, Size, Insn16))
+      return Fail;
+
+    // Calling the auto-generated decoder function.
+    return decodeInstruction(DecoderTable16, Instr, Insn16, Address, this, STI);
   }
-  // Calling the auto-generated decoder function.
-  return decodeInstruction(DecoderTable16, Instr, Insn16, Address, this, STI);
 }
 
 static MCDisassembler *createARCDisassembler(const Target &T,

Modified: llvm/trunk/lib/Target/ARC/InstPrinter/ARCInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARC/InstPrinter/ARCInstPrinter.cpp?rev=319609&r1=319608&r2=319609&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARC/InstPrinter/ARCInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARC/InstPrinter/ARCInstPrinter.cpp Fri Dec  1 21:25:17 2017
@@ -101,6 +101,12 @@ static void printExpr(const MCExpr *Expr
   int Offset = 0;
   const MCSymbolRefExpr *SRE;
 
+  if (const auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
+    OS << "0x";
+    OS.write_hex(CE->getValue());
+    return;
+  }
+
   if (const auto *BE = dyn_cast<MCBinaryExpr>(Expr)) {
     SRE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
     const auto *CE = dyn_cast<MCConstantExpr>(BE->getRHS());

Modified: llvm/trunk/test/MC/Disassembler/ARC/alu.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARC/alu.txt?rev=319609&r1=319608&r2=319609&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARC/alu.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARC/alu.txt Fri Dec  1 21:25:17 2017
@@ -72,4 +72,11 @@
 # CHECK: sub %r0, %r22, %r0
 0x02 0x26 0x00 0x20
 
+# CHECK: sub1 %r3, %fp, %r1
+0x17 0x23 0x43 0x30
 
+# CHECK: sub2 %r3, %fp, 17
+0x58 0x23 0x43 0x34
+
+# CHECK: sub3 %fp, %fp, -1
+0x99 0x23 0xff 0x3f

Added: llvm/trunk/test/MC/Disassembler/ARC/compact.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARC/compact.txt?rev=319609&view=auto
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARC/compact.txt (added)
+++ llvm/trunk/test/MC/Disassembler/ARC/compact.txt Fri Dec  1 21:25:17 2017
@@ -0,0 +1,379 @@
+# RUN: llvm-mc -triple=arc -disassemble %s | FileCheck %s
+
+# CHECK: abs_s %r0, %r1
+0x31 0x78
+
+# CHECK: add_s %r0, %r1, %r2
+0x58 0x61
+
+# CHECK: add_s %r0, %r0, %fp
+0x63 0x70
+
+# CHECK: add_s %fp, %fp, -1
+0x67 0x77
+
+# CHECK: add_s %fp, %fp, 6
+0x67 0x76
+
+# CHECK: add_s %r0, %r0, 287454020
+0xc3 0x70 0x22 0x11 0x44 0x33
+
+# CHECK: add_s 0, 287454020, 4
+0xc7 0x74 0x22 0x11 0x44 0x33
+
+# CHECK: add_s %r0, %sp, 64
+0x90 0xc0
+
+# CHECK: add_s %r0, %r0, 64
+0x40 0xe0
+
+# CHECK: add_s %r0, %r1, 7
+0x07 0x69
+
+# CHECK: add_s %sp, %sp, 64
+0xb0 0xc0
+
+# CHECK: add_s %r0, %gp, -4
+0xff 0xcf
+
+# CHECK: add_s %r0, %r1, 4
+0x0c 0x49
+
+# CHECK: add_s %r1, %r0, 4
+0x8c 0x48
+
+# CHECK: add1_s %r0, %r0, %r1
+0x34 0x78
+
+# CHECK: add2_s %r0, %r0, %r1
+0x35 0x78
+
+# CHECK: add3_s %r0, %r0, %r1
+0x36 0x78
+
+# CHECK: and_s %r0, %r0, %r1
+0x24 0x78
+
+# CHECK: asl_s %r0, %r1
+0x3b 0x78
+
+# CHECK: asl_s %r1, %r0, 4
+0x34 0x68
+
+# CHECK: asl_s %r0, %r0, %r1
+0x38 0x78
+
+# CHECK: asl_s %r0, %r0, 16
+0x10 0xb8
+
+# CHECK: asr_s %r0, %r1
+0x3c 0x78
+
+# CHECK: asr_s %r1, %r0, 4
+0x3c 0x68
+
+# CHECK: asr_s %r0, %r0, %r1
+0x3a 0x78
+
+# CHECK: asr_s %r0, %r0, 16
+0x50 0xb8
+
+# CHECK: b_s 256
+0x80 0xf0
+
+# CHECK: b_s -4
+0xfe 0xf1
+
+# CHECK: beq_s -4
+0xfe 0xf3
+
+# CHECK: bne_s -4
+0xfe 0xf5
+
+# CHECK: bgt_s -4
+0x3e 0xf6
+
+# CHECK: bge_s -4
+0x7e 0xf6
+
+# CHECK: blt_s -4
+0xbe 0xf6
+
+# CHECK: ble_s -4
+0xfe 0xf6
+
+# CHECK: bhi_s -4
+0x3e 0xf7
+
+# CHECK: bhs_s -4
+0x7e 0xf7
+
+# CHECK: blo_s -4
+0xbe 0xf7
+
+# CHECK: bls_s -4
+0xfe 0xf7
+
+# CHECK: bclr_s %r0, %r0, 24
+0xb8 0xb8
+
+# CHECK: bic_s %r0, %r0, %r1
+0x26 0x78
+
+# CHECK: bl_s -256
+0xc0 0xff
+
+# CHECK: bmsk_s %r0, %r0, 24
+0xd8 0xb8
+
+# CHECK: brne_s %r0, 0, -128
+0xc0 0xe8
+
+# CHECK: breq_s %r0, 0, -128
+0x40 0xe8
+
+# CHECK: brk_s
+0xff 0x7f
+
+# CHECK: bset_s %r0, %r0, 24
+0x98 0xb8
+
+# CHECK: btst_s %r0, 24
+0xf8 0xb8
+
+# CHECK: cmp_s %r0, %sp
+0x93 0x70
+
+# CHECK: cmp_s %sp, -1
+0x97 0x77
+
+# CHECK: cmp_s %r2, 64
+0xc0 0xe2
+
+# CHECK: ei_s 512
+0x00 0x5e
+
+# CHECK: enter_s 16
+0xe0 0xc1
+
+# CHECK: extb_s %r0, %r1
+0x2f 0x78
+
+# CHECK: exth_s %r0, %r1
+0x30 0x78
+
+# CHECK: j_s [%r0]
+0x00 0x78
+
+# CHECK: j_s [%blink]
+0xe0 0x7e
+
+# CHECK: j_s.d [%r0]
+0x20 0x78
+
+# CHECK: j_s.d [%blink]
+0xe0 0x7f
+
+# CHECK: jeq_s [%blink]
+0xe0 0x7c
+
+# CHECK: jne_s [%blink]
+0xe0 0x7d
+
+# CHECK: jl_s [%r0]
+0x40 0x78
+
+# CHECK: jl_s.d [%r0]
+0x60 0x78
+
+# CHECK: jli_s 512
+0x00 0x5a
+
+# CHECK: ld_s %r0, [%r1, %r2]
+0x40 0x61
+
+# CHECK: ld_s %r0, [%sp, 64]
+0x10 0xc0
+
+# CHECK: ld_s %r0, [%pcl, 512]
+0x80 0xd0
+
+# CHECK: ld_s %r1, [%r0, 64]
+0x30 0x80
+
+# CHECK: ld_s %r0, [%gp, -1024]
+0x00 0xc9
+
+# CHECK: ldb_s %r0, [%r1, %r2]
+0x48 0x61
+
+# CHECK: ldb_s %r0, [%sp, 64]
+0x30 0xc0
+
+# CHECK: ldb_s %r1, [%r0, 16]
+0x30 0x88
+
+# CHECK: ldb_s %r0, [%gp, -256]
+0x00 0xcb
+
+# CHECK: ldh_s %r0, [%r1, %r2]
+0x50 0x61
+
+# CHECK: ldh_s %r1, [%r0, 32]
+0x30 0x90
+
+# CHECK: ldh_s %r0, [%gp, -512]
+0x00 0xcd
+
+# CHECK: ldh_s.x %r1, [%r0, 32]
+0x30 0x98
+
+# CHECK: ld_s %r0, [%r17, 8]
+0x36 0x40
+
+# CHECK: ld_s %r1, [%r17, 8]
+0x36 0x41
+
+# CHECK: ld_s %r2, [%r17, 8]
+0x36 0x42
+
+# CHECK: ld_s %r3, [%r17, 8]
+0x36 0x43
+
+# CHECK: ld_s.as %r0, [%r1, %r2]
+0x40 0x49
+
+# CHECK: ld_s %r1, [%gp, -1024]
+0x00 0x54
+
+# CHECK: ldi_s %r0, [64]
+0x88 0x50
+
+# CHECK: leave_s 16
+0xc0 0xc1
+
+# CHECK: lsr_s %r0, %r1
+0x3d 0x78
+
+# CHECK: lsr_s %r0, %r0, %r1
+0x39 0x78
+
+# CHECK: lsr_s %r0, %r0, 16
+0x30 0xb8
+
+# CHECK: mov_s %r17, -1
+0x2e 0x77
+
+# CHECK: mov_s 0, 5
+0xcf 0x75
+
+# CHECK: mov_s.ne %r0, %r17
+0x3e 0x70
+
+# CHECK: mov_s.ne %r0, 1024
+0xdf 0x70 0x00 0x00 0x00 0x04
+
+# CHECK: mov_s %r0, 128
+0x80 0xd8
+
+# CHECK: mov_s %r16, %r17
+0x32 0x40
+
+# CHECK: mov_s %r16, 1024
+0xd3 0x40 0x00 0x00 0x00 0x04
+
+# CHECK: mov_s 0, %r17
+0x3a 0x46
+
+# CHECK: mov_s 0, 1024
+0xdb 0x46 0x00 0x00 0x00 0x04
+
+# CHECK: mpy_s %r0, %r0, %r1
+0x2c 0x78
+
+# CHECK: mpyuw_s %r0, %r0, %r1
+0x2a 0x78
+
+# CHECK: mpyw_s %r0, %r0, %r1
+0x29 0x78
+
+# CHECK: neg_s %r0, %r1
+0x33 0x78
+
+# CHECK: nop_s
+0xe0 0x78
+
+# CHECK: not_s %r0, %r1
+0x32 0x78
+
+# CHECK: or_s %r0, %r0, %r1
+0x25 0x78
+
+# CHECK: pop_s %r0
+0xe1 0xc0
+
+# CHECK: pop_s %blink
+0xd1 0xc0
+
+# CHECK: push_s %r0
+0xc1 0xc0
+
+# CHECK: push_s %blink
+0xf1 0xc0
+
+# CHECK: sexb_s %r0, %r1
+0x2d 0x78
+
+# CHECK: sexh_s %r0, %r1
+0x2e 0x78
+
+# CHECK: st_s %r0, [%sp, 64]
+0x50 0xc0
+
+# CHECK: st_s %r1, [%r0, 64]
+0x30 0xa0
+
+# CHECK: st_s %r0, [%gp, -1024]
+0x10 0x54
+
+# CHECK: stb_s %r0, [%sp, 64]
+0x70 0xc0
+
+# CHECK: stb_s %r1, [%r0, 16]
+0x30 0xa8
+
+# CHECK: sth_s %r1, [%r0, 32]
+0x30 0xb0
+
+# CHECK: sub_s %r1, %r0, 4
+0x2c 0x68
+
+# CHECK: sub_s.ne %r0, %r0, %r0
+0xc0 0x78
+
+# CHECK: sub_s %r0, %r0, %r1
+0x22 0x78
+
+# CHECK: sub_s %r0, %r0, 16
+0x70 0xb8
+
+# CHECK: sub_s %sp, %sp, 64
+0xb0 0xc1
+
+# CHECK: sub_s %r0, %r1, %r2
+0x50 0x49
+
+# CHECK: swi_s
+0xe0 0x7a
+
+# CHECK: trap_s 32
+0x1e 0x7c
+
+# CHECK: tst_s %r0, %r1
+0x2b 0x78
+
+# CHECK: unimp_s
+0xe0 0x79
+
+# CHECK: xor_s %r0, %r0, %r1
+0x27 0x78

Modified: llvm/trunk/test/MC/Disassembler/ARC/misc.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARC/misc.txt?rev=319609&r1=319608&r2=319609&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/ARC/misc.txt (original)
+++ llvm/trunk/test/MC/Disassembler/ARC/misc.txt Fri Dec  1 21:25:17 2017
@@ -40,3 +40,11 @@
 # CHECK: j [%r3]
 0x20 0x20 0xc0 0x00
 
+# CHECK: seteq %r3, %fp, %r1
+0x38 0x23 0x43 0x30
+
+# CHECK: seteq %r3, %fp, 17
+0x78 0x23 0x43 0x34
+
+# CHECK: seteq %fp, %fp, -1
+0xb8 0x23 0xff 0x3f 




More information about the llvm-commits mailing list