<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 02/11/2015 11:41 AM, Tom Stellard
      wrote:<br>
    </div>
    <blockquote cite="mid:20150211194147.GB15853@freedesktop.org"
      type="cite">
      <div class="moz-text-plain" wrap="true" graphical-quote="true"
        style="font-family: -moz-fixed; font-size: 12px;"
        lang="x-western">
        <pre wrap="">Hi,

These patches add support for more scalar instructions to the assembler.

-Tom
</pre>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"><legend
          class="mimeAttachmentHeaderName">0001-R600-SI-Remove-some-unused-TableGen-classes.patch</legend></fieldset>
      <br>
      <div class="moz-text-plain" wrap="true" graphical-quote="true"
        style="font-family: -moz-fixed; font-size: 12px;"
        lang="x-western">
        <pre wrap="">From 2c64f439bcddcd154be74cae2faaccb8920a7b0a Mon Sep 17 00:00:00 2001
From: Tom Stellard <a moz-do-not-send="true" class="moz-txt-link-rfc2396E" href="mailto:thomas.stellard@amd.com"><thomas.stellard@amd.com></a>
Date: Thu, 11 Dec 2014 16:18:02 -0500
Subject: [PATCH 1/5] R600/SI: Remove some unused TableGen classes

---
 lib/Target/R600/SIInstrInfo.td | 19 -------------------
 1 file changed, 19 deletions(-)

</pre>
      </div>
    </blockquote>
    LGTM<br>
    <blockquote cite="mid:20150211194147.GB15853@freedesktop.org"
      type="cite"><br>
      <fieldset class="mimeAttachmentHeader"><legend
          class="mimeAttachmentHeaderName">0002-R600-SI-Lowercase-register-names.patch</legend></fieldset>
      <br>
      <div class="moz-text-plain" wrap="true" graphical-quote="true"
        style="font-family: -moz-fixed; font-size: 12px;"
        lang="x-western">
        <pre wrap="">From a24954e7cffcac84c0fca15dea128a5f8d083dc5 Mon Sep 17 00:00:00 2001
From: Tom Stellard <a moz-do-not-send="true" class="moz-txt-link-rfc2396E" href="mailto:thomas.stellard@amd.com"><thomas.stellard@amd.com></a>
Date: Tue, 2 Dec 2014 23:33:30 -0500
Subject: [PATCH 2/5] R600/SI: Lowercase register names

---
 lib/Target/R600/SIRegisterInfo.td | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

</pre>
      </div>
    </blockquote>
    LGTM<br>
    <blockquote cite="mid:20150211194147.GB15853@freedesktop.org"
      type="cite">
      <div class="moz-text-plain" wrap="true" graphical-quote="true"
        style="font-family: -moz-fixed; font-size: 12px;"
        lang="x-western">
        <pre wrap=""><div class="moz-txt-sig">

</div></pre>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"><legend
          class="mimeAttachmentHeaderName">0003-R600-SI-Refactor-SOP1-classes.patch</legend></fieldset>
      <br>
      <div class="moz-text-plain" wrap="true" graphical-quote="true"
        style="font-family: -moz-fixed; font-size: 12px;"
        lang="x-western">
        <pre wrap="">From c0bbcac32c9c59b29b1eef3397568baa5ad2e11a Mon Sep 17 00:00:00 2001
From: Tom Stellard <a moz-do-not-send="true" class="moz-txt-link-rfc2396E" href="mailto:thomas.stellard@amd.com"><thomas.stellard@amd.com></a>
Date: Tue, 9 Dec 2014 16:47:37 -0500
Subject: [PATCH 3/5] R600/SI: Refactor SOP1 classes

---
 lib/Target/R600/SIInstrInfo.td | 45 ++++++++++++++++++------------------------
 1 file changed, 19 insertions(+), 26 deletions(-)

</pre>
      </div>
    </blockquote>
    LGTM<br>
    <br>
    <blockquote cite="mid:20150211194147.GB15853@freedesktop.org"
      type="cite">
      <fieldset class="mimeAttachmentHeader"><legend
          class="mimeAttachmentHeaderName">0004-R600-SI-Add-assembler-support-for-s_load_dword-instr.patch</legend></fieldset>
      <br>
      <div class="moz-text-plain" wrap="true" graphical-quote="true"
        style="font-family: -moz-fixed; font-size: 12px;"
        lang="x-western">
        <pre wrap="">From f87d5c404203037687629c05fddb8a5adc055784 Mon Sep 17 00:00:00 2001
From: Tom Stellard <a moz-do-not-send="true" class="moz-txt-link-rfc2396E" href="mailto:thomas.stellard@amd.com"><thomas.stellard@amd.com></a>
Date: Fri, 14 Nov 2014 06:22:05 -0500
Subject: [PATCH 4/5] R600/SI: Add assembler support for s_load_dword*
 instructions

---
 docs/R600Usage.rst                            |   4 +
 lib/Target/R600/AsmParser/AMDGPUAsmParser.cpp | 161 +++++++++++++++++++++++---
 lib/Target/R600/SIInstrInfo.td                |   4 +-
 test/MC/R600/smrd.s                           |  31 +++++
 4 files changed, 185 insertions(+), 15 deletions(-)
 create mode 100644 test/MC/R600/smrd.s

diff --git a/docs/R600Usage.rst b/docs/R600Usage.rst
index 48a30c8..2282d54 100644
--- a/docs/R600Usage.rst
+++ b/docs/R600Usage.rst
@@ -15,6 +15,10 @@ Assembler
 The assembler is currently a work in progress and not yet complete.  Below
 are the currently supported features.
 
+SMRD Instructions
+-----------------
+The assembler currently supports only the s_load_dword* SMRD instructions.
+
 SOPP Instructions
 -----------------
 
diff --git a/lib/Target/R600/AsmParser/AMDGPUAsmParser.cpp b/lib/Target/R600/AsmParser/AMDGPUAsmParser.cpp
index 3b4ba1a..33cb2bb 100644
--- a/lib/Target/R600/AsmParser/AMDGPUAsmParser.cpp
+++ b/lib/Target/R600/AsmParser/AMDGPUAsmParser.cpp
@@ -27,6 +27,7 @@
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Debug.h"
 
 using namespace llvm;
 
