Need Help Understanding Operands in X86 MachineFunctionPass

Dear All,

I'm working on an X86 MachineFunctionPass that adds prefetch instructions to a function. I have code that adds a "prefetchnta <constant address>" instruction to x86 32-bit code. What I want to do is to add a "prefetchnta <constant address>" instruction to x86_64 code.

The code for adding the 32-bit instruction is:

BuildMI(MBB,MI,dl,TII->get(X86::PREFETCHNTA)).addReg(0).addImm(0).addReg(0).addImm(<constant>).addReg(0);

The code above doesn't work for x86_64, so I think I need to change the operands to the instruction. However, I have no idea what the different register and immediate arguments to this instruction represent. Do they somehow encode the Mod/RM bits used in x86 instruction encoding? Are they offset and register operands? I've checked the TableGen files, but their meaning appears cryptic to me.

Can someone explain to me what these operands are meant to represent?

Thanks in advance,

-- John T.

I'm working on an X86 MachineFunctionPass that adds prefetch instructions to a function. I have code that adds a "prefetchnta <constant address>" instruction to x86 32-bit code. What I want to do is to add a "prefetchnta <constant address>" instruction to x86_64 code.

Given that you don't actually want to execute this instruction ever, is there a reason to even emit the instruction? Why not just stick your ID directly into the code and then jump beyond it. Executing the instruction causes a slow down and it requires a bunch of extra bytes. If you can live with a 32-bit ID, it'll take 4 bytes. If you go the prefetchnta (or any of the other prefetch instructions) route, then on the x86_64, it looks like you're going to have 2 bytes of opcode, a mod r/m byte, and 8 bytes of address and look something like 0f 18 00 dd cc bb aa 00 00 00 00 (I probably got the mod r/m byte wrong, it's a /0 for prefetchnta at any rate). That's just going to add extra pressure to the icache.

The code for adding the 32-bit instruction is:

BuildMI(MBB,MI,dl,TII->get(X86::PREFETCHNTA)).addReg(0).addImm(0).addReg(0).addImm(<constant>).addReg(0);

That's surprising to me. What are all of those registers and immediates for?

Trying again from the correct email address, sorry if you get this twice.

I'm working on an X86 MachineFunctionPass that adds prefetch instructions to a function. I have code that adds a "prefetchnta <constant address>" instruction to x86 32-bit code. What I want to do is to add a "prefetchnta <constant address>" instruction to x86_64 code.

Given that you don't actually want to execute this instruction ever, is there a reason to even emit the instruction? Why not just stick your ID directly into the code and then jump beyond it. Executing the instruction causes a slow down and it requires a bunch of extra bytes. If you can live with a 32-bit ID, it'll take 4 bytes. If you go the prefetchnta (or any of the other prefetch instructions) route, then on the x86_64, it looks like you're going to have 2 bytes of opcode, a mod r/m byte, and 8 bytes of address and look something like 0f 18 00 dd cc bb aa 00 00 00 00 (I probably got the mod r/m byte wrong, it's a /0 for prefetchnta at any rate). That's just going to add extra pressure to the icache.

The code for adding the 32-bit instruction is:

BuildMI(MBB,MI,dl,TII->get(X86::PREFETCHNTA)).addReg(0).addImm(0).addReg(0).addImm(<constant>).addReg(0);

That's surprising to me. What are all of those registers and immediates for?

I'm working on an X86 MachineFunctionPass that adds prefetch instructions to a function. I have code that adds a "prefetchnta <constant address>" instruction to x86 32-bit code. What I want to do is to add a "prefetchnta <constant address>" instruction to x86_64 code.

Given that you don't actually want to execute this instruction ever, is there a reason to even emit the instruction?

It's true that I don't want to emit the instruction, but it may be easier to emit an instruction than to emit a constant into the instruction stream.

Also, I imagine that if I don't solve this problem with prefetchnta that I might run into it again when I write some other machine-level instrumentation. The prefetchnta is just a concrete example; more generally, I just need to understand how the operands to the x86 instructions work in the LLVM code generator. I figure that if I understand prefetchnta I'll have an easier time figuring out other instructions.

Why not just stick your ID directly into the code and then jump beyond it. Executing the instruction causes a slow down and it requires a bunch of extra bytes. If you can live with a 32-bit ID, it'll take 4 bytes. If you go the prefetchnta (or any of the other prefetch instructions) route, then on the x86_64, it looks like you're going to have 2 bytes of opcode, a mod r/m byte, and 8 bytes of address and look something like 0f 18 00 dd cc bb aa 00 00 00 00 (I probably got the mod r/m byte wrong, it's a /0 for prefetchnta at any rate). That's just going to add extra pressure to the icache.

I think the instrumentation already adds a jump around the prefetchnta.

The code for adding the 32-bit instruction is:

BuildMI(MBB,MI,dl,TII->get(X86::PREFETCHNTA)).addReg(0).addImm(0).addReg(0).addImm(<constant>).addReg(0);

That's surprising to me. What are all of those registers and immediates for?

That is precisely my question. What do all of those register and immediate arguments do?

-- John T.

...

The code for adding the 32-bit instruction is:

BuildMI(MBB,MI,dl,TII->get(X86::PREFETCHNTA)).addReg(0).addImm(0).add
Reg(0).addImm(<constant>).addReg(0);

That's surprising to me. What are all of those registers and immediates for?

That is precisely my question. What do all of those register and immediate arguments do?

-- John T.

The X86 backend records a machine memory operand using a sequence of five operands, as follows:

Base Register
Scale Amount
Index Register
Address offset
Segment register

See lib/Target/X86/MCTargetDesc/X86BaseInfo.h.

Preston

From: llvmdev-bounces@cs.uiuc.edu [mailto:llvmdev-bounces@cs.uiuc.edu] On Behalf Of John Criswell
Sent: Tuesday, September 11, 2012 1:42 PM
To: Steve Checkoway
Cc: LLVMdev@cs.uiuc.edu
Subject: Re: [LLVMdev] Need Help Understanding Operands in X86 MachineFunctionPass

...

The code for adding the 32-bit instruction is:

BuildMI(MBB,MI,dl,TII->get(X86::PREFETCHNTA)).addReg(0).addImm(0).add
Reg(0).addImm(<constant>).addReg(0);

That's surprising to me. What are all of those registers and immediates for?

That is precisely my question. What do all of those register and immediate arguments do?

-- John T.

The X86 backend records a machine memory operand using a sequence of five operands, as follows:

Base Register
Scale Amount
Index Register
Address offset
Segment register

See lib/Target/X86/MCTargetDesc/X86BaseInfo.h.

Thanks! This is exactly the information for which I was looking.

-- John T.