@@ -126,6 +126,8 @@ class X86AsmBackend : public MCAsmBackend {
126
126
X86AlignBranchKind AlignBranchType;
127
127
Align AlignBoundary;
128
128
129
+ uint8_t determinePaddingPrefix (const MCInst &Inst) const ;
130
+
129
131
bool isMacroFused (const MCInst &Cmp, const MCInst &Jcc) const ;
130
132
131
133
bool needAlign (MCObjectStreamer &OS) const ;
@@ -340,6 +342,83 @@ static bool isFirstMacroFusibleInst(const MCInst &Inst,
340
342
return FIK != X86::FirstMacroFusionInstKind::Invalid;
341
343
}
342
344
345
+ // / X86 can reduce the bytes of NOP by padding instructions with prefixes to
346
+ // / get a better peformance in some cases. Here, we determine which prefix is
347
+ // / the most suitable.
348
+ // /
349
+ // / If the instruction has a segment override prefix, use the existing one.
350
+ // / If the target is 64-bit, use the CS.
351
+ // / If the target is 32-bit,
352
+ // / - If the instruction has a ESP/EBP base register, use SS.
353
+ // / - Otherwise use DS.
354
+ uint8_t X86AsmBackend::determinePaddingPrefix (const MCInst &Inst) const {
355
+ assert ((STI.hasFeature (X86::Mode32Bit) || STI.hasFeature (X86::Mode64Bit)) &&
356
+ " Prefixes can be added only in 32-bit or 64-bit mode." );
357
+ const MCInstrDesc &Desc = MCII->get (Inst.getOpcode ());
358
+ uint64_t TSFlags = Desc.TSFlags ;
359
+
360
+ // Determine where the memory operand starts, if present.
361
+ int MemoryOperand = X86II::getMemoryOperandNo (TSFlags);
362
+ if (MemoryOperand != -1 )
363
+ MemoryOperand += X86II::getOperandBias (Desc);
364
+
365
+ unsigned SegmentReg = 0 ;
366
+ if (MemoryOperand >= 0 ) {
367
+ // Check for explicit segment override on memory operand.
368
+ SegmentReg = Inst.getOperand (MemoryOperand + X86::AddrSegmentReg).getReg ();
369
+ }
370
+
371
+ switch (TSFlags & X86II::FormMask) {
372
+ default :
373
+ break ;
374
+ case X86II::RawFrmDstSrc: {
375
+ // Check segment override opcode prefix as needed (not for %ds).
376
+ if (Inst.getOperand (2 ).getReg () != X86::DS)
377
+ SegmentReg = Inst.getOperand (2 ).getReg ();
378
+ break ;
379
+ }
380
+ case X86II::RawFrmSrc: {
381
+ // Check segment override opcode prefix as needed (not for %ds).
382
+ if (Inst.getOperand (1 ).getReg () != X86::DS)
383
+ SegmentReg = Inst.getOperand (1 ).getReg ();
384
+ break ;
385
+ }
386
+ case X86II::RawFrmMemOffs: {
387
+ // Check segment override opcode prefix as needed.
388
+ SegmentReg = Inst.getOperand (1 ).getReg ();
389
+ break ;
390
+ }
391
+ }
392
+
393
+ switch (SegmentReg) {
394
+ case 0 :
395
+ break ;
396
+ case X86::CS:
397
+ return X86::CS_Encoding;
398
+ case X86::DS:
399
+ return X86::DS_Encoding;
400
+ case X86::ES:
401
+ return X86::ES_Encoding;
402
+ case X86::FS:
403
+ return X86::FS_Encoding;
404
+ case X86::GS:
405
+ return X86::GS_Encoding;
406
+ case X86::SS:
407
+ return X86::SS_Encoding;
408
+ }
409
+
410
+ if (STI.hasFeature (X86::Mode64Bit))
411
+ return X86::CS_Encoding;
412
+
413
+ if (MemoryOperand >= 0 ) {
414
+ unsigned BaseRegNum = MemoryOperand + X86::AddrBaseReg;
415
+ unsigned BaseReg = Inst.getOperand (BaseRegNum).getReg ();
416
+ if (BaseReg == X86::ESP || BaseReg == X86::EBP)
417
+ return X86::SS_Encoding;
418
+ }
419
+ return X86::DS_Encoding;
420
+ }
421
+
343
422
// / Check if the two instructions will be macro-fused on the target cpu.
344
423
bool X86AsmBackend::isMacroFused (const MCInst &Cmp, const MCInst &Jcc) const {
345
424
const MCInstrDesc &InstDesc = MCII->get (Jcc.getOpcode ());
0 commit comments