llvm.org GIT mirror llvm / 228232b
Rewrite mwait and monitor support and custom lower arguments. Fixes PR8573. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120404 91177308-0d34-0410-b5e6-96231b3b80d8 Eric Christopher 9 years ago
4 changed file(s) with 101 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
94439443 }
94449444
94459445 MachineBasicBlock *
9446 X86TargetLowering::EmitMonitor(MachineInstr *MI, MachineBasicBlock *BB) const {
9447 assert((Subtarget->hasSSE3()) && "Target must have SSE3 features enabled");
9448
9449 DebugLoc dl = MI->getDebugLoc();
9450 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
9451
9452 // Address into RAX/EAX, other two args into ECX, EDX.
9453 unsigned MemOpc = Subtarget->is64Bit() ? X86::LEA64r : X86::LEA32r;
9454 unsigned MemReg = Subtarget->is64Bit() ? X86::RAX : X86::EAX;
9455 MachineInstrBuilder MIB = BuildMI(*BB, MI, dl, TII->get(MemOpc), MemReg);
9456 for (int i = 0; i < X86::AddrNumOperands; ++i)
9457 (*MIB).addOperand(MI->getOperand(i));
9458
9459 unsigned ValOps = X86::AddrNumOperands;
9460 BuildMI(*BB, MI, dl, TII->get(TargetOpcode::COPY), X86::ECX)
9461 .addReg(MI->getOperand(ValOps).getReg());
9462 BuildMI(*BB, MI, dl, TII->get(TargetOpcode::COPY), X86::EDX)
9463 .addReg(MI->getOperand(ValOps+1).getReg());
9464
9465 // The instruction doesn't actually take any operands though.
9466 BuildMI(*BB, MI, dl, TII->get(X86::MONITORrrr));
9467
9468 MI->eraseFromParent(); // The pseudo is gone now.
9469 return BB;
9470 }
9471
9472 MachineBasicBlock *
9473 X86TargetLowering::EmitMwait(MachineInstr *MI, MachineBasicBlock *BB) const {
9474 assert((Subtarget->hasSSE3()) && "Target must have SSE3 features enabled");
9475
9476 DebugLoc dl = MI->getDebugLoc();
9477 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
9478
9479 // First arg in ECX, the second in EAX.
9480 BuildMI(*BB, MI, dl, TII->get(TargetOpcode::COPY), X86::ECX)
9481 .addReg(MI->getOperand(0).getReg());
9482 BuildMI(*BB, MI, dl, TII->get(TargetOpcode::COPY), X86::EAX)
9483 .addReg(MI->getOperand(1).getReg());
9484
9485 // The instruction doesn't actually take any operands though.
9486 BuildMI(*BB, MI, dl, TII->get(X86::MWAITrr));
9487
9488 MI->eraseFromParent(); // The pseudo is gone now.
9489 return BB;
9490 }
9491
9492 MachineBasicBlock *
94469493 X86TargetLowering::EmitVAARG64WithCustomInserter(
94479494 MachineInstr *MI,
94489495 MachineBasicBlock *MBB) const {
1004010087 case X86::PCMPESTRM128MEM:
1004110088 case X86::VPCMPESTRM128MEM:
1004210089 return EmitPCMP(MI, BB, 5, true /* in mem */);
10090
10091 // Thread synchronization.
10092 case X86::MONITOR:
10093 return EmitMonitor(MI, BB);
10094 case X86::MWAIT:
10095 return EmitMwait(MI, BB);
1004310096
1004410097 // Atomic Lowering.
1004510098 case X86::ATOMAND32:
820820 MachineBasicBlock *EmitPCMP(MachineInstr *BInstr, MachineBasicBlock *BB,
821821 unsigned argNum, bool inMem) const;
822822
823 /// Utility functions to emit monitor and mwait instructions. These
824 /// need to make sure that the arguments to the intrinsic are in the
825 /// correct registers.
826 MachineBasicBlock *EmitMonitor(MachineInstr *MI, MachineBasicBlock *BB)
827 const;
828 MachineBasicBlock *EmitMwait(MachineInstr *MI, MachineBasicBlock *BB) const;
829
823830 /// Utility function to emit atomic bitwise operations (and, or, xor).
824831 /// It takes the bitwise instruction to expand, the associated machine basic
825832 /// block, and the associated X86 opcodes for reg/reg and reg/imm.
36393639 //===---------------------------------------------------------------------===//
36403640
36413641 // Thread synchronization
3642 def MONITOR : I<0x01, MRM_C8, (outs), (ins), "monitor",
3643 [(int_x86_sse3_monitor EAX, ECX, EDX)]>,TB, Requires<[HasSSE3]>;
3644 def MWAIT : I<0x01, MRM_C9, (outs), (ins), "mwait",
3645 [(int_x86_sse3_mwait ECX, EAX)]>, TB, Requires<[HasSSE3]>;
3642 let usesCustomInserter = 1 in {
3643 def MONITOR : I<0, Pseudo, (outs), (ins i32mem:$src1, GR32:$src2, GR32:$src3),
3644 "# MONITORrrr PSUEDO",
3645 [(int_x86_sse3_monitor addr:$src1, GR32:$src2, GR32:$src3)]>;
3646 def MWAIT : I<0, Pseudo, (outs), (ins GR32:$src1, GR32:$src2),
3647 "# MWAITrr PSEUDO",
3648 [(int_x86_sse3_mwait GR32:$src1, GR32:$src2)]>;
3649 }
3650
3651 let Uses = [EAX, ECX, EDX] in
3652 def MONITORrrr : I<0x01, MRM_C8, (outs), (ins), "monitor", []>, TB,
3653 Requires<[HasSSE3]>;
3654 let Uses = [ECX, EAX] in
3655 def MWAITrr : I<0x01, MRM_C9, (outs), (ins), "mwait", []>, TB,
3656 Requires<[HasSSE3]>;
36463657
36473658 //===---------------------------------------------------------------------===//
36483659 // Non-Instruction Patterns
0 ; RUN: llc < %s -o - -march=x86-64 | FileCheck %s
1 ; PR8573
2
3 ; CHECK: _foo:
4 ; CHECK: leaq (%rdi), %rax
5 ; CHECK-NEXT: movl %esi, %ecx
6 ; CHECK-NEXT: monitor
7 define void @foo(i8* %P, i32 %E, i32 %H) nounwind {
8 entry:
9 tail call void @llvm.x86.sse3.monitor(i8* %P, i32 %E, i32 %H)
10 ret void
11 }
12
13 declare void @llvm.x86.sse3.monitor(i8*, i32, i32) nounwind
14
15 ; CHECK: _bar:
16 ; CHECK: movl %edi, %ecx
17 ; CHECK-NEXT: movl %esi, %eax
18 ; CHECK-NEXT: mwait
19 define void @bar(i32 %E, i32 %H) nounwind {
20 entry:
21 tail call void @llvm.x86.sse3.mwait(i32 %E, i32 %H)
22 ret void
23 }
24
25 declare void @llvm.x86.sse3.mwait(i32, i32) nounwind