From 3955891035024f9d2a3b6fb26f5b7b81f5294c0a Mon Sep 17 00:00:00 2001
From: Nguyen Anh Quynh <aquynh@gmail.com>
Date: Sun, 22 May 2016 16:32:28 +0800
Subject: [PATCH] propagate error from encodeInstruction() back to ks_asm().
 this fixes an issue in #9

---
 llvm/include/llvm/MC/MCCodeEmitter.h          |  3 +-
 llvm/include/llvm/MC/MCELFStreamer.h          |  2 +-
 llvm/include/llvm/MC/MCObjectStreamer.h       |  4 +-
 llvm/include/llvm/MC/MCStreamer.h             |  2 +-
 llvm/lib/MC/MCAssembler.cpp                   |  6 +-
 llvm/lib/MC/MCELFStreamer.cpp                 |  8 ++-
 llvm/lib/MC/MCObjectStreamer.cpp              | 13 ++--
 llvm/lib/MC/MCStreamer.cpp                    |  3 +-
 .../AArch64/AsmParser/AArch64AsmParser.cpp    |  7 +-
 .../MCTargetDesc/AArch64MCCodeEmitter.cpp     |  7 +-
 .../lib/Target/ARM/AsmParser/ARMAsmParser.cpp |  4 +-
 .../ARM/MCTargetDesc/ARMMCCodeEmitter.cpp     |  8 ++-
 .../Hexagon/AsmParser/HexagonAsmParser.cpp    |  3 +-
 .../MCTargetDesc/HexagonMCCodeEmitter.cpp     |  5 +-
 .../MCTargetDesc/HexagonMCCodeEmitter.h       |  3 +-
 .../MCTargetDesc/HexagonMCELFStreamer.h       |  2 +-
 .../Target/Mips/AsmParser/MipsAsmParser.cpp   |  4 +-
 .../Mips/MCTargetDesc/MipsELFStreamer.h       |  2 +-
 .../Mips/MCTargetDesc/MipsMCCodeEmitter.cpp   |  5 +-
 .../Mips/MCTargetDesc/MipsMCCodeEmitter.h     |  3 +-
 .../Target/PowerPC/AsmParser/PPCAsmParser.cpp |  4 +-
 .../PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp |  5 +-
 .../Target/Sparc/AsmParser/SparcAsmParser.cpp |  4 +-
 .../Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp |  9 ++-
 .../SystemZ/AsmParser/SystemZAsmParser.cpp    |  4 +-
 .../MCTargetDesc/SystemZMCCodeEmitter.cpp     |  9 ++-
 .../X86/AsmParser/X86AsmInstrumentation.cpp   |  9 +--
 .../X86/AsmParser/X86AsmInstrumentation.h     |  5 +-
 .../lib/Target/X86/AsmParser/X86AsmParser.cpp | 32 ++++++---
 .../X86/MCTargetDesc/X86MCCodeEmitter.cpp     | 72 +++++++++++++------
 30 files changed, 166 insertions(+), 81 deletions(-)

diff --git a/llvm/include/llvm/MC/MCCodeEmitter.h b/llvm/include/llvm/MC/MCCodeEmitter.h
index f9ca2ad..ac1fed1 100644
--- a/llvm/include/llvm/MC/MCCodeEmitter.h
+++ b/llvm/include/llvm/MC/MCCodeEmitter.h
@@ -38,7 +38,8 @@ public:
   /// stream \p OS.
   virtual void encodeInstruction(MCInst &Inst, raw_ostream &OS,
                                  SmallVectorImpl<MCFixup> &Fixups,
-                                 const MCSubtargetInfo &STI) const = 0;
+                                 const MCSubtargetInfo &STI,
+                                 unsigned int &KsError) const = 0;
 };
 
 } // End llvm namespace
diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h
index ebe439e..f5f5e68 100644
--- a/llvm/include/llvm/MC/MCELFStreamer.h
+++ b/llvm/include/llvm/MC/MCELFStreamer.h
@@ -85,7 +85,7 @@ public:
 private:
   bool isBundleLocked() const;
   void EmitInstToFragment(MCInst &Inst, const MCSubtargetInfo &) override;
-  void EmitInstToData(MCInst &Inst, const MCSubtargetInfo &) override;
+  void EmitInstToData(MCInst &Inst, const MCSubtargetInfo &, unsigned int &KsError) override;
 
   void fixSymbolsInTLSFixups(const MCExpr *expr);
 
diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h
index 7ecc137..d29a7a2 100644
--- a/llvm/include/llvm/MC/MCObjectStreamer.h
+++ b/llvm/include/llvm/MC/MCObjectStreamer.h
@@ -40,7 +40,7 @@ class MCObjectStreamer : public MCStreamer {
   bool EmitDebugFrame;
   SmallVector<MCSymbol *, 2> PendingLabels;
 
-  virtual void EmitInstToData(MCInst &Inst, const MCSubtargetInfo&) = 0;
+  virtual void EmitInstToData(MCInst &Inst, const MCSubtargetInfo&, unsigned int &KsError) = 0;
   void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
   void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
 
@@ -97,7 +97,7 @@ public:
   void EmitSLEB128Value(const MCExpr *Value) override;
   void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
   void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
-  void EmitInstruction(MCInst &Inst, const MCSubtargetInfo& STI) override;
+  void EmitInstruction(MCInst &Inst, const MCSubtargetInfo& STI, unsigned int &KsError) override;
 
   /// \brief Emit an instruction to a special fragment, because this instruction
   /// can change its size during relaxation.
diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index 262c9ba..e9d301a 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -720,7 +720,7 @@ public:
   }
 
   /// \brief Emit the given \p Instruction into the current section.
-  virtual void EmitInstruction(MCInst &Inst, const MCSubtargetInfo &STI);
+  virtual void EmitInstruction(MCInst &Inst, const MCSubtargetInfo &STI, unsigned int &KsError);
 
   /// \brief Set the bundle alignment mode from now on in the section.
   /// The argument is the power of 2 to which the alignment is set. The
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 6184a1f..006f7b5 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -716,7 +716,8 @@ bool MCAssembler::fragmentNeedsRelaxation(const MCRelaxableFragment *F,
 }
 
 bool MCAssembler::relaxInstruction(MCAsmLayout &Layout,
-                                   MCRelaxableFragment &F) {
+                                   MCRelaxableFragment &F)
+{
   if (!fragmentNeedsRelaxation(&F, Layout))
     return false;
 
@@ -735,7 +736,8 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout,
   SmallVector<MCFixup, 4> Fixups;
   SmallString<256> Code;
   raw_svector_ostream VecOS(Code);
-  getEmitter().encodeInstruction(Relaxed, VecOS, Fixups, F.getSubtargetInfo());
+  unsigned int KsError;
+  getEmitter().encodeInstruction(Relaxed, VecOS, Fixups, F.getSubtargetInfo(), KsError);
 
   // Update the fragment.
   F.setInst(Relaxed);
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index c881e14..3445f02 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -472,12 +472,16 @@ void MCELFStreamer::EmitInstToFragment(MCInst &Inst,
 }
 
 void MCELFStreamer::EmitInstToData(MCInst &Inst,
-                                   const MCSubtargetInfo &STI) {
+                                   const MCSubtargetInfo &STI,
+                                   unsigned int &KsError)
+{
   MCAssembler &Assembler = getAssembler();
   SmallVector<MCFixup, 4> Fixups;
   SmallString<256> Code;
   raw_svector_ostream VecOS(Code);
-  Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI);
+  Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI, KsError);
+  if (KsError)
+      return;
 
   for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
     fixSymbolsInTLSFixups(Fixups[i].getValue());
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 4335af9..6fe19f2 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -238,8 +238,10 @@ bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const {
 }
 
 void MCObjectStreamer::EmitInstruction(MCInst &Inst,
-                                       const MCSubtargetInfo &STI) {    // qq
-  MCStreamer::EmitInstruction(Inst, STI);
+                                       const MCSubtargetInfo &STI,
+                                       unsigned int &KsError)
+{
+  MCStreamer::EmitInstruction(Inst, STI, KsError);
 
   MCSection *Sec = getCurrentSectionOnly();
   Sec->setHasInstructions(true);
@@ -252,7 +254,7 @@ void MCObjectStreamer::EmitInstruction(MCInst &Inst,
   // If this instruction doesn't need relaxation, just emit it as data.
   MCAssembler &Assembler = getAssembler();
   if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
-    EmitInstToData(Inst, STI);
+    EmitInstToData(Inst, STI, KsError);
     return;
   }
 
@@ -267,7 +269,7 @@ void MCObjectStreamer::EmitInstruction(MCInst &Inst,
     getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
     while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
       getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed);
-    EmitInstToData(Relaxed, STI);
+    EmitInstToData(Relaxed, STI, KsError);
     return;
   }
 
