Generate data16 assembly instruction for TLS with PIC

Hi all,

System: x86-64 ubuntu 11.04
LLVM: 3.0
gcc: 4.5.2

I declare a thread_local global variable and access it in a function in llvm IR.
for example,

@my_value = linkonce thread_local global %dummy* null

define void @test1() {
entry:
%load_my_value = load %dummy** @my_value

}

After that, I use the following command:

bash$ llc -relocation-model=pic test.ll

And I have test.s which is an assembly file.

I tried to build it with gcc, but I have the following warning

bash$ gcc -c test.s

test.s: Assembler messages:
test.s:43: Warning: stand-alone `data16’ prefix

I just wonder why I have data16 instruction in my assembly file.
(ps. If I build it with “llc test.ll”, the assembly file will not have data16 instruction)

I search the llvm project and find some clues in this file: lib/Target/X86/X86MCInstLower.cpp
static void LowerTlsAddr(…)
{
bool is64Bits = MI.getOpcode() == X86::TLS_addr64;

if (is64Bits) {
MCInst prefix;
prefix.setOpcode(X86::DATA16_PREFIX);

}


}

I think it is the logic to generate data16 instruction, but I wonder why gcc report warning. Is it a LLVM’s bug?
Thanks for your time in advance :smiley:

Hey Wei-zhi,

I also had this issue with the X86 backend. And, unfortunately, searching for the warning did not turn up too much information. My solution was to emit a raw 0x66 byte in place of the data16 prefix. I believe those are equivalent and the assembler is much happier about it…

#if LLVM_31_MERGE
SmallString<11> byte;
byte = “\t.byte 0x66”;
OutStreamer.EmitRawText(byte);
#else /* LLVM_31_MERGE /
prefix.setOpcode(X86::DATA16_PREFIX);
OutStreamer.EmitInstruction(prefix);
#endif /
LLVM_31_MERGE */

-Cameron