diff options
-rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.cpp | 12 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/x86-interrupt_cld.ll | 17 |
2 files changed, 29 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index 8a283775138..700ebf9e91c 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -1381,6 +1381,18 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF, if (PushedRegs) emitCalleeSavedFrameMoves(MBB, MBBI, DL); } + + // X86 Interrupt handling function cannot assume anything about the direction + // flag (DF in EFLAGS register). Clear this flag by creating "cld" instruction + // in each prologue of interrupt handler function. + // + // FIXME: Create "cld" instruction only in these cases: + // 1. The interrupt handling function uses any of the "rep" instructions. + // 2. Interrupt handling function calls another function. + // + if (Fn->getCallingConv() == CallingConv::X86_INTR) + BuildMI(MBB, MBBI, DL, TII.get(X86::CLD)) + .setMIFlag(MachineInstr::FrameSetup); } bool X86FrameLowering::canUseLEAForSPInEpilogue( diff --git a/llvm/test/CodeGen/X86/x86-interrupt_cld.ll b/llvm/test/CodeGen/X86/x86-interrupt_cld.ll new file mode 100644 index 00000000000..bbb109eb633 --- /dev/null +++ b/llvm/test/CodeGen/X86/x86-interrupt_cld.ll @@ -0,0 +1,17 @@ +; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Checks that interrupt handler code calls cld before calling an external +;; function. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; CHECK: cld +; CHECK: call + +define x86_intrcc void @foo(i8* %frame) { + call void @bar() + ret void +} + +declare void @bar() + |