@@ -287,8 +289,9 @@ void MCObjectStreamer::EmitInstToFragment(MCInst &Inst,
 
   SmallString<128> Code;
   raw_svector_ostream VecOS(Code);
+  unsigned int KsError;
   getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(),
-                                                STI);
+                                                STI, KsError);
   IF->getContents().append(Code.begin(), Code.end());
 }
 
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index e9e765f..ac51eaf 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -662,7 +662,8 @@ void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
 }
 
 void MCStreamer::EmitInstruction(MCInst &Inst,
-                                 const MCSubtargetInfo &STI) {
+                                 const MCSubtargetInfo &STI,
+                                 unsigned int &KsError) {
   // Scan for values.
   for (unsigned i = Inst.getNumOperands(); i--;)
     if (Inst.getOperand(i).isExpr())
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index d94ad5e..391f411 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -4103,8 +4103,8 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
       return true;
 
     Inst.setLoc(IDLoc);
-    Out.EmitInstruction(Inst, getSTI());
-    return false;
+    Out.EmitInstruction(Inst, getSTI(), ErrorCode);
+    return (ErrorCode != 0);
   }
   case Match_MissingFeature: {
     assert(ErrorInfo && "Unknown missing feature!");
@@ -4316,7 +4316,8 @@ bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
   Inst.setOpcode(AArch64::TLSDESCCALL);
   Inst.addOperand(MCOperand::createExpr(Expr));
 
-  getParser().getStreamer().EmitInstruction(Inst, getSTI());
+  unsigned int KsError;
+  getParser().getStreamer().EmitInstruction(Inst, getSTI(), KsError);
   return false;
 }
 
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
index 3d0991b..4ac87dd 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp
@@ -174,7 +174,8 @@ public:
 
   void encodeInstruction(MCInst &MI, raw_ostream &OS,
                          SmallVectorImpl<MCFixup> &Fixups,
-                         const MCSubtargetInfo &STI) const override;
+                         const MCSubtargetInfo &STI,
+                         unsigned int &KsError) const override;
 
   unsigned fixMulHigh(const MCInst &MI, unsigned EncodedValue,
                       const MCSubtargetInfo &STI) const;
@@ -573,7 +574,9 @@ unsigned AArch64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue,
 
 void AArch64MCCodeEmitter::encodeInstruction(MCInst &MI, raw_ostream &OS,
                                              SmallVectorImpl<MCFixup> &Fixups,
-                                             const MCSubtargetInfo &STI) const {
+                                             const MCSubtargetInfo &STI,
+                                             unsigned int &KsError) const {
+  KsError = 0;
   if (MI.getOpcode() == AArch64::TLSDESCCALL) {
     // This is a directive which applies an R_AARCH64_TLSDESC_CALL to the
     // following (BLR) instruction. It doesn't emit any code itself so it
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index f02ecef..f0cbb64 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -8712,9 +8712,9 @@ bool ARMAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
       return false;
 
     Inst.setLoc(IDLoc);
-    Out.EmitInstruction(Inst, getSTI());
+    Out.EmitInstruction(Inst, getSTI(), ErrorCode);
     Address = Inst.getAddress(); // keystone update address
-    return false;
+    return ErrorCode != 0;
   case Match_MissingFeature: {
     ErrorCode = KS_ERR_ASM_ARM_MISSINGFEATURE;
     return true;
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
index 6652fc4..78ccc6e 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
@@ -436,7 +436,8 @@ public:
 
   void encodeInstruction(MCInst &MI, raw_ostream &OS,
                          SmallVectorImpl<MCFixup> &Fixups,
-                         const MCSubtargetInfo &STI) const override;
+                         const MCSubtargetInfo &STI,
+                         unsigned int &KsError) const override;
 };
 
 } // end anonymous namespace
