Skip to content

Commit 3017580

Browse files
committed
[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
1 parent 4bd186c commit 3017580

File tree

1 file changed

+50
-43
lines changed

1 file changed

+50
-43
lines changed

llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,12 @@ class X86MCCodeEmitter : public MCCodeEmitter {
7676
unsigned &CurByte, raw_ostream &OS) const;
7777

7878
void emitMemModRMByte(const MCInst &MI, unsigned Op, unsigned RegOpcodeField,
79-
uint64_t TSFlags, bool Rex, unsigned &CurByte,
79+
uint64_t TSFlags, bool HasREX, unsigned &CurByte,
8080
raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
8181
const MCSubtargetInfo &STI) const;
8282

83-
void emitPrefixImpl(unsigned &CurOp, unsigned &CurByte, bool &Rex,
84-
const MCInst &MI, const MCSubtargetInfo &STI,
85-
raw_ostream &OS) const;
83+
bool emitPrefixImpl(unsigned &CurOp, unsigned &CurByte, const MCInst &MI,
84+
const MCSubtargetInfo &STI, raw_ostream &OS) const;
8685

8786
void emitVEXOpcodePrefix(unsigned &CurByte, int MemOperand, const MCInst &MI,
8887
raw_ostream &OS) const;
@@ -93,7 +92,8 @@ class X86MCCodeEmitter : public MCCodeEmitter {
9392
bool emitOpcodePrefix(unsigned &CurByte, int MemOperand, const MCInst &MI,
9493
const MCSubtargetInfo &STI, raw_ostream &OS) const;
9594

96-
uint8_t determineREXPrefix(const MCInst &MI, int MemOperand) const;
95+
bool emitREXPrefix(unsigned &CurByte, int MemOperand, const MCInst &MI,
96+
raw_ostream &OS) const;
9797
};
9898

9999
} // end anonymous namespace
@@ -384,7 +384,7 @@ void X86MCCodeEmitter::emitSIBByte(unsigned SS, unsigned Index, unsigned Base,
384384

385385
void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
386386
unsigned RegOpcodeField,
387-
uint64_t TSFlags, bool Rex,
387+
uint64_t TSFlags, bool HasREX,
388388
unsigned &CurByte, raw_ostream &OS,
389389
SmallVectorImpl<MCFixup> &Fixups,
390390
const MCSubtargetInfo &STI) const {
@@ -412,7 +412,7 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
412412
default:
413413
return X86::reloc_riprel_4byte;
414414
case X86::MOV64rm:
415-
assert(Rex);
415+
assert(HasREX);
416416
return X86::reloc_riprel_4byte_movq_load;
417417
case X86::CALL64m:
418418
case X86::JMP64m:
@@ -426,8 +426,8 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
426426
case X86::SBB64rm:
427427
case X86::SUB64rm:
428428
case X86::XOR64rm:
429-
return Rex ? X86::reloc_riprel_4byte_relax_rex
430-
: X86::reloc_riprel_4byte_relax;
429+
return HasREX ? X86::reloc_riprel_4byte_relax_rex
430+
: X86::reloc_riprel_4byte_relax;
431431
}
432432
}();
433433

@@ -649,8 +649,11 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
649649
CurByte, OS, Fixups);
650650
}
651651