@@ -69,7 +70,8 @@ public:
 class AMDGPUOperand : public MCParsedAsmOperand {
   enum KindTy {
     Token,
-    Immediate
+    Immediate,
+    Register
   } Kind;
 
 public:
@@ -84,16 +86,21 @@ public:
     int64_t Val;
   };
 
+  struct RegOp {
+    unsigned RegNo;
+  };
+
   union {
     TokOp Tok;
     ImmOp Imm;
+    RegOp Reg;
   };
 
   void addImmOperands(MCInst &Inst, unsigned N) const {
     Inst.addOperand(MCOperand::CreateImm(getImm()));
   }
   void addRegOperands(MCInst &Inst, unsigned N) const {
-    llvm_unreachable("addRegOperands");
+    Inst.addOperand(MCOperand::CreateReg(getReg()));
   }
   StringRef getToken() const {
     return StringRef(Tok.Data, Tok.Length);
@@ -111,11 +118,11 @@ public:
   }
 
   bool isReg() const override {
-    return false;
+    return Kind == Register;
   }
 
   unsigned getReg() const override {
-    return 0;
+    return Reg.RegNo;
   }
 
   bool isMem() const override {
@@ -145,13 +152,125 @@ public:
     return Res;
   }
 
+  static std::unique_ptr<AMDGPUOperand> CreateReg(unsigned RegNo, SMLoc S,
+                                                  SMLoc E) {
+    auto Op = llvm::make_unique<AMDGPUOperand>(Register);
+    Op->Reg.RegNo = RegNo;
+    return Op;
+  }
+
   bool isSWaitCnt() const;
 };
 
 }
 
+static unsigned getRegClass(bool IsVgpr, unsigned RegWidth) {
+  if (IsVgpr) {
+    switch (RegWidth) {
+    default: llvm_unreachable("Unknown register width");
+    case 1: return AMDGPU::VGPR_32RegClassID;
+    case 2: return AMDGPU::VReg_64RegClassID;
+    case 3: return AMDGPU::VReg_96RegClassID;
+    case 4: return AMDGPU::VReg_128RegClassID;
+    case 8: return AMDGPU::VReg_256RegClassID;
+    case 16: return AMDGPU::VReg_512RegClassID;
+    }
+  } else {</pre>
      </div>
    </blockquote>
    No need for the else<br>
    <blockquote cite="mid:20150211194147.GB15853@freedesktop.org"
      type="cite">
      <div class="moz-text-plain" wrap="true" graphical-quote="true"
        style="font-family: -moz-fixed; font-size: 12px;"
        lang="x-western">
        <pre wrap="">
+    switch (RegWidth) {
+    default: llvm_unreachable("Unknown register width");
+    case 1: return AMDGPU::SGPR_32RegClassID;
+    case 2: return AMDGPU::SGPR_64RegClassID;
+    case 4: return AMDGPU::SReg_128RegClassID;
+    case 8: return AMDGPU::SReg_256RegClassID;
+    case 16: return AMDGPU::SReg_512RegClassID;
+    }
+  }
+}
+
 bool AMDGPUAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) {
-  return true;
+  const AsmToken Tok = Parser.getTok();
+  StartLoc = Tok.getLoc();
+  EndLoc = Tok.getEndLoc();
+  const StringRef &RegName = Tok.getString();
+  RegNo = 0;
+
+  // Handle special cases
+  if (RegName.equals("vcc_lo"))
+    RegNo = AMDGPU::VCC_LO;
+  else if (RegName.equals("vcc_hi"))
+    RegNo = AMDGPU::VCC_HI;
+  else if (RegName.equals("vcc"))
+    RegNo = AMDGPU::VCC;
+  else if (RegName.equals("exec_lo"))
+    RegNo = AMDGPU::EXEC_LO;
+  else if (RegName.equals("exec_hi"))
+    RegNo = AMDGPU::EXEC_HI;
+  else if (RegName.equals("exec"))
+    RegNo = AMDGPU::EXEC;
+  else if (RegName.equals("m0"))
+    RegNo = AMDGPU::M0;
+  else if (RegName.equals("flat_scr_lo"))
+    RegNo = AMDGPU::FLAT_SCR_LO;
+  else if (RegName.equals("flat_scr_hi"))
+    RegNo = AMDGPU::FLAT_SCR_HI;
+  else if (RegName.equals("flat_scr"))
+    RegNo = AMDGPU::FLAT_SCR;
+  else if (RegName.equals("scc"))
+    RegNo = AMDGPU::SCC;</pre>
      </div>
    </blockquote>
    I think this should be split into a separate function, use
    StringSwitch, and be sorted so that the common registers come first.
    e.g. vcc and exec are frequently used, but I've almost never seen
    the _lo/_hi on it.<br>
    <br>
    <blockquote cite="mid:20150211194147.GB15853@freedesktop.org"
      type="cite">
      <div class="moz-text-plain" wrap="true" graphical-quote="true"
        style="font-family: -moz-fixed; font-size: 12px;"
        lang="x-western">
        <pre wrap="">
+
+  if (RegNo)
+    return false;
+
+  // Match vgprs and sgprs
+  if (RegName[0] != 's' && RegName[0] != 'v')
+    return true;
+
+  bool IsVgpr = RegName[0] == 'v';
+  unsigned RegWidth;
+  unsigned RegIndexInClass;
+  if (RegName.size() > 1) {
+    // We have a 32-bit register
+    RegWidth = 1;
+    if (RegName.substr(1).getAsInteger(10, RegIndexInClass))
+      return true;
+    Parser.Lex();
+  } else {
+    // We have a register greater than 32-bits.
+
+    int64_t RegLo, RegHi;
+    Parser.Lex();
+    if (getLexer().isNot(AsmToken::LBrac))
+      return true;
+
+    Parser.Lex();
+    if (getParser().parseAbsoluteExpression(RegLo))
+      return true;
+
+    if (getLexer().isNot(AsmToken::Colon))
+      return true;
+
+    Parser.Lex();
+    if (getParser().parseAbsoluteExpression(RegHi))
+      return true;
+
+    if (getLexer().isNot(AsmToken::RBrac))
+      return true;
+
+    Parser.Lex();
+    RegWidth = (RegHi - RegLo) + 1;
+    if (IsVgpr) {
+      // VGPR registers aren't aligned.
+      RegIndexInClass = RegLo;
+    } else {
+      // SGPR registers are aligned.  Max alignment is 4 dwords.
+      RegIndexInClass = RegLo / std::min(RegWidth, 4u);
+    }
+  }
+
+  const MCRegisterInfo *TRC = getContext().getRegisterInfo();
+  unsigned RC = getRegClass(IsVgpr, RegWidth);
+  RegNo = TRC->getRegClass(RC).getRegister(RegIndexInClass);
+  return false;
 }
 
 