@@ -1704,7 +1705,10 @@ getShiftRight64Imm(const MCInst &MI, unsigned Op,
 void ARMMCCodeEmitter::
 encodeInstruction(MCInst &MI, raw_ostream &OS,
                   SmallVectorImpl<MCFixup> &Fixups,
-                  const MCSubtargetInfo &STI) const {   // qq
+                  const MCSubtargetInfo &STI,
+                  unsigned int &KsError) const
+{
+  KsError = 0;
   // Pseudo instructions don't get encoded.
   const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
   uint64_t TSFlags = Desc.TSFlags;
diff --git a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
index ef829da..103c90c 100644
--- a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
+++ b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
@@ -700,7 +700,8 @@ bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) {
       // Empty packets are valid yet aren't emitted
       return false;
     }
-    Out.EmitInstruction(MCB, getSTI());
+    unsigned int KsError;
+    Out.EmitInstruction(MCB, getSTI(), KsError);
   } else {
     // If compounding and duplexing didn't reduce the size below
     // 4 or less we have a packet that is too big.
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
index e1f6bac..720b94a 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
@@ -64,7 +64,10 @@ uint32_t HexagonMCCodeEmitter::parseBits(size_t Instruction, size_t Last,
 
 void HexagonMCCodeEmitter::encodeInstruction(MCInst &MI, raw_ostream &OS,
                                              SmallVectorImpl<MCFixup> &Fixups,
-                                             MCSubtargetInfo const &STI) const {
+                                             MCSubtargetInfo const &STI,
+                                             unsigned int &KsError) const
+{
+  KsError = 0;
   MCInst &HMB = const_cast<MCInst &>(MI);
 
   assert(HexagonMCInstrInfo::isBundle(HMB));
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h
index 51fa44a..64cdc04 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h
@@ -46,7 +46,8 @@ public:
 
   void encodeInstruction(MCInst &MI, raw_ostream &OS,
                          SmallVectorImpl<MCFixup> &Fixups,
-                         MCSubtargetInfo const &STI) const override;
+                         MCSubtargetInfo const &STI,
+                         unsigned int &KsError) const override;
 
   void EncodeSingleInstruction(const MCInst &MI, raw_ostream &OS,
                                SmallVectorImpl<MCFixup> &Fixups,
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.h
index 08a2882..13d46c8 100644
--- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.h
+++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCELFStreamer.h
@@ -28,7 +28,7 @@ public:
         MCII(createHexagonMCInstrInfo()) {}
 
   virtual void EmitInstruction(MCInst &Inst,
-                               const MCSubtargetInfo &STI) override;
+                               const MCSubtargetInfo &STI, unsigned int &KsError) override;
   void EmitSymbol(const MCInst &Inst);
   void HexagonMCEmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
                                       unsigned ByteAlignment,
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 054de29..76140fe 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -3641,8 +3641,8 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     if (processInstruction(Inst, IDLoc, Instructions))
       return true;
     for (unsigned i = 0; i < Instructions.size(); i++)
-      Out.EmitInstruction(Instructions[i], getSTI());
-    return false;
+      Out.EmitInstruction(Instructions[i], getSTI(), ErrorCode);
+    return ErrorCode != 0;
   }
   case Match_MissingFeature:
     Error(IDLoc, "instruction requires a CPU feature not currently enabled");
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
index 7c9926e..f54646c 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h
@@ -46,7 +46,7 @@ public:
   /// \p Inst is actually emitted. For example, we can inspect the operands and
   /// gather sufficient information that allows us to reason about the register
   /// usage for the translation unit.
-  void EmitInstruction(MCInst &Inst, const MCSubtargetInfo &STI) override;
+  void EmitInstruction(MCInst &Inst, const MCSubtargetInfo &STI, unsigned int &KsError) override;
 
   /// Overriding this function allows us to record all labels that should be
   /// marked as microMIPS. Based on this data marking is done in
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
index a72c287..2e9f7e8 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
@@ -147,9 +147,10 @@ void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size,
 void MipsMCCodeEmitter::
 encodeInstruction(MCInst &MI, raw_ostream &OS,
                   SmallVectorImpl<MCFixup> &Fixups,
-                  const MCSubtargetInfo &STI) const
+                  const MCSubtargetInfo &STI,
+                  unsigned int &KsError) const
 {
-
+  KsError = 0;
   // Non-pseudo instructions that get changed for direct object
   // only based on operand values.
   // If this list of instructions get much longer we will move
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
index 203c131..8201e91 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.h
@@ -53,7 +53,8 @@ public:
 
   void encodeInstruction(MCInst &MI, raw_ostream &OS,
                          SmallVectorImpl<MCFixup> &Fixups,
-                         const MCSubtargetInfo &STI) const override;
+                         const MCSubtargetInfo &STI,
+                         unsigned int &KsError) const override;
 
   // getBinaryCodeForInstr - TableGen'erated function for getting the
   // binary encoding for an instruction.
diff --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
index 18e40ec..3dad04f 100644
--- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -1206,8 +1206,8 @@ bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     // Post-process instructions (typically extended mnemonics)
     ProcessInstruction(Inst, Operands);
     Inst.setLoc(IDLoc);
