[llvm-dev] do any targets use address space modifiers to implement "near" or "far" pointers?

Peeter Joot via llvm-dev llvm-dev at lists.llvm.org
Tue Nov 1 13:49:21 PDT 2016


I'm attempting to implement a clang/llvm prototype of mixed mode x86 and x86_64 code. My intent is to be able to generate "32-bit" code that emulates another 32bit platform (without porting that code to 64-bit or intel, so that all the pointer references in that code can still be 32-bit), and run that code in a thread that explicitly allocates stack in "low memory". I've hacked enough of clang and llvm to make this work in a limited fashion, defining two address spaces:

-p0:32:32:32-p1:64:64:64

(and following the x64 linux model in some places (but not all, like the x64 specific ELF format)).

I'm now able to generate 32-bit memory model code and execute it in a 32-bit process. Pointers and stack and data references are all 32-bit, but the code is able to use 64-bit registers (like the x64 memory model, but all in the same process).

Now, I'm trying to see what's required to call out to 64-bit code from this "32-bit" code, and access that "high" memory range for calls to runtime infrastructure implemented 64-bit shared libraries. I see that I can define types (and indirectly pointers to those types) in my "far" address space:

typedef int a1int __attribute__( ( address_space( 1 ) ) );

The int * references in the IR do have the desired(1) address space, and generated code accessing a 32-bit pointer vs. a 64-bit pointer looks about right:


00000000000001c0 <addr0>:


1c0:  55 push  %rbp


1c1:  89 e5  mov %esp,%ebp


1c3:  89 7d fc mov %edi,-0x4(%rbp)


1c6:  8b 7d fc mov -0x4(%rbp),%edi


1c9:  67 8b 07 mov (%edi),%eax


1cc:  5d pop %rbp


1cd:  c3 retq


1ce:  66 90  xchg  %ax,%ax





00000000000001d0 <addr1>:


1d0:  55 push  %rbp


1d1:  89 e5  mov %esp,%ebp


1d3:  48 89 7d f8  mov %rdi,-0x8(%rbp)


1d7:  48 8b 7d f8  mov -0x8(%rbp),%rdi


1db:  8b 07  mov (%rdi),%eax


1dd:  5d pop %rbp


1de:  c3 retq

With IR:


; Function Attrs: nounwind uwtable


define i32 @addr0(i32* %p) #0 {


entry:


%p.addr = alloca i32*, align 4


store i32* %p, i32** %p.addr, align 4


%0 = load i32*, i32** %p.addr, align 4


%1 = load i32, i32* %0, align 4


ret i32 %1


}





; Function Attrs: nounwind uwtable


define i32 @addr1(i32 addrspace(1)* %p) #0 {


entry:


%p.addr = alloca i32 addrspace(1)*, align 4


store i32 addrspace(1)* %p, i32 addrspace(1)** %p.addr, align 4


%0 = load i32 addrspace(1)*, i32 addrspace(1)** %p.addr, align 4


%1 = load i32, i32 addrspace(1)* %0, align 4


ret i32 %1


}


However, sizeof() for such a pointer is still 4.

I find address spaces used in some GPU and opencl code. Are there any targets that utilize address spaces to generate the equivalent of "near" or "far" pointers, where the address range of a "near" pointer is less than that of a "far" pointer? If so, I'd like to look at that code, to see if I can model what I'm trying on that.



--
Peeter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161101/5519aafb/attachment.html>


More information about the llvm-dev mailing list