[Sparc] Add support for parsing branch instructions and conditional moves.
authorVenkatraman Govindaraju <venkatra@cs.wisc.edu>
Wed, 8 Jan 2014 06:14:52 +0000 (06:14 +0000)
committerVenkatraman Govindaraju <venkatra@cs.wisc.edu>
Wed, 8 Jan 2014 06:14:52 +0000 (06:14 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198738 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp
lib/Target/Sparc/SparcInstr64Bit.td
lib/Target/Sparc/SparcInstrAliases.td [new file with mode: 0644]
lib/Target/Sparc/SparcInstrInfo.td
test/MC/Disassembler/Sparc/sparc.txt
test/MC/Sparc/sparc-ctrl-instructions.s
test/MC/Sparc/sparc64-ctrl-instructions.s [new file with mode: 0644]

index 8ae10c801cd853d21b8f9aa5e8ec7a5e93c12fa1..cc6c983f58574bf8c2c6a433cc1c8734c13f4cbc 100644 (file)
@@ -537,9 +537,29 @@ SparcAsmParser::parseSparcAsmOperand(SparcOperand *&Op)
     Parser.Lex(); // Eat the '%'.
     unsigned RegNo;
     if (matchRegisterName(Parser.getTok(), RegNo, false, false)) {
+      StringRef name = Parser.getTok().getString();
       Parser.Lex(); // Eat the identifier token.
       E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
-      Op = SparcOperand::CreateReg(RegNo, SparcOperand::rk_None, S, E);
+      switch (RegNo) {
+      default:
+        Op = SparcOperand::CreateReg(RegNo, SparcOperand::rk_None, S, E);
+        break;
+      case Sparc::Y:
+        Op = SparcOperand::CreateToken("%y", S);
+        break;
+
+      case Sparc::ICC:
+        if (name == "xcc")
+          Op = SparcOperand::CreateToken("%xcc", S);
+        else
+          Op = SparcOperand::CreateToken("%icc", S);
+        break;
+
+      case Sparc::FCC:
+        assert(name == "fcc0" && "Cannot handle %fcc other than %fcc0 yet");
+        Op = SparcOperand::CreateToken("%fcc0", S);
+        break;
+      }
       break;
     }
     if (matchSparcAsmModifiers(EVal, E)) {
index 77404f831468ddc47a344795163922973a7637ee..5e39bd6cb1f8bf61d3d770e41afdb973c5697ae7 100644 (file)
@@ -82,6 +82,17 @@ void SparcInstPrinter::printCCOperand(const MCInst *MI, int opNum,
                                      raw_ostream &O)
 {
   int CC = (int)MI->getOperand(opNum).getImm();
+  switch (MI->getOpcode()) {
+  default: break;
+  case SP::FBCOND:
+  case SP::MOVFCCrr:
+  case SP::MOVFCCri:
+  case SP::FMOVS_FCC:
+  case SP::FMOVD_FCC:
+  case SP::FMOVQ_FCC:  // Make sure CC is a fp conditional flag.
+    CC = (CC < 16) ? (CC + 16) : CC;
+    break;
+  }
   O << SPARCCondCodeToString((SPCC::CondCodes)CC);
 }
 
index 7ccbd9ea1dcb351f31677ce8f3b24c70807cde3a..3ff881d7e04cb95ae5343f3b8910bb78898c3681 100644 (file)
@@ -333,32 +333,42 @@ class XBranchSP<dag ins, string asmstr, list<dag> pattern>
 let Predicates = [Is64Bit] in {
 
 let Uses = [ICC] in
-def BPXCC : XBranchSP<(ins brtarget:$imm22, CCOp:$cond),
-                     "b$cond %xcc, $imm22",
-                     [(SPbrxcc bb:$imm22, imm:$cond)]>;
+def BPXCC : XBranchSP<(ins brtarget:$imm19, CCOp:$cond),
+                     "b$cond %xcc, $imm19",
+                     [(SPbrxcc bb:$imm19, imm:$cond)]>;
 
 // Conditional moves on %xcc.
 let Uses = [ICC], Constraints = "$f = $rd" in {
-def MOVXCCrr : Pseudo<(outs IntRegs:$rd),
+let cc = 0b110 in {
+def MOVXCCrr : F4_1<0b101100, (outs IntRegs:$rd),
                       (ins IntRegs:$rs2, IntRegs:$f, CCOp:$cond),
                       "mov$cond %xcc, $rs2, $rd",
                       [(set i32:$rd,
                        (SPselectxcc i32:$rs2, i32:$f, imm:$cond))]>;
-def MOVXCCri : Pseudo<(outs IntRegs:$rd),
-                      (ins i32imm:$i, IntRegs:$f, CCOp:$cond),
-                      "mov$cond %xcc, $i, $rd",
+def MOVXCCri : F4_2<0b101100, (outs IntRegs:$rd),
+                      (ins i32imm:$simm11, IntRegs:$f, CCOp:$cond),
+                      "mov$cond %xcc, $simm11, $rd",
                       [(set i32:$rd,
-                       (SPselectxcc simm11:$i, i32:$f, imm:$cond))]>;
-def FMOVS_XCC : Pseudo<(outs FPRegs:$rd),
+                       (SPselectxcc simm11:$simm11, i32:$f, imm:$cond))]>;
+} // cc
+
+let opf_cc = 0b110 in {
+def FMOVS_XCC : F4_3<0b110101, 0b000001, (outs FPRegs:$rd),
                       (ins FPRegs:$rs2, FPRegs:$f, CCOp:$cond),
                       "fmovs$cond %xcc, $rs2, $rd",
                       [(set f32:$rd,
                        (SPselectxcc f32:$rs2, f32:$f, imm:$cond))]>;
-def FMOVD_XCC : Pseudo<(outs DFPRegs:$rd),
+def FMOVD_XCC : F4_3<0b110101, 0b000010, (outs DFPRegs:$rd),
                       (ins DFPRegs:$rs2, DFPRegs:$f, CCOp:$cond),
                       "fmovd$cond %xcc, $rs2, $rd",
                       [(set f64:$rd,
                        (SPselectxcc f64:$rs2, f64:$f, imm:$cond))]>;
+def FMOVQ_XCC : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd),
+                      (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond),
+                      "fmovq$cond %xcc, $rs2, $rd",
+                      [(set f128:$rd,
+                       (SPselectxcc f128:$rs2, f128:$f, imm:$cond))]>;
+} // opf_cc
 } // Uses, Constraints
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/Target/Sparc/SparcInstrAliases.td b/lib/Target/Sparc/SparcInstrAliases.td
new file mode 100644 (file)
index 0000000..3a489f4
--- /dev/null
@@ -0,0 +1,119 @@
+//===-- SparcInstrAliases.td - Instruction Aliases for Sparc Target -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains instruction aliases for Sparc.
+//===----------------------------------------------------------------------===//
+
+// Instruction aliases for conditional moves.
+
+// mov<cond> <ccreg> rs2, rd
+multiclass cond_mov_alias<string cond, int condVal, string ccreg,
+                          Instruction movrr, Instruction movri,
+                          Instruction fmovs, Instruction fmovd> {
+
+  // mov<cond> (%icc|%xcc|%fcc0), rs2, rd
+  def : InstAlias<!strconcat(!strconcat(!strconcat("mov", cond), ccreg),
+                             ", $rs2, $rd"),
+                  (movrr IntRegs:$rd, IntRegs:$rs2, condVal)>;
+
+  // mov<cond> (%icc|%xcc|%fcc0), simm11, rd
+  def : InstAlias<!strconcat(!strconcat(!strconcat("mov", cond), ccreg),
+                             ", $simm11, $rd"),
+                  (movri IntRegs:$rd, i32imm:$simm11, condVal)>;
+
+  // fmovs<cond> (%icc|%xcc|%fcc0), $rs2, $rd
+  def : InstAlias<!strconcat(!strconcat(!strconcat("fmovs", cond), ccreg),
+                             ", $rs2, $rd"),
+                  (fmovs FPRegs:$rd, FPRegs:$rs2, condVal)>;
+
+  // fmovd<cond> (%icc|%xcc|%fcc0), $rs2, $rd
+  def : InstAlias<!strconcat(!strconcat(!strconcat("fmovd", cond), ccreg),
+                             ", $rs2, $rd"),
+                  (fmovd DFPRegs:$rd, DFPRegs:$rs2, condVal)>;
+}
+
+
+// Instruction aliases for integer conditional branches and moves.
+multiclass int_cond_alias<string cond, int condVal> {
+
+  // b<cond> $imm
+  def : InstAlias<!strconcat(!strconcat("b", cond), " $imm"),
+                  (BCOND brtarget:$imm, condVal)>;
+
+  // b<cond> %xcc, $imm
+  def : InstAlias<!strconcat(!strconcat("b", cond), " %xcc, $imm"),
+                  (BPXCC brtarget:$imm, condVal)>, Requires<[Is64Bit]>;
+
+  defm : cond_mov_alias<cond, condVal, " %icc",
+                            MOVICCrr, MOVICCri,
+                            FMOVS_ICC, FMOVD_ICC>, Requires<[HasV9]>;
+
+  defm : cond_mov_alias<cond, condVal, " %xcc",
+                            MOVXCCrr, MOVXCCri,
+                            FMOVS_XCC, FMOVD_XCC>, Requires<[Is64Bit]>;
+
+  // fmovq<cond> (%icc|%xcc), $rs2, $rd
+  def : InstAlias<!strconcat(!strconcat("fmovq", cond), " %icc, $rs2, $rd"),
+                  (FMOVQ_ICC QFPRegs:$rd, QFPRegs:$rs2, condVal)>,
+                  Requires<[HasV9, HasHardQuad]>;
+  def : InstAlias<!strconcat(!strconcat("fmovq", cond), " %xcc, $rs2, $rd"),
+                  (FMOVQ_XCC QFPRegs:$rd, QFPRegs:$rs2, condVal)>,
+                  Requires<[Is64Bit, HasHardQuad]>;
+
+}
+
+
+// Instruction aliases for floating point conditional branches and moves.
+multiclass fp_cond_alias<string cond, int condVal> {
+
+  // fb<cond> $imm
+  def : InstAlias<!strconcat(!strconcat("fb", cond), " $imm"),
+                  (FBCOND brtarget:$imm, condVal), 0>;
+
+  defm : cond_mov_alias<cond, condVal, " %fcc0",
+                        MOVFCCrr, MOVFCCri,
+                        FMOVS_FCC, FMOVD_FCC>, Requires<[HasV9]>;
+
+  // fmovq<cond> %fcc0, $rs2, $rd
+  def : InstAlias<!strconcat(!strconcat("fmovq", cond), " %fcc0, $rs2, $rd"),
+                  (FMOVQ_ICC QFPRegs:$rd, QFPRegs:$rs2, condVal)>,
+                  Requires<[HasV9, HasHardQuad]>;
+}
+
+defm : int_cond_alias<"a",    0b1000>;
+defm : int_cond_alias<"n",    0b0000>;
+defm : int_cond_alias<"ne",   0b1001>;
+defm : int_cond_alias<"e",    0b0001>;
+defm : int_cond_alias<"g",    0b1010>;
+defm : int_cond_alias<"le",   0b0010>;
+defm : int_cond_alias<"ge",   0b1011>;
+defm : int_cond_alias<"l",    0b0011>;
+defm : int_cond_alias<"gu",   0b1100>;
+defm : int_cond_alias<"leu",  0b0100>;
+defm : int_cond_alias<"cc",   0b1101>;
+defm : int_cond_alias<"cs",   0b0101>;
+defm : int_cond_alias<"pos",  0b1110>;
+defm : int_cond_alias<"neg",  0b0110>;
+defm : int_cond_alias<"vc",   0b1111>;
+defm : int_cond_alias<"vs",   0b0111>;
+
+defm : fp_cond_alias<"u",     0b0111>;
+defm : fp_cond_alias<"g",     0b0110>;
+defm : fp_cond_alias<"ug",    0b0101>;
+defm : fp_cond_alias<"l",     0b0100>;
+defm : fp_cond_alias<"ul",    0b0011>;
+defm : fp_cond_alias<"lg",    0b0010>;
+defm : fp_cond_alias<"ne",    0b0001>;
+defm : fp_cond_alias<"e",     0b1001>;
+defm : fp_cond_alias<"ue",    0b1010>;
+defm : fp_cond_alias<"ge",    0b1011>;
+defm : fp_cond_alias<"uge",   0b1100>;
+defm : fp_cond_alias<"le",    0b1101>;
+defm : fp_cond_alias<"ule",   0b1110>;
+defm : fp_cond_alias<"o",     0b1111>;
index 7808a1aea4ccbc66ef630d475603851e7870a6b5..a884adfee87fd3dd6cfcdb888994903efc4cf66f 100644 (file)
@@ -928,8 +928,9 @@ let Predicates = [HasV9], Constraints = "$f = $rd" in {
     def FMOVQ_ICC
       : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd),
                (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond),