-    Out.EmitInstruction(Inst, getSTI());
-    return false;
+    Out.EmitInstruction(Inst, getSTI(), ErrorCode);
+    return (ErrorCode != 0);
   case Match_MissingFeature:
     // return Error(IDLoc, "instruction use requires an option to be enabled");
     ErrorCode = KS_ERR_ASM_PPC_MISSINGFEATURE;
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
index cca9ad8..27c8367 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
@@ -98,12 +98,15 @@ public:
                                  const MCSubtargetInfo &STI) const;
   void encodeInstruction(MCInst &MI, raw_ostream &OS,
                          SmallVectorImpl<MCFixup> &Fixups,
-                         const MCSubtargetInfo &STI) const override {
+                         const MCSubtargetInfo &STI,
+                         unsigned int &KsError) const override {
     unsigned Opcode = MI.getOpcode();
     const MCInstrDesc &Desc = MCII.get(Opcode);
 
     uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
 
+    KsError = 0;
+
     // Output the constant in big/little endian byte order.
     unsigned Size = Desc.getSize();
     switch (Size) {
diff --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
index 1f5f911..ad13ab6 100644
--- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
@@ -530,9 +530,9 @@ bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
     }
 
     for (MCInst &I : Instructions) {
-      Out.EmitInstruction(I, getSTI());
+      Out.EmitInstruction(I, getSTI(), ErrorCode);
     }
-    return false;
+    return (ErrorCode != 0);
   }
 
   case Match_MissingFeature:
diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
index 7ce2c17..a59a542 100644
--- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
@@ -42,7 +42,8 @@ public:
 
   void encodeInstruction(MCInst &MI, raw_ostream &OS,
                          SmallVectorImpl<MCFixup> &Fixups,
-                         const MCSubtargetInfo &STI) const override;
+                         const MCSubtargetInfo &STI,
+                         unsigned int &KsError) const override;
 
   // getBinaryCodeForInstr - TableGen'erated function for getting the
   // binary encoding for an instruction.