@@ -206,6 +325,14 @@ AMDGPUAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
       Operands.push_back(AMDGPUOperand::CreateImm(IntVal));
       return MatchOperand_Success;
     }
+    case AsmToken::Identifier: {
+      SMLoc S, E;
+      unsigned RegNo;
+      if (ParseRegister(RegNo, S, E))
+        return MatchOperand_NoMatch;
+      Operands.push_back(AMDGPUOperand::CreateReg(RegNo, S, E));
+      return MatchOperand_Success;
+    }
     default:
       return MatchOperand_NoMatch;
   }
@@ -217,17 +344,23 @@ bool AMDGPUAsmParser::ParseInstruction(ParseInstructionInfo &Info,
   // Add the instruction mnemonic
   Operands.push_back(AMDGPUOperand::CreateToken(Name, NameLoc));
 
-  if (getLexer().is(AsmToken::EndOfStatement))
-    return false;
+  while (!getLexer().is(AsmToken::EndOfStatement)) {
 
-  AMDGPUAsmParser::OperandMatchResultTy Res = parseOperand(Operands, Name);
-  switch (Res) {
-    case MatchOperand_Success: return false;
-    case MatchOperand_ParseFail: return Error(NameLoc,
-                                              "Failed parsing operand");
-    case MatchOperand_NoMatch: return Error(NameLoc, "Not a valid operand");
+    AMDGPUAsmParser::OperandMatchResultTy Res = parseOperand(Operands, Name);
+
+    // Eat the comma if there is one.
+    if (getLexer().is(AsmToken::Comma))
+      Parser.Lex();
+
+    switch (Res) {
+      case MatchOperand_Success: break;
+      case MatchOperand_ParseFail: return Error(getLexer().getLoc(),
+                                                "failed parsing operand.");
+      case MatchOperand_NoMatch: return Error(getLexer().getLoc(),
+                                              "not a valid operand.");
+    }
   }
-  return true;
+  return false;
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/Target/R600/SIInstrInfo.td b/lib/Target/R600/SIInstrInfo.td
index 3dfde3a..ceca467 100644
--- a/lib/Target/R600/SIInstrInfo.td
+++ b/lib/Target/R600/SIInstrInfo.td
@@ -575,7 +575,9 @@ multiclass SMRD_m <bits<5> op, string opName, bit imm, dag outs, dag ins,
 
   def "" : SMRD_Pseudo <opName, outs, ins, pattern>;
 
-  def _si : SMRD_Real_si <op, opName, imm, outs, ins, asm>;
+  let isCodeGenOnly = 0 in {
+    def _si : SMRD_Real_si <op, opName, imm, outs, ins, asm>;
+  }
 
   def _vi : SMRD_Real_vi <{0, 0, 0, op}, opName, imm, outs, ins, asm>;
 }
diff --git a/test/MC/R600/smrd.s b/test/MC/R600/smrd.s
new file mode 100644
index 0000000..d511c42
--- /dev/null
+++ b/test/MC/R600/smrd.s
@@ -0,0 +1,31 @@
+// RUN: llvm-mc -arch=r600 -mcpu=SI  -show-encoding %s | FileCheck %s
+
+s_load_dword s1, s[2:3], 1
+// CHECK: s_load_dword s1, s[2:3], 0x1 ; encoding: [0x01,0x83,0x00,0xc0]
+
+s_load_dword s1, s[2:3], s4
+// CHECK: s_load_dword s1, s[2:3], s4 ; encoding: [0x04,0x82,0x00,0xc0]
+
+s_load_dwordx2 s[2:3], s[2:3], 1
+// CHECK: s_load_dwordx2 s[2:3], s[2:3], 0x1 ; encoding: [0x01,0x03,0x41,0xc0]
+
+s_load_dwordx2 s[2:3], s[2:3], s4
+// CHECK: s_load_dwordx2 s[2:3], s[2:3], s4 ; encoding: [0x04,0x02,0x41,0xc0]
+
+s_load_dwordx4 s[4:7], s[2:3], 1
+// CHECK: s_load_dwordx4 s[4:7], s[2:3], 0x1 ; encoding: [0x01,0x03,0x82,0xc0]
+
+s_load_dwordx4 s[4:7], s[2:3], s4
+// CHECK: s_load_dwordx4 s[4:7], s[2:3], s4 ; encoding: [0x04,0x02,0x82,0xc0]
+
+s_load_dwordx8 s[8:15], s[2:3], 1
+// CHECK: s_load_dwordx8 s[8:15], s[2:3], 0x1 ; encoding: [0x01,0x03,0xc4,0xc0]
+
+s_load_dwordx8 s[8:15], s[2:3], s4
+// CHECK: s_load_dwordx8 s[8:15], s[2:3], s4 ; encoding: [0x04,0x02,0xc4,0xc0]
+
+s_load_dwordx16 s[16:31], s[2:3], 1
+// CHECK: s_load_dwordx16 s[16:31], s[2:3], 0x1 ; encoding: [0x01,0x03,0x08,0xc1]
+
+s_load_dwordx16 s[16:31], s[2:3], s4
+// CHECK: s_load_dwordx16 s[16:31], s[2:3], s4 ; encoding: [0x04,0x02,0x08,0xc1]
<div class="moz-txt-sig">-- 
2.0.4

</div></pre>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"><legend
          class="mimeAttachmentHeaderName">0005-R600-SI-Assembler-support-for-SOP1-instructions.patch</legend></fieldset>
      <br>
      <div class="moz-text-plain" wrap="true" graphical-quote="true"
        style="font-family: -moz-fixed; font-size: 12px;"
        lang="x-western">
        <pre wrap="">From 8c636e2f929eb2b701c133a406003f8e77cb0d7a Mon Sep 17 00:00:00 2001
From: Tom Stellard <a moz-do-not-send="true" class="moz-txt-link-rfc2396E" href="mailto:thomas.stellard@amd.com"><thomas.stellard@amd.com></a>
Date: Fri, 14 Nov 2014 21:24:45 -0500
Subject: [PATCH 5/5] R600/SI: Assembler support for SOP1 instructions

---
 docs/R600Usage.rst                            |   4 +
 lib/Target/R600/AsmParser/AMDGPUAsmParser.cpp |  98 ++++++++++++----
 lib/Target/R600/SIInstrFormats.td             |   1 +
 lib/Target/R600/SIInstrInfo.td                |  20 +++-
 lib/Target/R600/SIInstructions.td             |  24 ++--
 lib/Target/R600/SIRegisterInfo.td             |  13 ++-
 test/MC/R600/sop1-err.s                       |  21 ++++
 test/MC/R600/sop1.s                           | 157 ++++++++++++++++++++++++++
 8 files changed, 301 insertions(+), 37 deletions(-)
 create mode 100644 test/MC/R600/sop1-err.s
 create mode 100644 test/MC/R600/sop1.s

diff --git a/docs/R600Usage.rst b/docs/R600Usage.rst
index 2282d54..5e95b12 100644
--- a/docs/R600Usage.rst
+++ b/docs/R600Usage.rst
@@ -19,6 +19,10 @@ SMRD Instructions
 -----------------
 The assembler currently supports only the s_load_dword* SMRD instructions.
 
+SOP1 Instructions
+-----------------
+All SOP1 instructions are supported.
+
 SOPP Instructions
 -----------------
 
diff --git a/lib/Target/R600/AsmParser/AMDGPUAsmParser.cpp b/lib/Target/R600/AsmParser/AMDGPUAsmParser.cpp
index 33cb2bb..862bb3d 100644
--- a/lib/Target/R600/AsmParser/AMDGPUAsmParser.cpp
+++ b/lib/Target/R600/AsmParser/AMDGPUAsmParser.cpp
@@ -74,6 +74,8 @@ class AMDGPUOperand : public MCParsedAsmOperand {
     Register
   } Kind;
 
+  SMLoc StartLoc, EndLoc;
+
 public:
   AMDGPUOperand(enum KindTy K) : MCParsedAsmOperand(), Kind(K) {}
 
@@ -88,6 +90,7 @@ public:
 
   struct RegOp {
     unsigned RegNo;
+    const MCRegisterInfo *TRI;
   };
 
   union {
@@ -99,12 +102,22 @@ public:
   void addImmOperands(MCInst &Inst, unsigned N) const {
     Inst.addOperand(MCOperand::CreateImm(getImm()));
   }
+
   void addRegOperands(MCInst &Inst, unsigned N) const {
     Inst.addOperand(MCOperand::CreateReg(getReg()));
   }
+
+  void addRegOrImmOperands(MCInst &Inst, unsigned N) const {
+    if (isReg())
+      addRegOperands(Inst, N);
+    else
+      addImmOperands(Inst, N);
+  }
+
   StringRef getToken() const {
     return StringRef(Tok.Data, Tok.Length);
   }
+
   bool isToken() const override {
     return Kind == Token;
   }
@@ -113,6 +126,14 @@ public:
     return Kind == Immediate;
   }
 
+  bool is64BitInlineImm() const {
+    return isImm() && Imm.Val <= -1 && Imm.Val >= -16;
+  }</pre>
      </div>
    </blockquote>
    This doesn't handle the fp64 values<br>
    <blockquote cite="mid:20150211194147.GB15853@freedesktop.org"
      type="cite">
      <div class="moz-text-plain" wrap="true" graphical-quote="true"
        style="font-family: -moz-fixed; font-size: 12px;"
        lang="x-western">
        <pre wrap="">
+
+  bool isImm32Bit() const {
+    return isImm() && isUInt<32>(Imm.Val);
+  }
+
   int64_t getImm() const {
     return Imm.Val;
   }
@@ -125,23 +146,42 @@ public:
     return Reg.RegNo;
   }
 