-               "fmovd$cond %icc, $rs2, $rd",
-               [(set f128:$rd, (SPselecticc f128:$rs2, f128:$f, imm:$cond))]>;
+               "fmovq$cond %icc, $rs2, $rd",
+               [(set f128:$rd, (SPselecticc f128:$rs2, f128:$f, imm:$cond))]>,
+               Requires<[HasHardQuad]>;
   }
 
   let Uses = [FCC], opf_cc = 0b000 in {
@@ -946,8 +947,9 @@ let Predicates = [HasV9], Constraints = "$f = $rd" in {
     def FMOVQ_FCC
       : F4_3<0b110101, 0b000011, (outs QFPRegs:$rd),
              (ins QFPRegs:$rs2, QFPRegs:$f, CCOp:$cond),
-             "fmovd$cond %fcc0, $rs2, $rd",
-             [(set f128:$rd, (SPselectfcc f128:$rs2, f128:$f, imm:$cond))]>;
+             "fmovq$cond %fcc0, $rs2, $rd",
+             [(set f128:$rd, (SPselectfcc f128:$rs2, f128:$f, imm:$cond))]>,
+             Requires<[HasHardQuad]>;
   }
 
 }
@@ -1092,3 +1094,4 @@ def : Pat<(atomic_store ADDRri:$dst, i32:$val), (STri ADDRri:$dst, $val)>;
 
 
 include "SparcInstr64Bit.td"