@@ -80,9 +81,13 @@ MCCodeEmitter *llvm::createSparcMCCodeEmitter(const MCInstrInfo &MCII,
 
 void SparcMCCodeEmitter::encodeInstruction(MCInst &MI, raw_ostream &OS,
                                            SmallVectorImpl<MCFixup> &Fixups,
-                                           const MCSubtargetInfo &STI) const {
+                                           const MCSubtargetInfo &STI,
+                                           unsigned int &KsError) const
+{
   unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI);
 
+  KsError = 0;
+
   if (Ctx.getAsmInfo()->isLittleEndian()) {
     // Output the bits in little-endian byte order.
     support::endian::Writer<support::little>(OS).write<uint32_t>(Bits);
diff --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
index 601b257..9fd2db5 100644
--- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
+++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
@@ -823,8 +823,8 @@ bool SystemZAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   switch (MatchResult) {
   case Match_Success:
     Inst.setLoc(IDLoc);
-    Out.EmitInstruction(Inst, getSTI());
-    return false;
+    Out.EmitInstruction(Inst, getSTI(), ErrorCode);
+    return (ErrorCode != 0);
 
   case Match_MissingFeature: {
 #if 0
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
index b27bf86..e481911 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
@@ -39,7 +39,8 @@ public:
   // OVerride MCCodeEmitter.
   void encodeInstruction(MCInst &MI, raw_ostream &OS,
                          SmallVectorImpl<MCFixup> &Fixups,
-                         const MCSubtargetInfo &STI) const override;
+                         const MCSubtargetInfo &STI,
+                         unsigned int &KsError) const override;
 
 private:
   // Automatically generated by TableGen.
@@ -122,9 +123,13 @@ MCCodeEmitter *llvm::createSystemZMCCodeEmitter(const MCInstrInfo &MCII,
 void SystemZMCCodeEmitter::
 encodeInstruction(MCInst &MI, raw_ostream &OS,
                   SmallVectorImpl<MCFixup> &Fixups,
-                  const MCSubtargetInfo &STI) const {
+                  const MCSubtargetInfo &STI,
+                  unsigned int &KsError) const
+{
   uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
   unsigned Size = MCII.get(MI.getOpcode()).getSize();
+
+  KsError = 0;
   // Big-endian insertion of Size bytes.
   unsigned ShiftValue = (Size * 8) - 8;
   for (unsigned I = 0; I != Size; ++I) {
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp
index 944669e..c802224 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp
@@ -101,13 +101,14 @@ X86AsmInstrumentation::~X86AsmInstrumentation() {}
 
 void X86AsmInstrumentation::InstrumentAndEmitInstruction(
     MCInst &Inst, OperandVector &Operands, MCContext &Ctx,
-    const MCInstrInfo &MII, MCStreamer &Out) {
-  EmitInstruction(Out, Inst);
+    const MCInstrInfo &MII, MCStreamer &Out, unsigned int &KsError) {
+  EmitInstruction(Out, Inst, KsError);
 }
 
 void X86AsmInstrumentation::EmitInstruction(MCStreamer &Out,
-                                            MCInst &Inst) {
-  Out.EmitInstruction(Inst, *STI);
+                                            MCInst &Inst,
+                                            unsigned int &KsError) {
+  Out.EmitInstruction(Inst, *STI, KsError);
 }
 
 unsigned X86AsmInstrumentation::GetFrameRegGeneric(const MCContext &Ctx,
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.h b/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.h
index 3552e3b..2a6e2e6 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.h
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmInstrumentation.h
@@ -44,7 +44,8 @@ public:
   virtual void InstrumentAndEmitInstruction(
       MCInst &Inst,
       SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand> > &Operands,
-      MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out);
+      MCContext &Ctx, const MCInstrInfo &MII, MCStreamer &Out,
+      unsigned int &KsError);
 
 protected:
   friend X86AsmInstrumentation *
@@ -56,7 +57,7 @@ protected:
 
   unsigned GetFrameRegGeneric(const MCContext &Ctx, MCStreamer &Out);
 
-  void EmitInstruction(MCStreamer &Out, MCInst &Inst);
+  void EmitInstruction(MCStreamer &Out, MCInst &Inst, unsigned int &KsError);
 
   const MCSubtargetInfo *&STI;
 
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index de54729..815e88e 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -785,7 +785,8 @@ private:
 
   /// Wrapper around MCStreamer::EmitInstruction(). Possibly adds
   /// instrumentation around Inst.
-  void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out);
+  void EmitInstruction(MCInst &Inst, OperandVector &Operands, MCStreamer &Out,
+          unsigned int &KsError);
 
   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                                OperandVector &Operands, MCStreamer &Out,
@@ -1853,6 +1854,7 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand(StringRef Mnem, unsi
 
   bool PtrInOperand = false;
   unsigned Size = getIntelMemOperandSize(Tok.getString());
+  //printf(">> Intel Op Size = %u\n", Size);
   if (Size) {
     Parser.Lex(); // Eat operand size (e.g., byte, word).
     if (KsSyntax == KS_OPT_SYNTAX_NASM) {
@@ -2655,9 +2657,9 @@ bool X86AsmParser::processInstruction(MCInst &Inst, const OperandVector &Ops) {
 static const char *getSubtargetFeatureName(uint64_t Val);
 
 void X86AsmParser::EmitInstruction(MCInst &Inst, OperandVector &Operands,
-                                   MCStreamer &Out) {
+                                   MCStreamer &Out, unsigned int &KsError) {
   Instrumentation->InstrumentAndEmitInstruction(Inst, Operands, getContext(),
-                                                MII, Out);
+                                                MII, Out, KsError);
 }
 
 bool X86AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
@@ -2691,8 +2693,9 @@ void X86AsmParser::MatchFPUWaitAlias(SMLoc IDLoc, X86Operand &Op,
     MCInst Inst;
     Inst.setOpcode(X86::WAIT);
     Inst.setLoc(IDLoc);
+    unsigned int KsError = 0;
     if (!MatchingInlineAsm)
-      EmitInstruction(Inst, Operands, Out);
+      EmitInstruction(Inst, Operands, Out, KsError);
     Operands[0] = X86Operand::CreateToken(Repl, IDLoc);
   }
 }
@@ -2744,8 +2747,11 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
         ;
 
     Inst.setLoc(IDLoc);
-    if (!MatchingInlineAsm)
-      EmitInstruction(Inst, Operands, Out);
+    if (!MatchingInlineAsm) {
+      EmitInstruction(Inst, Operands, Out, ErrorCode);
+      if (ErrorCode)
+          return true;
+    }
     Opcode = Inst.getOpcode();
     return false;
   case Match_MissingFeature:
@@ -2801,8 +2807,11 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
       std::count(std::begin(Match), std::end(Match), Match_Success);
   if (NumSuccessfulMatches == 1) {
     Inst.setLoc(IDLoc);
-    if (!MatchingInlineAsm)
-      EmitInstruction(Inst, Operands, Out);
+    if (!MatchingInlineAsm) {
+      EmitInstruction(Inst, Operands, Out, ErrorCode);
+      if (ErrorCode)
+          return true;
+    }
     Opcode = Inst.getOpcode();
     return false;
   }
@@ -3008,8 +3017,11 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
       while (processInstruction(Inst, Operands))
         ;
     Inst.setLoc(IDLoc);
-    if (!MatchingInlineAsm)
-      EmitInstruction(Inst, Operands, Out);
+    if (!MatchingInlineAsm) {
+      EmitInstruction(Inst, Operands, Out, ErrorCode);
+      if (ErrorCode)
+          return true;
+    }
     Opcode = Inst.getOpcode();
     return false;
   } else if (NumSuccessfulMatches > 1) {
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index c2b6867..b09ba33 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -24,6 +24,8 @@
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/Support/raw_ostream.h"
 
+#include <keystone/keystone.h>
+
 using namespace llvm;
 
 #define DEBUG_TYPE "mccodeemitter"
@@ -123,6 +125,7 @@ public:
                      unsigned ImmSize, MCFixupKind FixupKind,
                      unsigned &CurByte, raw_ostream &OS,
                      SmallVectorImpl<MCFixup> &Fixups,
+                     unsigned int &KsError,
                      int ImmOffset = 0) const;
 
   inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode,
@@ -151,7 +154,7 @@ public:
 
   void encodeInstruction(MCInst &MI, raw_ostream &OS,
                          SmallVectorImpl<MCFixup> &Fixups,
-                         const MCSubtargetInfo &STI) const override;
+                         const MCSubtargetInfo &STI, unsigned int &KsError) const override;
 
   void EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand,
                            const MCInst &MI, const MCInstrDesc &Desc,
@@ -290,12 +293,34 @@ static bool HasSecRelSymbolRef(const MCExpr *Expr) {
   return false;
 }
 
+// return false if Imm value is invalid for a given size
+static bool validImmRange(uint64_t Imm, unsigned int Size)
+{
+    switch(Size) {
+        default:
+            return true;
+        case 1:
+            return (Imm <= 0xff);
+        case 2:
+            return (Imm <= 0xffff);
+        case 4:
+            return (Imm <= 0xffffffff);
+    }
+
+}
+
 void X86MCCodeEmitter::
 EmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size,
               MCFixupKind FixupKind, unsigned &CurByte, raw_ostream &OS,
-              SmallVectorImpl<MCFixup> &Fixups, int ImmOffset) const {
+              SmallVectorImpl<MCFixup> &Fixups, unsigned int &KsError, int ImmOffset) const
+{
+  KsError = 0;
   const MCExpr *Expr = nullptr;
   if (DispOp.isImm()) {
+    if (!validImmRange(DispOp.getImm(), Size)) {
+        KsError = KS_ERR_ASM_INVALIDOPERAND;
+        return;
+    }
     // If this is a simple integer displacement that doesn't require a
     // relocation, emit it now.
     if (FixupKind != FK_PCRel_1 &&
@@ -372,6 +397,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
   const MCOperand &IndexReg = MI.getOperand(Op+X86::AddrIndexReg);
   unsigned BaseReg = Base.getReg();
   bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX;
+  unsigned int KsError;
 
   // Handle %rip relative addressing.
   if (BaseReg == X86::RIP) {    // [disp32+RIP] in X86-64 mode
@@ -395,7 +421,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
     int ImmSize = X86II::hasImm(TSFlags) ? X86II::getSizeOfImm(TSFlags) : 0;
 
     EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind),
-                  CurByte, OS, Fixups, -ImmSize);
+                  CurByte, OS, Fixups, KsError, -ImmSize);
     return;
   }
 
@@ -448,7 +474,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
         }
         // Use the [REG]+disp8 form, including for [BP] which cannot be encoded.
         EmitByte(ModRMByte(1, RegOpcodeField, RMfield), CurByte, OS);
-        EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups);
+        EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, KsError);
         return;
       }
       // This is the [REG]+disp16 case.
