forked from OSchip/llvm-project
[X86][MC][NFC] Reduce the parameters of functions in X86MCCodeEmitter(Part II)
Summary: We determine the REX prefix used by instruction in `determineREXPrefix`, and this value is used in `emitMemModRMByte' and used as the return value of `emitOpcodePrefix`. Before this patch, REX was passed as reference to `emitPrefixImpl`, it is strange and not necessary, e.g, we have to write ``` bool Rex = false; emitPrefixImpl(CurOp, CurByte, Rex, MI, STI, OS); ``` in `emitPrefix` even if `Rex` will not be used. So we let HasREX be the return value of `emitPrefixImpl`. The HasREX is passed from `emitREXPrefix` to `emitOpcodePrefix` and then to `emitPrefixImpl`. This makes sense since REX is a kind of opcode prefix and of course is a prefix. Reviewers: craig.topper, pengfei Reviewed By: craig.topper Subscribers: annita.zhang, craig.topper, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D78276
This commit is contained in:
parent
4bd186c0ff
commit
3017580c79
|
@ -76,13 +76,12 @@ private:
|
|||
unsigned &CurByte, raw_ostream &OS) const;
|
||||
|
||||
void emitMemModRMByte(const MCInst &MI, unsigned Op, unsigned RegOpcodeField,
|
||||
uint64_t TSFlags, bool Rex, unsigned &CurByte,
|
||||
uint64_t TSFlags, bool HasREX, unsigned &CurByte,
|
||||
raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
|
||||
void emitPrefixImpl(unsigned &CurOp, unsigned &CurByte, bool &Rex,
|
||||
const MCInst &MI, const MCSubtargetInfo &STI,
|
||||
raw_ostream &OS) const;
|
||||
bool emitPrefixImpl(unsigned &CurOp, unsigned &CurByte, const MCInst &MI,
|
||||
const MCSubtargetInfo &STI, raw_ostream &OS) const;
|
||||
|
||||
void emitVEXOpcodePrefix(unsigned &CurByte, int MemOperand, const MCInst &MI,
|
||||
raw_ostream &OS) const;
|
||||
|
@ -93,7 +92,8 @@ private:
|
|||
bool emitOpcodePrefix(unsigned &CurByte, int MemOperand, const MCInst &MI,
|
||||
const MCSubtargetInfo &STI, raw_ostream &OS) const;
|
||||
|
||||
uint8_t determineREXPrefix(const MCInst &MI, int MemOperand) const;
|
||||
bool emitREXPrefix(unsigned &CurByte, int MemOperand, const MCInst &MI,
|
||||
raw_ostream &OS) const;
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
@ -384,7 +384,7 @@ void X86MCCodeEmitter::emitSIBByte(unsigned SS, unsigned Index, unsigned Base,
|
|||
|
||||
void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
|
||||
unsigned RegOpcodeField,
|
||||
uint64_t TSFlags, bool Rex,
|
||||
uint64_t TSFlags, bool HasREX,
|
||||
unsigned &CurByte, raw_ostream &OS,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
|
@ -412,7 +412,7 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
|
|||
default:
|
||||
return X86::reloc_riprel_4byte;
|
||||
case X86::MOV64rm:
|
||||
assert(Rex);
|
||||
assert(HasREX);
|
||||
return X86::reloc_riprel_4byte_movq_load;
|
||||
case X86::CALL64m:
|
||||
case X86::JMP64m:
|
||||
|
@ -426,8 +426,8 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
|
|||
case X86::SBB64rm:
|
||||
case X86::SUB64rm:
|
||||
case X86::XOR64rm:
|
||||
return Rex ? X86::reloc_riprel_4byte_relax_rex
|
||||
: X86::reloc_riprel_4byte_relax;
|
||||
return HasREX ? X86::reloc_riprel_4byte_relax_rex
|
||||
: X86::reloc_riprel_4byte_relax;
|
||||
}
|
||||
}();
|
||||
|
||||
|
@ -649,8 +649,11 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
|
|||
CurByte, OS, Fixups);
|
||||
}
|
||||
|
||||
void X86MCCodeEmitter::emitPrefixImpl(unsigned &CurOp, unsigned &CurByte,
|
||||
bool &Rex, const MCInst &MI,
|
||||
/// Emit all instruction prefixes.
|
||||
///
|
||||
/// \returns true if REX prefix is used, otherwise returns false.
|
||||
bool X86MCCodeEmitter::emitPrefixImpl(unsigned &CurOp, unsigned &CurByte,
|
||||
const MCInst &MI,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &OS) const {
|
||||
uint64_t TSFlags = MCII.get(MI.getOpcode()).TSFlags;
|
||||
|
@ -696,10 +699,11 @@ void X86MCCodeEmitter::emitPrefixImpl(unsigned &CurOp, unsigned &CurByte,
|
|||
|
||||
// Encoding type for this instruction.
|
||||
uint64_t Encoding = TSFlags & X86II::EncodingMask;
|
||||
if (Encoding == 0)
|
||||
Rex = emitOpcodePrefix(CurByte, MemoryOperand, MI, STI, OS);
|
||||
else
|
||||
bool HasREX = false;
|
||||
if (Encoding)
|
||||
emitVEXOpcodePrefix(CurByte, MemoryOperand, MI, OS);
|
||||
else
|
||||
HasREX = emitOpcodePrefix(CurByte, MemoryOperand, MI, STI, OS);
|
||||
|
||||
uint64_t Form = TSFlags & X86II::FormMask;
|
||||
switch (Form) {
|
||||
|
@ -748,6 +752,8 @@ void X86MCCodeEmitter::emitPrefixImpl(unsigned &CurOp, unsigned &CurByte,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return HasREX;
|
||||
}
|
||||
|
||||
/// AVX instructions are encoded using a opcode prefix called VEX.
|
||||
|
@ -1181,11 +1187,14 @@ void X86MCCodeEmitter::emitVEXOpcodePrefix(unsigned &CurByte, int MemOperand,
|
|||
}
|
||||
}
|
||||
|
||||
/// Determine if the MCInst has to be encoded with a X86-64 REX prefix which
|
||||
/// specifies 1) 64-bit instructions, 2) non-default operand size, and 3) use
|
||||
/// of X86-64 extended registers.
|
||||
uint8_t X86MCCodeEmitter::determineREXPrefix(const MCInst &MI,
|
||||
int MemOperand) const {
|
||||
/// Emit REX prefix which specifies
|
||||
/// 1) 64-bit instructions,
|
||||
/// 2) non-default operand size, and
|
||||
/// 3) use of X86-64 extended registers.
|
||||
///
|
||||
/// \returns true if REX prefix is used, otherwise returns false.
|
||||
bool X86MCCodeEmitter::emitREXPrefix(unsigned &CurByte, int MemOperand,
|
||||
const MCInst &MI, raw_ostream &OS) const {
|
||||
uint8_t REX = 0;
|
||||
bool UsesHighByteReg = false;
|
||||
|
||||
|
@ -1271,7 +1280,10 @@ uint8_t X86MCCodeEmitter::determineREXPrefix(const MCInst &MI,
|
|||
report_fatal_error(
|
||||
"Cannot encode high byte register in REX-prefixed instruction");
|
||||
|
||||
return REX;
|
||||
if (REX)
|
||||
emitByte(0x40 | REX, CurByte, OS);
|
||||
|
||||
return REX != 0;
|
||||
}
|
||||
|
||||
/// Emit segment override opcode prefix as needed.
|
||||
|
@ -1289,7 +1301,7 @@ void X86MCCodeEmitter::emitSegmentOverridePrefix(unsigned &CurByte,
|
|||
/// \param MemOperand the operand # of the start of a memory operand if present.
|
||||
/// If not present, it is -1.
|
||||
///
|
||||
/// \returns true if a REX prefix was used.
|
||||
/// \returns true if REX prefix is used, otherwise returns false.
|
||||
bool X86MCCodeEmitter::emitOpcodePrefix(unsigned &CurByte, int MemOperand,
|
||||
const MCInst &MI,
|
||||
const MCSubtargetInfo &STI,
|
||||
|
@ -1297,7 +1309,6 @@ bool X86MCCodeEmitter::emitOpcodePrefix(unsigned &CurByte, int MemOperand,
|
|||
const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
|
||||
uint64_t TSFlags = Desc.TSFlags;
|
||||
|
||||
bool Ret = false;
|
||||
// Emit the operand size opcode prefix as needed.
|
||||
if ((TSFlags & X86II::OpSizeMask) ==
|
||||
(STI.hasFeature(X86::Mode16Bit) ? X86II::OpSize32 : X86II::OpSize16))
|
||||
|
@ -1324,15 +1335,11 @@ bool X86MCCodeEmitter::emitOpcodePrefix(unsigned &CurByte, int MemOperand,
|
|||
}
|
||||
|
||||
// Handle REX prefix.
|
||||
// FIXME: Can this come before F2 etc to simplify emission?
|
||||
if (STI.hasFeature(X86::Mode64Bit)) {
|
||||
if (uint8_t REX = determineREXPrefix(MI, MemOperand)) {
|
||||
emitByte(0x40 | REX, CurByte, OS);
|
||||
Ret = true;
|
||||
}
|
||||
} else {
|
||||
assert(!(TSFlags & X86II::REX_W) && "REX.W requires 64bit mode.");
|
||||
}
|
||||
assert((STI.hasFeature(X86::Mode64Bit) || !(TSFlags & X86II::REX_W)) &&
|
||||
"REX.W requires 64bit mode.");
|
||||
bool HasREX = STI.hasFeature(X86::Mode64Bit)
|
||||
? emitREXPrefix(CurByte, MemOperand, MI, OS)
|
||||
: false;
|
||||
|
||||
// 0x0F escape code must be emitted just before the opcode.
|
||||
switch (TSFlags & X86II::OpMapMask) {
|
||||
|
@ -1352,7 +1359,8 @@ bool X86MCCodeEmitter::emitOpcodePrefix(unsigned &CurByte, int MemOperand,
|
|||
emitByte(0x3A, CurByte, OS);
|
||||
break;
|
||||
}
|
||||
return Ret;
|
||||
|
||||
return HasREX;
|
||||
}
|
||||
|
||||
void X86MCCodeEmitter::emitPrefix(const MCInst &MI, raw_ostream &OS,
|
||||
|
@ -1370,8 +1378,7 @@ void X86MCCodeEmitter::emitPrefix(const MCInst &MI, raw_ostream &OS,
|
|||
// Keep track of the current byte being emitted.
|
||||
unsigned CurByte = 0;
|
||||
|
||||
bool Rex = false;
|
||||
emitPrefixImpl(CurOp, CurByte, Rex, MI, STI, OS);
|
||||
emitPrefixImpl(CurOp, CurByte, MI, STI, OS);
|
||||
}
|
||||
|
||||
void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
|
@ -1391,8 +1398,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||
// Keep track of the current byte being emitted.
|
||||
unsigned CurByte = 0;
|
||||
|
||||
bool Rex = false;
|
||||
emitPrefixImpl(CurOp, CurByte, Rex, MI, STI, OS);
|
||||
bool HasREX = emitPrefixImpl(CurOp, CurByte, MI, STI, OS);
|
||||
|
||||
// It uses the VEX.VVVV field?
|
||||
bool HasVEX_4V = TSFlags & X86II::VEX_4V;
|
||||
|
@ -1497,7 +1503,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||
++SrcRegNum;
|
||||
|
||||
emitMemModRMByte(MI, CurOp, getX86RegNum(MI.getOperand(SrcRegNum)), TSFlags,
|
||||
Rex, CurByte, OS, Fixups, STI);
|
||||
HasREX, CurByte, OS, Fixups, STI);
|
||||
CurOp = SrcRegNum + 1;
|
||||
break;
|
||||
}
|
||||
|
@ -1570,7 +1576,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||
emitByte(BaseOpcode, CurByte, OS);
|
||||
|
||||
emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(CurOp)),
|
||||
TSFlags, Rex, CurByte, OS, Fixups, STI);
|
||||
TSFlags, HasREX, CurByte, OS, Fixups, STI);
|
||||
CurOp = FirstMemOp + X86::AddrNumOperands;
|
||||
if (HasVEX_I8Reg)
|
||||
I8RegNum = getX86RegEncoding(MI, CurOp++);
|
||||
|
@ -1582,7 +1588,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||
emitByte(BaseOpcode, CurByte, OS);
|
||||
|
||||
emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(CurOp)),
|
||||
TSFlags, Rex, CurByte, OS, Fixups, STI);
|
||||
TSFlags, HasREX, CurByte, OS, Fixups, STI);
|
||||
CurOp = FirstMemOp + X86::AddrNumOperands;
|
||||
++CurOp; // Encoded in VEX.VVVV.
|
||||
break;
|
||||
|
@ -1599,7 +1605,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||
emitByte(BaseOpcode, CurByte, OS);
|
||||
|
||||
emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(CurOp)),
|
||||
TSFlags, Rex, CurByte, OS, Fixups, STI);
|
||||
TSFlags, HasREX, CurByte, OS, Fixups, STI);
|
||||
CurOp = FirstMemOp + X86::AddrNumOperands;
|
||||
break;
|
||||
}
|
||||
|
@ -1612,7 +1618,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||
emitByte(BaseOpcode + CC, CurByte, OS);
|
||||
|
||||
emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(RegOp)),
|
||||
TSFlags, Rex, CurByte, OS, Fixups, STI);
|
||||
TSFlags, HasREX, CurByte, OS, Fixups, STI);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1651,7 +1657,8 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||
unsigned CC = MI.getOperand(CurOp++).getImm();
|
||||
emitByte(BaseOpcode + CC, CurByte, OS);
|
||||
|
||||
emitMemModRMByte(MI, FirstMemOp, 0, TSFlags, Rex, CurByte, OS, Fixups, STI);
|
||||
emitMemModRMByte(MI, FirstMemOp, 0, TSFlags, HasREX, CurByte, OS, Fixups,
|
||||
STI);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1671,7 +1678,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
|||
emitByte(BaseOpcode, CurByte, OS);
|
||||
emitMemModRMByte(MI, CurOp,
|
||||
(Form == X86II::MRMXm) ? 0 : Form - X86II::MRM0m, TSFlags,
|
||||
Rex, CurByte, OS, Fixups, STI);
|
||||
HasREX, CurByte, OS, Fixups, STI);
|
||||
CurOp += X86::AddrNumOperands;
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue