I am working on a few changes to make Clang 3.1 accept a few more Microsoft-specific extensions and play nice with the MSVC linker (via ClangVSx).
My current task is to implement __debugbreak(), which is boiled down into an INT3 instruction when MSVC deals with it. Should be simple enough, or so I thought…
During CodeGenFunction::EmitX86BuiltinExpr() I added a call to the x86_int interrupt intrinsic, thus:
int32_t Interrupt = 3;
Value *ArgValue = llvm::ConstantInt::get(Int8Ty, Interrupt);
llvm::Type *ArgType = ArgValue->getType();
Value *F = CGM.getIntrinsic(Intrinsic::x86_int, ArgType);
return Builder.CreateCall(F, ArgValue);
which arrives in the LL disassembly as
call void @llvm.x86.int.i8(i8 3)
… but so far I can’t discern how to properly lower that into an INT3 during code generation (or earlier … I’m still pretty new to the LLVM codebase). In the x86 dasm I end up with
E8 00 00 00 00 call _llvm.x86.int.i8
I notice that there is a definition for INT3 in the X86InstrSystem.td table file:
def INT3 : I<0xcc, RawFrm, (outs), (ins), “int3”,
[(int_x86_int (i8 3))]>;
Which suggests to me that it should already be able to figure out what I’m after… but perhaps I’m being naive.
Anyone who can help point me to the right area of the project to examine (I’ve been sat trying to trace through and find what’s missing but to no avail) or has any other hints / tips … some guidance would be very appreciated!