@@ -459,7 +485,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
     }
 
     // Emit 16-bit displacement for plain disp16 or [REG]+disp16 cases.
-    EmitImmediate(Disp, MI.getLoc(), 2, FK_Data_2, CurByte, OS, Fixups);
+    EmitImmediate(Disp, MI.getLoc(), 2, FK_Data_2, CurByte, OS, Fixups, KsError);
     return;
   }
 
@@ -480,7 +506,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
 
     if (BaseReg == 0) {          // [disp32]     in X86-32 mode
       EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS);
-      EmitImmediate(Disp, MI.getLoc(), 4, FK_Data_4, CurByte, OS, Fixups);
+      EmitImmediate(Disp, MI.getLoc(), 4, FK_Data_4, CurByte, OS, Fixups, KsError);
       return;
     }
 
@@ -497,7 +523,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
     if (Disp.isImm()) {
       if (!HasEVEX && isDisp8(Disp.getImm())) {
         EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS);
-        EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups);
+        EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, KsError);
         return;
       }
       // Try EVEX compressed 8-bit displacement first; if failed, fall back to
@@ -506,7 +532,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
       if (HasEVEX && isCDisp8(TSFlags, Disp.getImm(), CDisp8)) {
         EmitByte(ModRMByte(1, RegOpcodeField, BaseRegNo), CurByte, OS);
         EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups,
-                      CDisp8 - Disp.getImm());
+                      KsError, CDisp8 - Disp.getImm());
         return;
       }
     }