652-
void X86MCCodeEmitter::emitPrefixImpl(unsigned &CurOp, unsigned &CurByte,
653-
bool &Rex, const MCInst &MI,
652+
/// Emit all instruction prefixes.
653+
///
654+
/// \returns true if REX prefix is used, otherwise returns false.
655+
bool X86MCCodeEmitter::emitPrefixImpl(unsigned &CurOp, unsigned &CurByte,
656+
const MCInst &MI,
654657
const MCSubtargetInfo &STI,
655658
raw_ostream &OS) const {
656659
uint64_t TSFlags = MCII.get(MI.getOpcode()).TSFlags;
@@ -696,10 +699,11 @@ void X86MCCodeEmitter::emitPrefixImpl(unsigned &CurOp, unsigned &CurByte,
696699

697700
// Encoding type for this instruction.
698701
uint64_t Encoding = TSFlags & X86II::EncodingMask;
699-
if (Encoding == 0)
700-
Rex = emitOpcodePrefix(CurByte, MemoryOperand, MI, STI, OS);
701-
else
702+
bool HasREX = false;
703+
if (Encoding)
702704
emitVEXOpcodePrefix(CurByte, MemoryOperand, MI, OS);
705+
else
706+
HasREX = emitOpcodePrefix(CurByte, MemoryOperand, MI, STI, OS);
703707

704708
uint64_t Form = TSFlags & X86II::FormMask;
705709
switch (Form) {
@@ -748,6 +752,8 @@ void X86MCCodeEmitter::emitPrefixImpl(unsigned &CurOp, unsigned &CurByte,
748752
break;
749753
}
750754
}
755+
756+
return HasREX;
751757
}
752758

753759
/// AVX instructions are encoded using a opcode prefix called VEX.
@@ -1181,11 +1187,14 @@ void X86MCCodeEmitter::emitVEXOpcodePrefix(unsigned &CurByte, int MemOperand,
11811187
}
11821188
}
11831189

1184-
/// Determine if the MCInst has to be encoded with a X86-64 REX prefix which
1185-
/// specifies 1) 64-bit instructions, 2) non-default operand size, and 3) use
1186-
/// of X86-64 extended registers.
1187-
uint8_t X86MCCodeEmitter::determineREXPrefix(const MCInst &MI,
1188-
int MemOperand) const {
1190+
/// Emit REX prefix which specifies
1191+
/// 1) 64-bit instructions,
1192+
/// 2) non-default operand size, and
1193+
/// 3) use of X86-64 extended registers.
1194+
///
1195+
/// \returns true if REX prefix is used, otherwise returns false.
1196+
bool X86MCCodeEmitter::emitREXPrefix(unsigned &CurByte, int MemOperand,
1197+
const MCInst &MI, raw_ostream &OS) const {
11891198
uint8_t REX = 0;
11901199
bool UsesHighByteReg = false;
11911200

@@ -1271,7 +1280,10 @@ uint8_t X86MCCodeEmitter::determineREXPrefix(const MCInst &MI,
12711280
report_fatal_error(
12721281
"Cannot encode high byte register in REX-prefixed instruction");
12731282

1274-
return REX;
1283+
if (REX)
1284+
emitByte(0x40 | REX, CurByte, OS);
1285+
1286+
return REX != 0;
12751287
}
12761288

12771289
/// Emit segment override opcode prefix as needed.
@@ -1289,15 +1301,14 @@ void X86MCCodeEmitter::emitSegmentOverridePrefix(unsigned &CurByte,
12891301
/// \param MemOperand the operand # of the start of a memory operand if present.
12901302
/// If not present, it is -1.
12911303
///
1292-
/// \returns true if a REX prefix was used.
1304+
/// \returns true if REX prefix is used, otherwise returns false.
12931305
bool X86MCCodeEmitter::emitOpcodePrefix(unsigned &CurByte, int MemOperand,
12941306
const MCInst &MI,
12951307
const MCSubtargetInfo &STI,
12961308
raw_ostream &OS) const {
12971309
const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
12981310
uint64_t TSFlags = Desc.TSFlags;
12991311

1300-
bool Ret = false;
13011312
// Emit the operand size opcode prefix as needed.
13021313
if ((TSFlags & X86II::OpSizeMask) ==
13031314
(STI.hasFeature(X86::Mode16Bit) ? X86II::OpSize32 : X86II::OpSize16))
@@ -1324,15 +1335,11 @@ bool X86MCCodeEmitter::emitOpcodePrefix(unsigned &CurByte, int MemOperand,
13241335
}
13251336

13261337
// Handle REX prefix.
1327-
// FIXME: Can this come before F2 etc to simplify emission?
1328-
if (STI.hasFeature(X86::Mode64Bit)) {
1329-
if (uint8_t REX = determineREXPrefix(MI, MemOperand)) {
1330-
emitByte(0x40 | REX, CurByte, OS);
1331-
Ret = true;
1332-
}
1333-
} else {
1334-
assert(!(TSFlags & X86II::REX_W) && "REX.W requires 64bit mode.");
1335-
}
1338+
assert((STI.hasFeature(X86::Mode64Bit) || !(TSFlags & X86II::REX_W)) &&
1339+
"REX.W requires 64bit mode.");
1340+
bool HasREX = STI.hasFeature(X86::Mode64Bit)
1341+
? emitREXPrefix(CurByte, MemOperand, MI, OS)
1342+
: false;
13361343

13371344
// 0x0F escape code must be emitted just before the opcode.
13381345
switch (TSFlags & X86II::OpMapMask) {
@@ -1352,7 +1359,8 @@ bool X86MCCodeEmitter::emitOpcodePrefix(unsigned &CurByte, int MemOperand,
13521359
emitByte(0x3A, CurByte, OS);
13531360
break;
13541361
}
1355-
return Ret;
1362+
1363+
return HasREX;
13561364
}
13571365

13581366
void X86MCCodeEmitter::emitPrefix(const MCInst &MI, raw_ostream &OS,
@@ -1370,8 +1378,7 @@ void X86MCCodeEmitter::emitPrefix(const MCInst &MI, raw_ostream &OS,
13701378
// Keep track of the current byte being emitted.
13711379
unsigned CurByte = 0;
13721380

1373-
bool Rex = false;
1374-
emitPrefixImpl(CurOp, CurByte, Rex, MI, STI, OS);
1381+
emitPrefixImpl(CurOp, CurByte, MI, STI, OS);
13751382
}
13761383

13771384
void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
@@ -1391,8 +1398,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
13911398
// Keep track of the current byte being emitted.
13921399
unsigned CurByte = 0;
13931400

1394-
bool Rex = false;
1395-
emitPrefixImpl(CurOp, CurByte, Rex, MI, STI, OS);
1401+
bool HasREX = emitPrefixImpl(CurOp, CurByte, MI, STI, OS);
13961402

13971403
// It uses the VEX.VVVV field?
13981404
bool HasVEX_4V = TSFlags & X86II::VEX_4V;
@@ -1497,7 +1503,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
14971503
++SrcRegNum;
14981504

14991505
emitMemModRMByte(MI, CurOp, getX86RegNum(MI.getOperand(SrcRegNum)), TSFlags,
1500-
Rex, CurByte, OS, Fixups, STI);
1506+
HasREX, CurByte, OS, Fixups, STI);
15011507
CurOp = SrcRegNum + 1;
15021508
break;
15031509
}
@@ -1570,7 +1576,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
15701576
emitByte(BaseOpcode, CurByte, OS);
15711577

15721578
emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(CurOp)),
1573-
TSFlags, Rex, CurByte, OS, Fixups, STI);
1579+
TSFlags, HasREX, CurByte, OS, Fixups, STI);
15741580
CurOp = FirstMemOp + X86::AddrNumOperands;
15751581
if (HasVEX_I8Reg)
15761582
I8RegNum = getX86RegEncoding(MI, CurOp++);
@@ -1582,7 +1588,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
15821588
emitByte(BaseOpcode, CurByte, OS);
15831589

15841590
emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(CurOp)),
1585-
TSFlags, Rex, CurByte, OS, Fixups, STI);
1591+
TSFlags, HasREX, CurByte, OS, Fixups, STI);
15861592
CurOp = FirstMemOp + X86::AddrNumOperands;
15871593
++CurOp; // Encoded in VEX.VVVV.
15881594
break;
@@ -1599,7 +1605,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
15991605
emitByte(BaseOpcode, CurByte, OS);
16001606