+  bool isRegOrImm() const {
+    return isReg() || isImm();
+  }
+
+  bool isRegClass(unsigned RCID) const {
+    return Reg.TRI->getRegClass(RCID).contains(getReg());
+  }
+
+  bool isSSrc32() const {
+    return isImm32Bit() || (isReg() && isRegClass(AMDGPU::SReg_32RegClassID));
+  }
+
+  bool isSSrc64() const {
+    return isImm32Bit() || is64BitInlineImm() ||
+           (isReg() && isRegClass(AMDGPU::SReg_64RegClassID));
+  }
+
   bool isMem() const override {
     return false;
   }
 
   SMLoc getStartLoc() const override {
-    return SMLoc();
+    return StartLoc;
   }
 
   SMLoc getEndLoc() const override {
-    return SMLoc();
+    return EndLoc;
   }
 
   void print(raw_ostream &OS) const override { }
 
-  static std::unique_ptr<AMDGPUOperand> CreateImm(int64_t Val) {
+  static std::unique_ptr<AMDGPUOperand> CreateImm(int64_t Val, SMLoc Loc) {
     auto Op = llvm::make_unique<AMDGPUOperand>(Immediate);
     Op->Imm.Val = Val;
+    Op->StartLoc = Loc;
+    Op->EndLoc = Loc;
     return Op;
   }
 
@@ -149,13 +189,19 @@ public:
     auto Res = llvm::make_unique<AMDGPUOperand>(Token);
     Res->Tok.Data = Str.data();
     Res->Tok.Length = Str.size();
+    Res->StartLoc = Loc;
+    Res->EndLoc = Loc;
     return Res;
   }
 
   static std::unique_ptr<AMDGPUOperand> CreateReg(unsigned RegNo, SMLoc S,
-                                                  SMLoc E) {
+                                                  SMLoc E,
+                                                  const MCRegisterInfo *TRI) {
     auto Op = llvm::make_unique<AMDGPUOperand>(Register);
     Op->Reg.RegNo = RegNo;
+    Op->Reg.TRI = TRI;
+    Op->StartLoc = S;
+    Op->EndLoc = E;
     return Op;
   }
 
@@ -282,22 +328,27 @@ bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   MCInst Inst;
 
   switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