@@ -514,7 +540,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
     // Otherwise, emit the most general non-SIB encoding: [REG+disp32]
     EmitByte(ModRMByte(2, RegOpcodeField, BaseRegNo), CurByte, OS);
     EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte),
-                  CurByte, OS, Fixups);
+                  CurByte, OS, Fixups, KsError);
     return;
   }
 
@@ -588,10 +614,10 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
 
   // Do we need to output a displacement?
   if (ForceDisp8)
-    EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, ImmOffset);
+    EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups, KsError, ImmOffset);
   else if (ForceDisp32 || Disp.getImm() != 0)
     EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte),
-                  CurByte, OS, Fixups);
+                  CurByte, OS, Fixups, KsError);
 }
 
 /// EmitVEXOpcodePrefix - AVX instructions are encoded using a opcode prefix
@@ -1178,12 +1204,14 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
 void X86MCCodeEmitter::
 encodeInstruction(MCInst &MI, raw_ostream &OS,
                   SmallVectorImpl<MCFixup> &Fixups,
-                  const MCSubtargetInfo &STI) const
+                  const MCSubtargetInfo &STI, unsigned int &KsError) const
 {
   unsigned Opcode = MI.getOpcode();
   const MCInstrDesc &Desc = MCII.get(Opcode);
   uint64_t TSFlags = Desc.TSFlags;
 
+  KsError = 0;
+
   // Pseudo instructions don't get encoded.
   if ((TSFlags & X86II::FormMask) == X86II::Pseudo)
     return;
@@ -1319,7 +1347,7 @@ encodeInstruction(MCInst &MI, raw_ostream &OS,
     EmitByte(BaseOpcode, CurByte, OS);
     EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
                   X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
-                  CurByte, OS, Fixups);
+                  CurByte, OS, Fixups, KsError);
     ++CurOp; // skip segment operand
     break;
   case X86II::RawFrmImm8:
@@ -1327,18 +1355,18 @@ encodeInstruction(MCInst &MI, raw_ostream &OS,
     EmitByte(BaseOpcode, CurByte, OS);
     EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
                   X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
-                  CurByte, OS, Fixups);
+                  CurByte, OS, Fixups, KsError);
     EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 1, FK_Data_1, CurByte,
-                  OS, Fixups);
+                  OS, Fixups, KsError);
     break;
   case X86II::RawFrmImm16:
     //printf(">> gg\n");
     EmitByte(BaseOpcode, CurByte, OS);
     EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
                   X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
-                  CurByte, OS, Fixups);
+                  CurByte, OS, Fixups, KsError);
     EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), 2, FK_Data_2, CurByte,
-                  OS, Fixups);
+                  OS, Fixups, KsError);
     break;
 
   case X86II::AddRegFrm:
@@ -1534,16 +1562,20 @@ encodeInstruction(MCInst &MI, raw_ostream &OS,
           RegNum |= Val;
         }
       }
+      //printf(">> uu\n");
       EmitImmediate(MCOperand::createImm(RegNum), MI.getLoc(), 1, FK_Data_1,
-                    CurByte, OS, Fixups);
+                    CurByte, OS, Fixups, KsError);
     } else {
+      //printf(">> vv\n");
       EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
                     X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
-                    CurByte, OS, Fixups);
+                    CurByte, OS, Fixups, KsError);
+      if (KsError)
+          break;
     }
   }
 
-  if (TSFlags & X86II::Has3DNow0F0FOpcode)
+  if (KsError == 0 && TSFlags & X86II::Has3DNow0F0FOpcode)
     EmitByte(X86II::getBaseOpcodeFor(TSFlags), CurByte, OS);
 
 #ifndef NDEBUG
-- 
GitLab