+include "SparcInstrAliases.td"
index 451a871393c5710c7ade11e64317f9c16c35acd5..388dd68717ebb7aab7d59a2bde26aeabbd9565fd 100644 (file)
 
 # CHECK: subxcc %g1, %g2, %g3
 0x86 0xe0 0x40 0x02
+
+# CHECK: ba 4194303
+0x10 0xbf 0xff 0xff
+
+# CHECK: bne 4194303
+0x12 0xbf 0xff 0xff
+
+# CHECK: be 4194303
+0x02 0xbf 0xff 0xff
+
+# CHECK: bg 4194303
+0x14 0xbf 0xff 0xff
+
+# CHECK: ble 4194303
+0x04 0xbf 0xff 0xff
+
+# CHECK: bge 4194303
+0x16 0xbf 0xff 0xff
+
+# CHECK: bl 4194303
+0x06 0xbf 0xff 0xff
+
+# CHECK: bgu 4194303
+0x18 0xbf 0xff 0xff
+
+# CHECK: bleu 4194303
+0x08 0xbf 0xff 0xff
+
+# CHECK: bcc 4194303
+0x1a 0xbf 0xff 0xff
+
+# CHECK: bcs 4194303
+0x0a 0xbf 0xff 0xff
+
+# CHECK: bpos 4194303
+0x1c 0xbf 0xff 0xff
+
+# CHECK: bneg 4194303
+0x0c 0xbf 0xff 0xff
+
+# CHECK: bvc 4194303
+0x1e 0xbf 0xff 0xff
+
+# CHECK: bvs 4194303
+0x0e 0xbf 0xff 0xff
+
+# CHECK: fbu 4194303
+0x0f 0xbf 0xff 0xff
+
+# CHECK: fbg 4194303
+0x0d 0xbf 0xff 0xff
+
+# CHECK: fbug 4194303
+0x0b 0xbf 0xff 0xff
+
+# CHECK: fbl 4194303
+0x09 0xbf 0xff 0xff
+
+# CHECK: fbul 4194303
+0x07 0xbf 0xff 0xff
+
+# CHECK: fblg 4194303
+0x05 0xbf 0xff 0xff
+
+# CHECK: fbne 4194303
+0x03 0xbf 0xff 0xff
+
+# CHECK: fbe 4194303
+0x13 0xbf 0xff 0xff
+
+# CHECK: fbue 4194303
+0x15 0xbf 0xff 0xff
+
+# CHECK: fbge 4194303
+0x17 0xbf 0xff 0xff
+
+# CHECK: fbuge 4194303
+0x19 0xbf 0xff 0xff
+
+# CHECK: fble 4194303
+0x1b 0xbf 0xff 0xff
+
+# CHECK: fbule 4194303
+0x1d 0xbf 0xff 0xff
+
+# CHECK: fbo 4194303
+0x1f 0xbf 0xff 0xff
index b6ea1131ca63c0ca657ca7d6bc766935667cf69f..acedcb46cce2eb9a7d6b323c8bf065ec02ff66f2 100644 (file)
         ! CHECK-NEXT:                ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
         jmp %g1+%lo(sym)
 
