diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp --- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -1160,20 +1160,17 @@ if (!STI.hasFeature(X86::Is64Bit)) return None; X86OpcodePrefixHelper Prefix(*Ctx.getRegisterInfo()); - bool UsesHighByteReg = false; const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); uint64_t TSFlags = Desc.TSFlags; Prefix.setW(TSFlags & X86II::REX_W); unsigned NumOps = MI.getNumOperands(); - if (!NumOps) { - PrefixKind Kind = Prefix.determineOptimalKind(); - Prefix.emit(OS); - return Kind; - } - unsigned CurOp = X86II::getOperandBias(Desc); + bool UsesHighByteReg = false; + bool HasRegOp = false; + unsigned CurOp = NumOps ? X86II::getOperandBias(Desc) : 0; for (unsigned i = CurOp; i != NumOps; ++i) { const MCOperand &MO = MI.getOperand(i); if (MO.isReg()) { + HasRegOp = true; unsigned Reg = MO.getReg(); if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH) UsesHighByteReg = true; @@ -1193,7 +1190,26 @@ } } } + PrefixKind Kind; + auto emitAndCheck = [&]() { + Kind = Prefix.determineOptimalKind(); + if (Kind && UsesHighByteReg) + report_fatal_error( + "Cannot encode high byte register in REX-prefixed instruction"); + Prefix.emit(OS); + }; + if (!HasRegOp) { + emitAndCheck(); + return Kind; + } switch (TSFlags & X86II::FormMask) { + default: + llvm_unreachable("Unexpected form in emitREXPrefix!"); + case X86II::RawFrmMemOffs: + case X86II::RawFrmSrc: + case X86II::RawFrmDst: + case X86II::RawFrmDstSrc: + break; case X86II::AddRegFrm: Prefix.setB(MI, CurOp++); break; @@ -1245,11 +1261,7 @@ Prefix.setB(MI, CurOp++); break; } - PrefixKind Kind = Prefix.determineOptimalKind(); - if (Kind && UsesHighByteReg) - report_fatal_error( - "Cannot encode high byte register in REX-prefixed instruction"); - Prefix.emit(OS); + emitAndCheck(); return Kind; }