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