-  case Match_Success:
-    Inst.setLoc(IDLoc);
-    Out.EmitInstruction(Inst, STI);
-    return false;
-  case Match_MissingFeature:
-    return Error(IDLoc, "instruction use requires an option to be enabled");
-  case Match_MnemonicFail:
-    return Error(IDLoc, "unrecognized instruction mnemonic");
-  case Match_InvalidOperand: {
-    if (ErrorInfo != ~0ULL) {
-      if (ErrorInfo >= Operands.size())
-        return Error(IDLoc, "too few operands for instruction");
-
+    default: break;
+    case Match_Success:
+      Inst.setLoc(IDLoc);
+      Out.EmitInstruction(Inst, STI);
+      return false;
+    case Match_MissingFeature:
+      return Error(IDLoc, "instruction use requires an option to be enabled");
+    case Match_MnemonicFail:
+        return Error(IDLoc, "unrecognized instruction mnemonic");
+    case Match_InvalidOperand: {
+      SMLoc ErrorLoc = IDLoc;
+      if (ErrorInfo != ~0ULL) {
+        if (ErrorInfo >= Operands.size())
+          return Error(IDLoc, "too few operands for instruction");
+
+      }
+      ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
+      if (ErrorLoc == SMLoc())
+        ErrorLoc = IDLoc;
+      return Error(ErrorLoc, "invalid operand for instruction");
     }
-    return Error(IDLoc, "invalid operand for instruction");
-  }
   }
   llvm_unreachable("Implement any new match types added!");
 }
@@ -319,10 +370,11 @@ AMDGPUAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
 
   switch(getLexer().getKind()) {
     case AsmToken::Integer: {
+      SMLoc S = Parser.getTok().getLoc();
       int64_t IntVal;
       if (getParser().parseAbsoluteExpression(IntVal))
         return MatchOperand_ParseFail;
-      Operands.push_back(AMDGPUOperand::CreateImm(IntVal));
+      Operands.push_back(AMDGPUOperand::CreateImm(IntVal, S));
       return MatchOperand_Success;
     }
     case AsmToken::Identifier: {
@@ -330,7 +382,8 @@ AMDGPUAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
       unsigned RegNo;
       if (ParseRegister(RegNo, S, E))
         return MatchOperand_NoMatch;
-      Operands.push_back(AMDGPUOperand::CreateReg(RegNo, S, E));
+      Operands.push_back(
+          AMDGPUOperand::CreateReg(RegNo, S, E, getContext().getRegisterInfo()));
       return MatchOperand_Success;
     }
     default:
@@ -417,6 +470,7 @@ AMDGPUAsmParser::parseSWaitCntOps(OperandVector &Operands) {
   // expcnt  [6:4]
   // lgkmcnt [10:8]
   int64_t CntVal = 0x77f;
+  SMLoc S = Parser.getTok().getLoc();
 
   switch(getLexer().getKind()) {
     default: return MatchOperand_ParseFail;
@@ -433,7 +487,7 @@ AMDGPUAsmParser::parseSWaitCntOps(OperandVector &Operands) {
       } while(getLexer().isNot(AsmToken::EndOfStatement));
       break;
   }
-  Operands.push_back(AMDGPUOperand::CreateImm(CntVal));
+  Operands.push_back(AMDGPUOperand::CreateImm(CntVal, S));
   return MatchOperand_Success;
 }
 
diff --git a/lib/Target/R600/SIInstrFormats.td b/lib/Target/R600/SIInstrFormats.td
index 16a35ff..611d41c6 100644
--- a/lib/Target/R600/SIInstrFormats.td
+++ b/lib/Target/R600/SIInstrFormats.td
@@ -213,6 +213,7 @@ class SOP1 <dag outs, dag ins, string asm, list<dag> pattern> :
   let mayLoad = 0;
   let mayStore = 0;
   let hasSideEffects = 0;
+  let isCodeGenOnly = 0;
   let SALU = 1;
   let SOP1 = 1;
 }
diff --git a/lib/Target/R600/SIInstrInfo.td b/lib/Target/R600/SIInstrInfo.td
index ceca467..baaecdc 100644
--- a/lib/Target/R600/SIInstrInfo.td
+++ b/lib/Target/R600/SIInstrInfo.td
@@ -381,12 +381,15 @@ class SOP1_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
   SOP1 <outs, ins, "", pattern>,
   SIMCInstr<opName, SISubtarget.NONE> {
   let isPseudo = 1;
+  let isCodeGenOnly = 1;
 }
 
 class SOP1_Real_si <sop1 op, string opName, dag outs, dag ins, string asm> :
   SOP1 <outs, ins, asm, []>,
   SOP1e <op.SI>,
-  SIMCInstr<opName, SISubtarget.SI>;
+  SIMCInstr<opName, SISubtarget.SI> {
+  let isCodeGenOnly = 0;
+}
 
 class SOP1_Real_vi <sop1 op, string opName, dag outs, dag ins, string asm> :
   SOP1 <outs, ins, asm, []>,
@@ -429,6 +432,21 @@ multiclass SOP1_64_0 <sop1 op, string opName, list<dag> pattern> {
   }
 }
 
+// 64-bit input, no output
+multiclass SOP1_1 <sop1 op, string opName, list<dag> pattern> {
+  def "" : SOP1_Pseudo <opName, (outs), (ins SReg_64:$src0), pattern>;
+
+  def _si : SOP1_Real_si <op, opName, (outs), (ins SReg_64:$src0),
+    opName#" $src0"> {
+    let SDST = 0;
+  }
+
+  def _vi : SOP1_Real_vi <op, opName, (outs), (ins SReg_64:$src0),
+    opName#" $src0"> {
+    let SDST = 0;
+  }
+}
+
 // 64-bit input, 32-bit output.
 multiclass SOP1_32_64 <sop1 op, string opName, list<dag> pattern> : SOP1_m <
     op, opName, (outs SReg_32:$dst), (ins SSrc_64:$src0),
diff --git a/lib/Target/R600/SIInstructions.td b/lib/Target/R600/SIInstructions.td
index db9301d..c9f883a 100644
--- a/lib/Target/R600/SIInstructions.td
+++ b/lib/Target/R600/SIInstructions.td
@@ -133,28 +133,28 @@ defm S_BREV_B32 : SOP1_32 <sop1<0x0b, 0x08>, "s_brev_b32",
 defm S_BREV_B64 : SOP1_64 <sop1<0x0c, 0x09>, "s_brev_b64", []>;
 
 let Defs = [SCC] in {
-  //defm S_BCNT0_I32_B32 : SOP1_BCNT0 <sop1<0x0d, 0x0a>, "s_bcnt0_i32_b32", []>;
-  //defm S_BCNT0_I32_B64 : SOP1_BCNT0 <sop1<0x0e, 0x0b>, "s_bcnt0_i32_b64", []>;
+  defm S_BCNT0_I32_B32 : SOP1_32 <sop1<0x0d, 0x0a>, "s_bcnt0_i32_b32", []>;
+  defm S_BCNT0_I32_B64 : SOP1_32_64 <sop1<0x0e, 0x0b>, "s_bcnt0_i32_b64", []>;
   defm S_BCNT1_I32_B32 : SOP1_32 <sop1<0x0f, 0x0c>, "s_bcnt1_i32_b32",
     [(set i32:$dst, (ctpop i32:$src0))]
   >;
   defm S_BCNT1_I32_B64 : SOP1_32_64 <sop1<0x10, 0x0d>, "s_bcnt1_i32_b64", []>;
 } // End Defs = [SCC]
 
-//defm S_FF0_I32_B32 : SOP1_32 <sop1<0x11, 0x0e>, "s_ff0_i32_b32", []>;
-//defm S_FF0_I32_B64 : SOP1_FF0 <sop1<0x12, 0x0f>, "s_ff0_i32_b64", []>;
+defm S_FF0_I32_B32 : SOP1_32 <sop1<0x11, 0x0e>, "s_ff0_i32_b32", []>;
+defm S_FF0_I32_B64 : SOP1_32_64 <sop1<0x12, 0x0f>, "s_ff0_i32_b64", []>;
 defm S_FF1_I32_B32 : SOP1_32 <sop1<0x13, 0x10>, "s_ff1_i32_b32",
   [(set i32:$dst, (cttz_zero_undef i32:$src0))]
 >;
-////defm S_FF1_I32_B64 : SOP1_FF1 <sop1<0x14, 0x11>, "s_ff1_i32_b64", []>;
+defm S_FF1_I32_B64 : SOP1_32_64 <sop1<0x14, 0x11>, "s_ff1_i32_b64", []>;
 
 defm S_FLBIT_I32_B32 : SOP1_32 <sop1<0x15, 0x12>, "s_flbit_i32_b32",
   [(set i32:$dst, (ctlz_zero_undef i32:$src0))]
 >;
 
-//defm S_FLBIT_I32_B64 : SOP1_32 <sop1<0x16, 0x13>, "s_flbit_i32_b64", []>;
+defm S_FLBIT_I32_B64 : SOP1_32_64 <sop1<0x16, 0x13>, "s_flbit_i32_b64", []>;
 defm S_FLBIT_I32 : SOP1_32 <sop1<0x17, 0x14>, "s_flbit_i32", []>;
-//defm S_FLBIT_I32_I64 : SOP1_32 <sop1<0x18, 0x15>, "s_flbit_i32_i64", []>;
+defm S_FLBIT_I32_I64 : SOP1_32_64 <sop1<0x18, 0x15>, "s_flbit_i32_i64", []>;
 defm S_SEXT_I32_I8 : SOP1_32 <sop1<0x19, 0x16>, "s_sext_i32_i8",
   [(set i32:$dst, (sext_inreg i32:$src0, i8))]
 >;
@@ -162,10 +162,10 @@ defm S_SEXT_I32_I16 : SOP1_32 <sop1<0x1a, 0x17>, "s_sext_i32_i16",
   [(set i32:$dst, (sext_inreg i32:$src0, i16))]
 >;
 
-////defm S_BITSET0_B32 : SOP1_BITSET0 <sop1<0x1b, 0x18>, "s_bitset0_b32", []>;
-////defm S_BITSET0_B64 : SOP1_BITSET0 <sop1<0x1c, 0x19>, "s_bitset0_b64", []>;
-////defm S_BITSET1_B32 : SOP1_BITSET1 <sop1<0x1d, 0x1a>, "s_bitset1_b32", []>;
-////defm S_BITSET1_B64 : SOP1_BITSET1 <sop1<0x1e, 0x1b>, "s_bitset1_b64", []>;
+defm S_BITSET0_B32 : SOP1_32 <sop1<0x1b, 0x18>, "s_bitset0_b32", []>;
+defm S_BITSET0_B64 : SOP1_64 <sop1<0x1c, 0x19>, "s_bitset0_b64", []>;
+defm S_BITSET1_B32 : SOP1_32 <sop1<0x1d, 0x1a>, "s_bitset1_b32", []>;
+defm S_BITSET1_B64 : SOP1_64 <sop1<0x1e, 0x1b>, "s_bitset1_b64", []>;
 defm S_GETPC_B64 : SOP1_64_0 <sop1<0x1f, 0x1c>, "s_getpc_b64", []>;
 defm S_SETPC_B64 : SOP1_64 <sop1<0x20, 0x1d>, "s_setpc_b64", []>;
 defm S_SWAPPC_B64 : SOP1_64 <sop1<0x21, 0x1e>, "s_swappc_b64", []>;
@@ -190,7 +190,7 @@ defm S_MOVRELS_B32 : SOP1_32 <sop1<0x2e, 0x2a>, "s_movrels_b32", []>;
 defm S_MOVRELS_B64 : SOP1_64 <sop1<0x2f, 0x2b>, "s_movrels_b64", []>;
 defm S_MOVRELD_B32 : SOP1_32 <sop1<0x30, 0x2c>, "s_movreld_b32", []>;
 defm S_MOVRELD_B64 : SOP1_64 <sop1<0x31, 0x2d>, "s_movreld_b64", []>;
