@@ -76,13 +76,12 @@ class X86MCCodeEmitter : public MCCodeEmitter {
76
76
unsigned &CurByte, raw_ostream &OS) const ;
77
77
78
78
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,
80
80
raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
81
81
const MCSubtargetInfo &STI) const ;
82
82
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 ;
86
85
87
86
void emitVEXOpcodePrefix (unsigned &CurByte, int MemOperand, const MCInst &MI,
88
87
raw_ostream &OS) const ;
@@ -93,7 +92,8 @@ class X86MCCodeEmitter : public MCCodeEmitter {
93
92
bool emitOpcodePrefix (unsigned &CurByte, int MemOperand, const MCInst &MI,
94
93
const MCSubtargetInfo &STI, raw_ostream &OS) const ;
95
94
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 ;
97
97
};
98
98
99
99
} // end anonymous namespace
@@ -384,7 +384,7 @@ void X86MCCodeEmitter::emitSIBByte(unsigned SS, unsigned Index, unsigned Base,
384
384
385
385
void X86MCCodeEmitter::emitMemModRMByte (const MCInst &MI, unsigned Op,
386
386
unsigned RegOpcodeField,
387
- uint64_t TSFlags, bool Rex ,
387
+ uint64_t TSFlags, bool HasREX ,
388
388
unsigned &CurByte, raw_ostream &OS,
389
389
SmallVectorImpl<MCFixup> &Fixups,
390
390
const MCSubtargetInfo &STI) const {
@@ -412,7 +412,7 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
412
412
default :
413
413
return X86::reloc_riprel_4byte;
414
414
case X86::MOV64rm:
415
- assert (Rex );
415
+ assert (HasREX );
416
416
return X86::reloc_riprel_4byte_movq_load;
417
417
case X86::CALL64m:
418
418
case X86::JMP64m:
@@ -426,8 +426,8 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
426
426
case X86::SBB64rm:
427
427
case X86::SUB64rm:
428
428
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;
431
431
}
432
432
}();
433
433
@@ -649,8 +649,11 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
649
649
CurByte, OS, Fixups);
650
650
}
651
651
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,
654
657
const MCSubtargetInfo &STI,
655
658
raw_ostream &OS) const {
656
659
uint64_t TSFlags = MCII.get (MI.getOpcode ()).TSFlags ;
@@ -696,10 +699,11 @@ void X86MCCodeEmitter::emitPrefixImpl(unsigned &CurOp, unsigned &CurByte,
696
699
697
700
// Encoding type for this instruction.
698
701
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)
702
704
emitVEXOpcodePrefix (CurByte, MemoryOperand, MI, OS);
705
+ else
706
+ HasREX = emitOpcodePrefix (CurByte, MemoryOperand, MI, STI, OS);
703
707
704
708
uint64_t Form = TSFlags & X86II::FormMask;
705
709
switch (Form) {
@@ -748,6 +752,8 @@ void X86MCCodeEmitter::emitPrefixImpl(unsigned &CurOp, unsigned &CurByte,
748
752
break ;
749
753
}
750
754
}
755
+
756
+ return HasREX;
751
757
}
752
758
753
759
// / AVX instructions are encoded using a opcode prefix called VEX.
@@ -1181,11 +1187,14 @@ void X86MCCodeEmitter::emitVEXOpcodePrefix(unsigned &CurByte, int MemOperand,
1181
1187
}
1182
1188
}
1183
1189
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 {
1189
1198
uint8_t REX = 0 ;
1190
1199
bool UsesHighByteReg = false ;
1191
1200
@@ -1271,7 +1280,10 @@ uint8_t X86MCCodeEmitter::determineREXPrefix(const MCInst &MI,
1271
1280
report_fatal_error (
1272
1281
" Cannot encode high byte register in REX-prefixed instruction" );
1273
1282
1274
- return REX;
1283
+ if (REX)
1284
+ emitByte (0x40 | REX, CurByte, OS);
1285
+
1286
+ return REX != 0 ;
1275
1287
}
1276
1288
1277
1289
// / Emit segment override opcode prefix as needed.
@@ -1289,15 +1301,14 @@ void X86MCCodeEmitter::emitSegmentOverridePrefix(unsigned &CurByte,
1289
1301
// / \param MemOperand the operand # of the start of a memory operand if present.
1290
1302
// / If not present, it is -1.
1291
1303
// /
1292
- // / \returns true if a REX prefix was used.
1304
+ // / \returns true if REX prefix is used, otherwise returns false .
1293
1305
bool X86MCCodeEmitter::emitOpcodePrefix (unsigned &CurByte, int MemOperand,
1294
1306
const MCInst &MI,
1295
1307
const MCSubtargetInfo &STI,
1296
1308
raw_ostream &OS) const {
1297
1309
const MCInstrDesc &Desc = MCII.get (MI.getOpcode ());
1298
1310
uint64_t TSFlags = Desc.TSFlags ;
1299
1311
1300
- bool Ret = false ;
1301
1312
// Emit the operand size opcode prefix as needed.
1302
1313
if ((TSFlags & X86II::OpSizeMask) ==
1303
1314
(STI.hasFeature (X86::Mode16Bit) ? X86II::OpSize32 : X86II::OpSize16))
@@ -1324,15 +1335,11 @@ bool X86MCCodeEmitter::emitOpcodePrefix(unsigned &CurByte, int MemOperand,
1324
1335
}
1325
1336
1326
1337
// 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 ;
1336
1343
1337
1344
// 0x0F escape code must be emitted just before the opcode.
1338
1345
switch (TSFlags & X86II::OpMapMask) {
@@ -1352,7 +1359,8 @@ bool X86MCCodeEmitter::emitOpcodePrefix(unsigned &CurByte, int MemOperand,
1352
1359
emitByte (0x3A , CurByte, OS);
1353
1360
break ;
1354
1361
}
1355
- return Ret;
1362
+
1363
+ return HasREX;
1356
1364
}
1357
1365
1358
1366
void X86MCCodeEmitter::emitPrefix (const MCInst &MI, raw_ostream &OS,
@@ -1370,8 +1378,7 @@ void X86MCCodeEmitter::emitPrefix(const MCInst &MI, raw_ostream &OS,
1370
1378
// Keep track of the current byte being emitted.
1371
1379
unsigned CurByte = 0 ;
1372
1380
1373
- bool Rex = false ;
1374
- emitPrefixImpl (CurOp, CurByte, Rex, MI, STI, OS);
1381
+ emitPrefixImpl (CurOp, CurByte, MI, STI, OS);
1375
1382
}
1376
1383
1377
1384
void X86MCCodeEmitter::encodeInstruction (const MCInst &MI, raw_ostream &OS,
@@ -1391,8 +1398,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
1391
1398
// Keep track of the current byte being emitted.
1392
1399
unsigned CurByte = 0 ;
1393
1400
1394
- bool Rex = false ;
1395
- emitPrefixImpl (CurOp, CurByte, Rex, MI, STI, OS);
1401
+ bool HasREX = emitPrefixImpl (CurOp, CurByte, MI, STI, OS);
1396
1402
1397
1403
// It uses the VEX.VVVV field?
1398
1404
bool HasVEX_4V = TSFlags & X86II::VEX_4V;
@@ -1497,7 +1503,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
1497
1503
++SrcRegNum;
1498
1504
1499
1505
emitMemModRMByte (MI, CurOp, getX86RegNum (MI.getOperand (SrcRegNum)), TSFlags,
1500
- Rex , CurByte, OS, Fixups, STI);
1506
+ HasREX , CurByte, OS, Fixups, STI);
1501
1507
CurOp = SrcRegNum + 1 ;
1502
1508
break ;
1503
1509
}
@@ -1570,7 +1576,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
1570
1576
emitByte (BaseOpcode, CurByte, OS);
1571
1577
1572
1578
emitMemModRMByte (MI, FirstMemOp, getX86RegNum (MI.getOperand (CurOp)),
1573
- TSFlags, Rex , CurByte, OS, Fixups, STI);
1579
+ TSFlags, HasREX , CurByte, OS, Fixups, STI);
1574
1580
CurOp = FirstMemOp + X86::AddrNumOperands;
1575
1581
if (HasVEX_I8Reg)
1576
1582
I8RegNum = getX86RegEncoding (MI, CurOp++);
@@ -1582,7 +1588,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
1582
1588
emitByte (BaseOpcode, CurByte, OS);
1583
1589
1584
1590
emitMemModRMByte (MI, FirstMemOp, getX86RegNum (MI.getOperand (CurOp)),
1585
- TSFlags, Rex , CurByte, OS, Fixups, STI);
1591
+ TSFlags, HasREX , CurByte, OS, Fixups, STI);
1586
1592
CurOp = FirstMemOp + X86::AddrNumOperands;
1587
1593
++CurOp; // Encoded in VEX.VVVV.
1588
1594
break ;
@@ -1599,7 +1605,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
1599
1605
emitByte (BaseOpcode, CurByte, OS);
1600
1606
1601
1607
emitMemModRMByte (MI, FirstMemOp, getX86RegNum (MI.getOperand (CurOp)),
1602
- TSFlags, Rex , CurByte, OS, Fixups, STI);
1608
+ TSFlags, HasREX , CurByte, OS, Fixups, STI);
1603
1609
CurOp = FirstMemOp + X86::AddrNumOperands;
1604
1610
break ;
1605
1611
}
@@ -1612,7 +1618,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
1612
1618
emitByte (BaseOpcode + CC, CurByte, OS);
1613
1619
1614
1620
emitMemModRMByte (MI, FirstMemOp, getX86RegNum (MI.getOperand (RegOp)),
1615
- TSFlags, Rex , CurByte, OS, Fixups, STI);
1621
+ TSFlags, HasREX , CurByte, OS, Fixups, STI);
1616
1622
break ;
1617
1623
}
1618
1624
@@ -1651,7 +1657,8 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
1651
1657
unsigned CC = MI.getOperand (CurOp++).getImm ();
1652
1658
emitByte (BaseOpcode + CC, CurByte, OS);
1653
1659
1654
- emitMemModRMByte (MI, FirstMemOp, 0 , TSFlags, Rex, CurByte, OS, Fixups, STI);
1660
+ emitMemModRMByte (MI, FirstMemOp, 0 , TSFlags, HasREX, CurByte, OS, Fixups,
1661
+ STI);
1655
1662
break ;
1656
1663
}
1657
1664
@@ -1671,7 +1678,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
1671
1678
emitByte (BaseOpcode, CurByte, OS);
1672
1679
emitMemModRMByte (MI, CurOp,
1673
1680
(Form == X86II::MRMXm) ? 0 : Form - X86II::MRM0m, TSFlags,
1674
- Rex , CurByte, OS, Fixups, STI);
1681
+ HasREX , CurByte, OS, Fixups, STI);
1675
1682
CurOp += X86::AddrNumOperands;
1676
1683
break ;
1677
1684
0 commit comments