+        ! CHECK: ba .BB0      ! encoding: [0x10,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        ba .BB0
+
+        ! CHECK: bne .BB0     ! encoding: [0x12,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        bne .BB0
+
+        ! CHECK: be .BB0      ! encoding: [0x02,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        be .BB0
+
+        ! CHECK: bg .BB0      ! encoding: [0x14,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        bg .BB0
+
+        ! CHECK: ble .BB0      ! encoding: [0x04,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        ble .BB0
+
+        ! CHECK: bge .BB0      ! encoding: [0x16,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        bge .BB0
+
+        ! CHECK: bl .BB0      ! encoding: [0x06,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        bl .BB0
+
+        ! CHECK: bgu .BB0      ! encoding: [0x18,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        bgu .BB0
+
+        ! CHECK: bleu .BB0      ! encoding: [0x08,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        bleu .BB0
+
+        ! CHECK: bcc .BB0      ! encoding: [0x1a,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        bcc .BB0
+
+        ! CHECK: bcs .BB0      ! encoding: [0x0a,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        bcs .BB0
+
+        ! CHECK: bpos .BB0      ! encoding: [0x1c,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        bpos .BB0
+
+        ! CHECK: bneg .BB0      ! encoding: [0x0c,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        bneg .BB0
+
+        ! CHECK: bvc .BB0      ! encoding: [0x1e,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        bvc .BB0
+
+        ! CHECK: bvs .BB0      ! encoding: [0x0e,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        bvs .BB0
+
+        ! CHECK:             fbu .BB0                        ! encoding: [0x0f,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:                                        !   fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        fbu .BB0
+
+        ! CHECK:             fbg .BB0                        ! encoding: [0x0d,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:                                        !   fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        fbg .BB0
+        ! CHECK:             fbug .BB0                       ! encoding: [0x0b,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:                                        !   fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        fbug .BB0
+
+        ! CHECK:             fbl .BB0                        ! encoding: [0x09,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:                                        !   fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        fbl .BB0
+
+        ! CHECK:             fbul .BB0                       ! encoding: [0x07,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:                                        !   fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        fbul .BB0
+
+        ! CHECK:             fblg .BB0                       ! encoding: [0x05,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:                                        !   fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        fblg .BB0
+
+        ! CHECK:             fbne .BB0                       ! encoding: [0x03,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:                                        !   fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        fbne .BB0
+
+        ! CHECK:             fbe .BB0                        ! encoding: [0x13,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:                                        !   fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        fbe .BB0
+
+        ! CHECK:             fbue .BB0                       ! encoding: [0x15,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:                                        !   fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        fbue .BB0
+
+        ! CHECK:             fbge .BB0                       ! encoding: [0x17,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:                                        !   fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        fbge .BB0
+
+        ! CHECK:             fbuge .BB0                      ! encoding: [0x19,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:                                        !   fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        fbuge .BB0
+
+        ! CHECK:             fble .BB0                       ! encoding: [0x1b,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:                                        !   fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        fble .BB0
+
+        ! CHECK:             fbule .BB0                      ! encoding: [0x1d,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:                                        !   fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        fbule .BB0
+
+        ! CHECK:             fbo .BB0                        ! encoding: [0x1f,0b10AAAAAA,A,A]
+        ! CHECK-NEXT:                                        !   fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br22
+        fbo .BB0
diff --git a/test/MC/Sparc/sparc64-ctrl-instructions.s b/test/MC/Sparc/sparc64-ctrl-instructions.s
new file mode 100644 (file)
index 0000000..5d525ef
--- /dev/null
@@ -0,0 +1,235 @@
+! RUN: llvm-mc %s -triple=sparc64-unknown-linux-gnu -show-encoding | FileCheck %s
+
+
+        ! CHECK: bne %xcc, .BB0     ! encoding: [0x12,0b01101AAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
+        bne %xcc, .BB0
+
+        ! CHECK: be %xcc, .BB0      ! encoding: [0x02,0b01101AAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
+        be %xcc, .BB0
+
+        ! CHECK: bg %xcc, .BB0      ! encoding: [0x14,0b01101AAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
+        bg %xcc, .BB0
+
+        ! CHECK: ble %xcc, .BB0      ! encoding: [0x04,0b01101AAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
+        ble %xcc, .BB0
+
+        ! CHECK: bge %xcc, .BB0      ! encoding: [0x16,0b01101AAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
+        bge %xcc, .BB0
+
+        ! CHECK: bl %xcc, .BB0      ! encoding: [0x06,0b01101AAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
+        bl %xcc, .BB0
+
+        ! CHECK: bgu %xcc, .BB0      ! encoding: [0x18,0b01101AAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
+        bgu %xcc, .BB0
+
+        ! CHECK: bleu %xcc, .BB0      ! encoding: [0x08,0b01101AAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
+        bleu %xcc, .BB0
+
+        ! CHECK: bcc %xcc, .BB0      ! encoding: [0x1a,0b01101AAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
+        bcc %xcc, .BB0
+
+        ! CHECK: bcs %xcc, .BB0      ! encoding: [0x0a,0b01101AAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
+        bcs %xcc, .BB0
+
+        ! CHECK: bpos %xcc, .BB0      ! encoding: [0x1c,0b01101AAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
+        bpos %xcc, .BB0
+
+        ! CHECK: bneg %xcc, .BB0      ! encoding: [0x0c,0b01101AAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
+        bneg %xcc, .BB0
+
+        ! CHECK: bvc %xcc, .BB0      ! encoding: [0x1e,0b01101AAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
+        bvc %xcc, .BB0
+
+        ! CHECK: bvs %xcc, .BB0      ! encoding: [0x0e,0b01101AAA,A,A]
+        ! CHECK-NEXT:         ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br19
+        bvs %xcc, .BB0
+
+
+        ! CHECK: movne %icc, %g1, %g2            ! encoding: [0x85,0x66,0x40,0x01]
+        ! CHECK: move %icc, %g1, %g2             ! encoding: [0x85,0x64,0x40,0x01]
+        ! CHECK: movg %icc, %g1, %g2             ! encoding: [0x85,0x66,0x80,0x01]
+        ! CHECK: movle %icc, %g1, %g2            ! encoding: [0x85,0x64,0x80,0x01]
+        ! CHECK: movge %icc, %g1, %g2            ! encoding: [0x85,0x66,0xc0,0x01]
+        ! CHECK: movl %icc, %g1, %g2             ! encoding: [0x85,0x64,0xc0,0x01]
+        ! CHECK: movgu %icc, %g1, %g2            ! encoding: [0x85,0x67,0x00,0x01]
+        ! CHECK: movleu %icc, %g1, %g2           ! encoding: [0x85,0x65,0x00,0x01]
+        ! CHECK: movcc %icc, %g1, %g2            ! encoding: [0x85,0x67,0x40,0x01]
+        ! CHECK: movcs %icc, %g1, %g2            ! encoding: [0x85,0x65,0x40,0x01]
+        ! CHECK: movpos %icc, %g1, %g2           ! encoding: [0x85,0x67,0x80,0x01]
+        ! CHECK: movneg %icc, %g1, %g2           ! encoding: [0x85,0x65,0x80,0x01]
+        ! CHECK: movvc %icc, %g1, %g2            ! encoding: [0x85,0x67,0xc0,0x01]
+        ! CHECK: movvs %icc, %g1, %g2            ! encoding: [0x85,0x65,0xc0,0x01]
+        movne  %icc, %g1, %g2
+        move   %icc, %g1, %g2
+        movg   %icc, %g1, %g2
+        movle  %icc, %g1, %g2
+        movge  %icc, %g1, %g2
+        movl   %icc, %g1, %g2
+        movgu  %icc, %g1, %g2
+        movleu %icc, %g1, %g2
+        movcc  %icc, %g1, %g2
+        movcs  %icc, %g1, %g2
+        movpos %icc, %g1, %g2
+        movneg %icc, %g1, %g2
+        movvc  %icc, %g1, %g2
+        movvs  %icc, %g1, %g2
+
+        ! CHECK: movne %xcc, %g1, %g2            ! encoding: [0x85,0x66,0x50,0x01]
+        ! CHECK: move %xcc, %g1, %g2             ! encoding: [0x85,0x64,0x50,0x01]
+        ! CHECK: movg %xcc, %g1, %g2             ! encoding: [0x85,0x66,0x90,0x01]
+        ! CHECK: movle %xcc, %g1, %g2            ! encoding: [0x85,0x64,0x90,0x01]
+        ! CHECK: movge %xcc, %g1, %g2            ! encoding: [0x85,0x66,0xd0,0x01]
+        ! CHECK: movl %xcc, %g1, %g2             ! encoding: [0x85,0x64,0xd0,0x01]
+        ! CHECK: movgu %xcc, %g1, %g2            ! encoding: [0x85,0x67,0x10,0x01]
+        ! CHECK: movleu %xcc, %g1, %g2           ! encoding: [0x85,0x65,0x10,0x01]
+        ! CHECK: movcc %xcc, %g1, %g2            ! encoding: [0x85,0x67,0x50,0x01]
+        ! CHECK: movcs %xcc, %g1, %g2            ! encoding: [0x85,0x65,0x50,0x01]
+        ! CHECK: movpos %xcc, %g1, %g2           ! encoding: [0x85,0x67,0x90,0x01]
+        ! CHECK: movneg %xcc, %g1, %g2           ! encoding: [0x85,0x65,0x90,0x01]
+        ! CHECK: movvc %xcc, %g1, %g2            ! encoding: [0x85,0x67,0xd0,0x01]
+        ! CHECK: movvs %xcc, %g1, %g2            ! encoding: [0x85,0x65,0xd0,0x01]
+        movne  %xcc, %g1, %g2
+        move   %xcc, %g1, %g2
+        movg   %xcc, %g1, %g2
+        movle  %xcc, %g1, %g2
+        movge  %xcc, %g1, %g2
+        movl   %xcc, %g1, %g2
+        movgu  %xcc, %g1, %g2
+        movleu %xcc, %g1, %g2
+        movcc  %xcc, %g1, %g2
+        movcs  %xcc, %g1, %g2
+        movpos %xcc, %g1, %g2
+        movneg %xcc, %g1, %g2
+        movvc  %xcc, %g1, %g2
+        movvs  %xcc, %g1, %g2
+
+        ! CHECK: movu %fcc0, %g1, %g2            ! encoding: [0x85,0x61,0xc0,0x01]
+        ! CHECK: movg %fcc0, %g1, %g2            ! encoding: [0x85,0x61,0x80,0x01]
+        ! CHECK: movug %fcc0, %g1, %g2           ! encoding: [0x85,0x61,0x40,0x01]
+        ! CHECK: movl %fcc0, %g1, %g2            ! encoding: [0x85,0x61,0x00,0x01]
+        ! CHECK: movul %fcc0, %g1, %g2           ! encoding: [0x85,0x60,0xc0,0x01]
+        ! CHECK: movlg %fcc0, %g1, %g2           ! encoding: [0x85,0x60,0x80,0x01]
+        ! CHECK: movne %fcc0, %g1, %g2           ! encoding: [0x85,0x60,0x40,0x01]
+        ! CHECK: move %fcc0, %g1, %g2            ! encoding: [0x85,0x62,0x40,0x01]
+        ! CHECK: movue %fcc0, %g1, %g2           ! encoding: [0x85,0x62,0x80,0x01]
+        ! CHECK: movge %fcc0, %g1, %g2           ! encoding: [0x85,0x62,0xc0,0x01]
+        ! CHECK: movuge %fcc0, %g1, %g2          ! encoding: [0x85,0x63,0x00,0x01]
+        ! CHECK: movle %fcc0, %g1, %g2           ! encoding: [0x85,0x63,0x40,0x01]
+        ! CHECK: movule %fcc0, %g1, %g2          ! encoding: [0x85,0x63,0x80,0x01]
+        ! CHECK: movo %fcc0, %g1, %g2            ! encoding: [0x85,0x63,0xc0,0x01]
+        movu   %fcc0, %g1, %g2
+        movg   %fcc0, %g1, %g2
+        movug  %fcc0, %g1, %g2
+        movl   %fcc0, %g1, %g2
+        movul  %fcc0, %g1, %g2
+        movlg  %fcc0, %g1, %g2
+        movne  %fcc0, %g1, %g2
+        move   %fcc0, %g1, %g2
+        movue  %fcc0, %g1, %g2
+        movge  %fcc0, %g1, %g2
+        movuge %fcc0, %g1, %g2
+        movle  %fcc0, %g1, %g2
+        movule %fcc0, %g1, %g2
+        movo   %fcc0, %g1, %g2
+
+
+        ! CHECK fmovsne %icc, %f1, %f2          ! encoding: [0x85,0xaa,0x60,0x21]
+        ! CHECK fmovse %icc, %f1, %f2           ! encoding: [0x85,0xa8,0x60,0x21]
+        ! CHECK fmovsg %icc, %f1, %f2           ! encoding: [0x85,0xaa,0xa0,0x21]
+        ! CHECK fmovsle %icc, %f1, %f2          ! encoding: [0x85,0xa8,0xa0,0x21]
+        ! CHECK fmovsge %icc, %f1, %f2          ! encoding: [0x85,0xaa,0xe0,0x21]
+        ! CHECK fmovsl %icc, %f1, %f2           ! encoding: [0x85,0xa8,0xe0,0x21]
+        ! CHECK fmovsgu %icc, %f1, %f2          ! encoding: [0x85,0xab,0x20,0x21]
+        ! CHECK fmovsleu %icc, %f1, %f2         ! encoding: [0x85,0xa9,0x20,0x21]
+        ! CHECK fmovscc %icc, %f1, %f2          ! encoding: [0x85,0xab,0x60,0x21]
+        ! CHECK fmovscs %icc, %f1, %f2          ! encoding: [0x85,0xa9,0x60,0x21]
+        ! CHECK fmovspos %icc, %f1, %f2         ! encoding: [0x85,0xab,0xa0,0x21]
+        ! CHECK fmovsneg %icc, %f1, %f2         ! encoding: [0x85,0xa9,0xa0,0x21]
+        ! CHECK fmovsvc %icc, %f1, %f2          ! encoding: [0x85,0xab,0xe0,0x21]
+        ! CHECK fmovsvs %icc, %f1, %f2          ! encoding: [0x85,0xa9,0xe0,0x21]
+        fmovsne  %icc, %f1, %f2
+        fmovse   %icc, %f1, %f2
+        fmovsg   %icc, %f1, %f2
+        fmovsle  %icc, %f1, %f2
+        fmovsge  %icc, %f1, %f2
+        fmovsl   %icc, %f1, %f2
+        fmovsgu  %icc, %f1, %f2
+        fmovsleu %icc, %f1, %f2
+        fmovscc  %icc, %f1, %f2
+        fmovscs  %icc, %f1, %f2
+        fmovspos %icc, %f1, %f2
+        fmovsneg %icc, %f1, %f2
+        fmovsvc  %icc, %f1, %f2
+        fmovsvs  %icc, %f1, %f2
+
+        ! CHECK fmovsne %xcc, %f1, %f2          ! encoding: [0x85,0xaa,0x70,0x21]
+        ! CHECK fmovse %xcc, %f1, %f2           ! encoding: [0x85,0xa8,0x70,0x21]
+        ! CHECK fmovsg %xcc, %f1, %f2           ! encoding: [0x85,0xaa,0xb0,0x21]
+        ! CHECK fmovsle %xcc, %f1, %f2          ! encoding: [0x85,0xa8,0xb0,0x21]
+        ! CHECK fmovsge %xcc, %f1, %f2          ! encoding: [0x85,0xaa,0xf0,0x21]
+        ! CHECK fmovsl %xcc, %f1, %f2           ! encoding: [0x85,0xa8,0xf0,0x21]
+        ! CHECK fmovsgu %xcc, %f1, %f2          ! encoding: [0x85,0xab,0x30,0x21]
+        ! CHECK fmovsleu %xcc, %f1, %f2         ! encoding: [0x85,0xa9,0x30,0x21]
+        ! CHECK fmovscc %xcc, %f1, %f2          ! encoding: [0x85,0xab,0x70,0x21]
+        ! CHECK fmovscs %xcc, %f1, %f2          ! encoding: [0x85,0xa9,0x70,0x21]
+        ! CHECK fmovspos %xcc, %f1, %f2         ! encoding: [0x85,0xab,0xb0,0x21]
+        ! CHECK fmovsneg %xcc, %f1, %f2         ! encoding: [0x85,0xa9,0xb0,0x21]
+        ! CHECK fmovsvc %xcc, %f1, %f2          ! encoding: [0x85,0xab,0xf0,0x21]
+        ! CHECK fmovsvs %xcc, %f1, %f2          ! encoding: [0x85,0xa9,0xf0,0x21]
+        fmovsne  %xcc, %f1, %f2
+        fmovse   %xcc, %f1, %f2
+        fmovsg   %xcc, %f1, %f2
+        fmovsle  %xcc, %f1, %f2
+        fmovsge  %xcc, %f1, %f2
+        fmovsl   %xcc, %f1, %f2
+        fmovsgu  %xcc, %f1, %f2
+        fmovsleu %xcc, %f1, %f2
+        fmovscc  %xcc, %f1, %f2
+        fmovscs  %xcc, %f1, %f2
+        fmovspos %xcc, %f1, %f2
+        fmovsneg %xcc, %f1, %f2
+        fmovsvc  %xcc, %f1, %f2
+        fmovsvs  %xcc, %f1, %f2
+
+        ! CHECK fmovsu %fcc0, %f1, %f2          ! encoding: [0x85,0xa9,0xc0,0x21]
+        ! CHECK fmovsg %fcc0, %f1, %f2          ! encoding: [0x85,0xa9,0x80,0x21]
+        ! CHECK fmovsug %fcc0, %f1, %f2         ! encoding: [0x85,0xa9,0x40,0x21]
+        ! CHECK fmovsl %fcc0, %f1, %f2          ! encoding: [0x85,0xa9,0x00,0x21]
+        ! CHECK fmovsul %fcc0, %f1, %f2         ! encoding: [0x85,0xa8,0xc0,0x21]
+        ! CHECK fmovslg %fcc0, %f1, %f2         ! encoding: [0x85,0xa8,0x80,0x21]
+        ! CHECK fmovsne %fcc0, %f1, %f2         ! encoding: [0x85,0xa8,0x40,0x21]
+        ! CHECK fmovse %fcc0, %f1, %f2          ! encoding: [0x85,0xaa,0x40,0x21]
+        ! CHECK fmovsue %fcc0, %f1, %f2         ! encoding: [0x85,0xaa,0x80,0x21]
+        ! CHECK fmovsge %fcc0, %f1, %f2         ! encoding: [0x85,0xaa,0xc0,0x21]
+        ! CHECK fmovsuge %fcc0, %f1, %f2        ! encoding: [0x85,0xab,0x00,0x21]
+        ! CHECK fmovsle %fcc0, %f1, %f2         ! encoding: [0x85,0xab,0x40,0x21]
+        ! CHECK fmovsule %fcc0, %f1, %f2        ! encoding: [0x85,0xab,0x80,0x21]
+        ! CHECK fmovso %fcc0, %f1, %f2          ! encoding: [0x85,0xab,0xc0,0x21]
+        fmovsu   %fcc0, %f1, %f2
+        fmovsg   %fcc0, %f1, %f2
+        fmovsug  %fcc0, %f1, %f2
+        fmovsl   %fcc0, %f1, %f2
+        fmovsul  %fcc0, %f1, %f2
+        fmovslg  %fcc0, %f1, %f2
+        fmovsne  %fcc0, %f1, %f2
+        fmovse   %fcc0, %f1, %f2
+        fmovsue  %fcc0, %f1, %f2
+        fmovsge  %fcc0, %f1, %f2
+        fmovsuge %fcc0, %f1, %f2
+        fmovsle  %fcc0, %f1, %f2
+        fmovsule %fcc0, %f1, %f2
+        fmovso   %fcc0, %f1, %f2
+