-//defm S_CBRANCH_JOIN : SOP1_ <sop1<0x32, 0x2e>, "s_cbranch_join", []>;
+defm S_CBRANCH_JOIN : SOP1_1 <sop1<0x32, 0x2e>, "s_cbranch_join", []>;
 defm S_MOV_REGRD_B32 : SOP1_32 <sop1<0x33, 0x2f>, "s_mov_regrd_b32", []>;
 let Defs = [SCC] in {
   defm S_ABS_I32 : SOP1_32 <sop1<0x34, 0x30>, "s_abs_i32", []>;
diff --git a/lib/Target/R600/SIRegisterInfo.td b/lib/Target/R600/SIRegisterInfo.td
index 3b0971b..3772c7e 100644
--- a/lib/Target/R600/SIRegisterInfo.td
+++ b/lib/Target/R600/SIRegisterInfo.td
@@ -169,6 +169,11 @@ def VGPR_512 : RegisterTuples<[sub0, sub1, sub2, sub3, sub4, sub5, sub6, sub7,
 //  Register classes used as source and destination
 //===----------------------------------------------------------------------===//
 
+class RegImmMatcher<string name> : AsmOperandClass {
+  let Name = name;
+  let RenderMethod = "addRegOrImmOperands";
+}
+
 // Special register classes for predicates and the M0 register
 def SCCReg : RegisterClass<"AMDGPU", [i32, i1], 32, (add SCC)> {
   let CopyCost = -1; // Theoretically it is possible to read from SCC,
@@ -225,9 +230,13 @@ class RegInlineOperand <RegisterClass rc> : RegisterOperand<rc> {
 //  SSrc_* Operands with an SGPR or a 32-bit immediate
 //===----------------------------------------------------------------------===//
 
-def SSrc_32 : RegImmOperand<SReg_32>;
+def SSrc_32 : RegImmOperand<SReg_32> {
+  let ParserMatchClass = RegImmMatcher<"SSrc32">;
+}
 
-def SSrc_64 : RegImmOperand<SReg_64>;
+def SSrc_64 : RegImmOperand<SReg_64> {
+  let ParserMatchClass = RegImmMatcher<"SSrc64">;
+}
 
 //===----------------------------------------------------------------------===//
 //  SCSrc_* Operands with an SGPR or a inline constant
diff --git a/test/MC/R600/sop1-err.s b/test/MC/R600/sop1-err.s
new file mode 100644
index 0000000..96a4ffe
--- /dev/null
+++ b/test/MC/R600/sop1-err.s
@@ -0,0 +1,21 @@
+// RUN: not llvm-mc -arch=r600 -mcpu=SI %s 2>&1 | FileCheck %s
+
+s_mov_b32 v1, s2
+// CHECK: error: invalid operand for instruction
+
+s_mov_b32 s1, v0
+// CHECK: error: invalid operand for instruction
+
+s_mov_b64 s1, s[0:1]
+// CHECK: error: invalid operand for instruction
+
+s_mov_b64 s[0:1], s1
+// CHECK: error: invalid operand for instruction
+
+// Immediate greater than 32-bits
+s_mov_b32 s1, 0xfffffffff
+// CHECK: error: invalid operand for instruction
+
+// Immediate greater than 32-bits
+s_mov_b64 s[0:1], 0xfffffffff
+// CHECK: error: invalid operand for instruction
diff --git a/test/MC/R600/sop1.s b/test/MC/R600/sop1.s
new file mode 100644
index 0000000..31133e5
--- /dev/null
+++ b/test/MC/R600/sop1.s
@@ -0,0 +1,157 @@
+// RUN: llvm-mc -arch=r600 -mcpu=SI  -show-encoding %s | FileCheck %s
+
+s_mov_b32 s1, s2
+// CHECK: s_mov_b32 s1, s2 ; encoding: [0x02,0x03,0x81,0xbe]
+
+s_mov_b32 s1, 1
+// CHECK: s_mov_b32 s1, 1 ; encoding: [0x81,0x03,0x81,0xbe]
+
+s_mov_b32 s1, 100
+// CHECK: s_mov_b32 s1, 0x64 ; encoding: [0xff,0x03,0x81,0xbe,0x64,0x00,0x00,0x00]
+
+s_mov_b64 s[2:3], s[4:5]
+// CHECK: s_mov_b64 s[2:3], s[4:5] ; encoding: [0x04,0x04,0x82,0xbe]
+
+s_mov_b64 s[2:3], 0xffffffffffffffff
+// CHECK: s_mov_b64 s[2:3], -1 ; encoding: [0xc1,0x04,0x82,0xbe]
+
+s_cmov_b32 s1, s2
+// CHECK: s_cmov_b32 s1, s2 ; encoding: [0x02,0x05,0x81,0xbe]
+
+s_cmov_b64 s[2:3], s[4:5]
+// CHECK: s_cmov_b64 s[2:3], s[4:5] ; encoding: [0x04,0x06,0x82,0xbe]
+
+s_not_b32 s1, s2
+// CHECK: s_not_b32 s1, s2 ; encoding: [0x02,0x07,0x81,0xbe]
+
+s_not_b64 s[2:3], s[4:5]
+// CHECK: s_not_b64 s[2:3], s[4:5] ; encoding: [0x04,0x08,0x82,0xbe]
+
+s_wqm_b32 s1, s2
+// CHECK: s_wqm_b32 s1, s2 ; encoding: [0x02,0x09,0x81,0xbe]
+
+s_wqm_b64 s[2:3], s[4:5]
+// CHECK: s_wqm_b64 s[2:3], s[4:5] ; encoding: [0x04,0x0a,0x82,0xbe]
+
+s_brev_b32 s1, s2
+// CHECK: s_brev_b32 s1, s2 ; encoding: [0x02,0x0b,0x81,0xbe]
+
+s_brev_b64 s[2:3], s[4:5]
+// CHECK: s_brev_b64 s[2:3], s[4:5] ; encoding: [0x04,0x0c,0x82,0xbe]
+
+s_bcnt0_i32_b32 s1, s2
+// CHECK: s_bcnt0_i32_b32 s1, s2 ; encoding: [0x02,0x0d,0x81,0xbe]
+
+s_bcnt0_i32_b64 s1, s[2:3]
+// CHECK: s_bcnt0_i32_b64 s1, s[2:3] ; encoding: [0x02,0x0e,0x81,0xbe]
+
+s_bcnt1_i32_b32 s1, s2
+// CHECK: s_bcnt1_i32_b32 s1, s2 ; encoding: [0x02,0x0f,0x81,0xbe]
+
+s_bcnt1_i32_b64 s1, s[2:3]
+// CHECK: s_bcnt1_i32_b64 s1, s[2:3] ; encoding: [0x02,0x10,0x81,0xbe]
+
+s_ff0_i32_b32 s1, s2
+// CHECK: s_ff0_i32_b32 s1, s2 ; encoding: [0x02,0x11,0x81,0xbe]
+
+s_ff0_i32_b64 s1, s[2:3]
+// CHECK: s_ff0_i32_b64 s1, s[2:3] ; encoding: [0x02,0x12,0x81,0xbe]
+
+s_ff1_i32_b32 s1, s2
+// CHECK: s_ff1_i32_b32 s1, s2 ; encoding: [0x02,0x13,0x81,0xbe]
+
+s_ff1_i32_b64 s1, s[2:3]
+// CHECK: s_ff1_i32_b64 s1, s[2:3] ; encoding: [0x02,0x14,0x81,0xbe]
+
+s_flbit_i32_b32 s1, s2
+// CHECK: s_flbit_i32_b32 s1, s2 ; encoding: [0x02,0x15,0x81,0xbe]
+
+s_flbit_i32_b64 s1, s[2:3]
+// CHECK: s_flbit_i32_b64 s1, s[2:3] ; encoding: [0x02,0x16,0x81,0xbe]
+
+s_flbit_i32 s1, s2
+// CHECK: s_flbit_i32 s1, s2 ; encoding: [0x02,0x17,0x81,0xbe]
+
+s_flbit_i32_i64 s1, s[2:3]
+// CHECK: s_flbit_i32_i64 s1, s[2:3] ; encoding: [0x02,0x18,0x81,0xbe]
+
+s_sext_i32_i8 s1, s2
+// CHECK: s_sext_i32_i8 s1, s2 ; encoding: [0x02,0x19,0x81,0xbe]
+
+s_sext_i32_i16 s1, s2
+// CHECK: s_sext_i32_i16 s1, s2 ; encoding: [0x02,0x1a,0x81,0xbe]
+
+s_bitset0_b32 s1, s2
+// CHECK: s_bitset0_b32 s1, s2 ; encoding: [0x02,0x1b,0x81,0xbe]
+
+s_bitset0_b64 s[2:3], s[4:5]
+// CHECK: s_bitset0_b64 s[2:3], s[4:5] ; encoding: [0x04,0x1c,0x82,0xbe]
+
+s_bitset1_b32 s1, s2
+// CHECK: s_bitset1_b32 s1, s2 ; encoding: [0x02,0x1d,0x81,0xbe]
+
+s_bitset1_b64 s[2:3], s[4:5]
+// CHECK: s_bitset1_b64 s[2:3], s[4:5] ; encoding: [0x04,0x1e,0x82,0xbe]
+
+s_getpc_b64 s[2:3]
+// CHECK: s_getpc_b64 s[2:3] ; encoding: [0x00,0x1f,0x82,0xbe]
+
+s_setpc_b64 s[2:3], s[4:5]
+// CHECK: s_setpc_b64 s[2:3], s[4:5] ; encoding: [0x04,0x20,0x82,0xbe]
+
+s_swappc_b64 s[2:3], s[4:5]
+// CHECK: s_swappc_b64 s[2:3], s[4:5] ; encoding: [0x04,0x21,0x82,0xbe]
+
+s_rfe_b64 s[2:3], s[4:5]
+// CHECK: s_rfe_b64 s[2:3], s[4:5] ; encoding: [0x04,0x22,0x82,0xbe]
+
+s_and_saveexec_b64 s[2:3], s[4:5]
+// CHECK: s_and_saveexec_b64 s[2:3], s[4:5] ; encoding: [0x04,0x24,0x82,0xbe]
+
+s_or_saveexec_b64 s[2:3], s[4:5]
+// CHECK: s_or_saveexec_b64 s[2:3], s[4:5] ; encoding: [0x04,0x25,0x82,0xbe]
+
+s_xor_saveexec_b64 s[2:3], s[4:5]
+// CHECK: s_xor_saveexec_b64 s[2:3], s[4:5] ; encoding: [0x04,0x26,0x82,0xbe]
+
+s_andn2_saveexec_b64 s[2:3], s[4:5]
+// CHECK: s_andn2_saveexec_b64 s[2:3], s[4:5] ; encoding: [0x04,0x27,0x82,0xbe]
+
+s_orn2_saveexec_b64 s[2:3], s[4:5]
+// CHECK: s_orn2_saveexec_b64 s[2:3], s[4:5] ; encoding: [0x04,0x28,0x82,0xbe]
+
+s_nand_saveexec_b64 s[2:3], s[4:5]
+// CHECK: s_nand_saveexec_b64 s[2:3], s[4:5] ; encoding: [0x04,0x29,0x82,0xbe]
+
+s_nor_saveexec_b64 s[2:3], s[4:5]
+// CHECK: s_nor_saveexec_b64 s[2:3], s[4:5] ; encoding: [0x04,0x2a,0x82,0xbe]
+
+s_xnor_saveexec_b64 s[2:3], s[4:5]
+// CHECK: s_xnor_saveexec_b64 s[2:3], s[4:5] ; encoding: [0x04,0x2b,0x82,0xbe]
+
+s_quadmask_b32 s1, s2
+// CHECK: s_quadmask_b32 s1, s2 ; encoding: [0x02,0x2c,0x81,0xbe]
+
+s_quadmask_b64 s[2:3], s[4:5]
+// CHECK: s_quadmask_b64 s[2:3], s[4:5] ; encoding: [0x04,0x2d,0x82,0xbe]
+
+s_movrels_b32 s1, s2
+// CHECK: s_movrels_b32 s1, s2 ; encoding: [0x02,0x2e,0x81,0xbe]
+
+s_movrels_b64 s[2:3], s[4:5]
+// CHECK: s_movrels_b64 s[2:3], s[4:5] ; encoding: [0x04,0x2f,0x82,0xbe]
+
+s_movreld_b32 s1, s2
+// CHECK: s_movreld_b32 s1, s2 ; encoding: [0x02,0x30,0x81,0xbe]
+
+s_movreld_b64 s[2:3], s[4:5]
+// CHECK: s_movreld_b64 s[2:3], s[4:5] ; encoding: [0x04,0x31,0x82,0xbe]
+
+s_cbranch_join s[4:5]
+// CHECK: s_cbranch_join s[4:5] ; encoding: [0x04,0x32,0x80,0xbe]
+
+s_abs_i32 s1, s2
+// CHECK: s_abs_i32 s1, s2 ; encoding: [0x02,0x34,0x81,0xbe]
+
+s_mov_fed_b32 s1, s2
+// CHECK: s_mov_fed_b32 s1, s2 ; encoding: [0x02,0x35,0x81,0xbe]
<div class="moz-txt-sig">-- 
2.0.4

</div></pre>
      </div>
    </blockquote>
    Some cases with literals for other operands in other instructions
    might be useful. The only immediate operands I see are on mov
    instructions / first source operand<br>
  </body>
</html>