[llvm-dev] Generating a custom opcode from an LLVM intrinsic

Gus Smith via llvm-dev llvm-dev at lists.llvm.org
Sun Mar 18 19:39:46 PDT 2018


Craig, thanks for the quick response. That helps a lot. I had no clue they
were buried in there, though I guess I should have looked harder -- the hex
should have given me a clue, perhaps!

For the sake of my own edification (and not taking up too much of your
time) I will try to generate it myself. I've found the definition of the
"I" class at line 358 of llvm/lib/Target/X86/X86InstrFormats.td, which
helps a lot.

Let's assume I want to produce opcode 0x16 (which I'm using because it
doesn't seem to be implemented in gem5 otherwise, and would simply produce
a warning). Then my guess is that I should use something like:
def CACHEADD : I<0x16, FORMAT, (outs), (ins),
                   ASM, [(int_cache_add)]>, PD;

where FORMAT comes from
http://legup.eecg.utoronto.ca/doxygen/namespacellvm_1_1X86II.html
and ASM = ???
and i deleted  IIC_SSE_PREFETCH (because I'm not sure what this flag
indicates, but I assume it's not needed).
I'm not sure what that PD is or if it should stay.

Looking for input on this! Clearly it's not correct as-is, but I feel like
I'm at least understanding parts of it. Thanks!

For posterity, this page helped a lot, and probably should have been read
first: https://llvm.org/docs/TableGen/index.html
In smaller part, this one helped too, but read the above page first:
https://llvm.org/docs/TableGen/LangRef.html

On Sun, Mar 18, 2018 at 7:43 PM, Craig Topper <craig.topper at gmail.com>
wrote:

> Here's a couple examples for mapping an intrinsic to an X86 instruction
> from X86InstrInfo.td. If you look for int_x86_* in any X86Instr*.td you can
> find others.
>
> let Predicates = [HasCLFLUSHOPT], SchedRW = [WriteLoad] in
> def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
>                    "clflushopt\t$src", [(int_x86_clflushopt addr:$src)],
>                    IIC_SSE_PREFETCH>, PD;
>
> let Predicates = [HasCLWB], SchedRW = [WriteLoad] in
> def CLWB       : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src",
>                    [(int_x86_clwb addr:$src)], IIC_SSE_PREFETCH>, PD;
>
> The encoding information for the binary output is buried in these
> definitions too. If you tell me what opcode you've chosen I can tell you
> what the right things are to get the binary output.
>
>
> ~Craig
>
> On Sun, Mar 18, 2018 at 3:22 PM, Gus Smith via llvm-dev <
> llvm-dev at lists.llvm.org> wrote:
>
>> Hello all. LLVM newbie here. If anything seems glaringly wrong with my
>> use of LLVM, that's probably why.
>>
>> Here's what I'm trying to do. I have modified the gem5 simulator to
>> accept a "new" x86 instruction. I've done this by just reserving the opcode
>> in gem5's ISA specification, just as all other instructions are specified.
>>
>> I'm trying to get an LLVM backend to generate this opcode during code
>> generation. My current plan is:
>>
>>    1. During an LLVM pass, I'll detect a series of instructions which
>>    can be replaced with this new instruction. (The new instruction is a "cache
>>    compute" instruction -- in my passes, I replace a series of loads,
>>    operations, and stores with this single instruction.) This step is complete.
>>    2. I replace the series of instructions with an intrinsic. I have
>>    added an intrinsic using the instructions here
>>    <https://llvm.org/docs/ExtendingLLVM.html#adding-a-new-intrinsic-function>.
>>    This step is complete.
>>    3. During code generation, the intrinsic should be converted to this
>>    reserved opcode. This is where I'm stuck.
>>
>> I'm stuck on step 3. I have two main questions that should unblock me:
>>
>> Question 1: where is the code that maps from intrinsics to instructions?
>> The link above states:
>>
>> "Add support to the .td file for the target(s) of your choice in
>> lib/Target/*/*.td. This is usually a matter of adding a pattern to the
>> .td file that matches the intrinsic, though it may obviously require adding
>> the instructions you want to generate as well. There are lots of examples
>> in the PowerPC and X86 backend to follow."
>>
>> However, looking through these examples isn't illuminating anything for
>> me. Any more documentation or high-level explanation on this subject would
>> be really helpful. I have read something about "lowering" of intrinsics;
>> not sure if that's relevant.
>>
>> Question 2: will I be able to generate this opcode directly from the
>> intrinsic, or will I have to add the opcode as an LLVM IR instruction and
>> specify how it gets compiled? I can imagine two options:
>> option 1: I can define a "translation" from intrinsic straight to an x86
>> opcode.
>> option 2: I can define a "translation" (perhaps in a .td file? I think
>> that's what they're used for) which translates my intrinsic into a new
>> instruction, and then I can define another translation which will map the
>> new instruction to my opcode during code gen. If this is the case, I'm not
>> sure there's any point to having an intrinsic; I should just add a new
>> instruction instead.
>>
>> Hoping someone can help! As you can tell, I'm a little lost...the
>> documentation for LLVM is great, but it's a little above my level right now
>> :)
>>
>> Gus Smith, PSU
>>
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180318/3f58b518/attachment.html>


More information about the llvm-dev mailing list