16011607
emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(CurOp)),
1602-
TSFlags, Rex, CurByte, OS, Fixups, STI);
1608+
TSFlags, HasREX, CurByte, OS, Fixups, STI);
16031609
CurOp = FirstMemOp + X86::AddrNumOperands;
16041610
break;
16051611
}
@@ -1612,7 +1618,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
16121618
emitByte(BaseOpcode + CC, CurByte, OS);
16131619

16141620
emitMemModRMByte(MI, FirstMemOp, getX86RegNum(MI.getOperand(RegOp)),
1615-
TSFlags, Rex, CurByte, OS, Fixups, STI);
1621+
TSFlags, HasREX, CurByte, OS, Fixups, STI);
16161622
break;
16171623
}
16181624

@@ -1651,7 +1657,8 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
16511657
unsigned CC = MI.getOperand(CurOp++).getImm();
16521658
emitByte(BaseOpcode + CC, CurByte, OS);
16531659

1654-
emitMemModRMByte(MI, FirstMemOp, 0, TSFlags, Rex, CurByte, OS, Fixups, STI);
1660+
emitMemModRMByte(MI, FirstMemOp, 0, TSFlags, HasREX, CurByte, OS, Fixups,
1661+
STI);
16551662
break;
16561663
}
16571664

@@ -1671,7 +1678,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
16711678
emitByte(BaseOpcode, CurByte, OS);
16721679
emitMemModRMByte(MI, CurOp,
16731680
(Form == X86II::MRMXm) ? 0 : Form - X86II::MRM0m, TSFlags,
1674-
Rex, CurByte, OS, Fixups, STI);
1681+
HasREX, CurByte, OS, Fixups, STI);
16751682
CurOp += X86::AddrNumOperands;
16761683
break;
16771684

0 commit comments

Comments
 (0)