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

Friedman, Eli via llvm-dev llvm-dev at lists.llvm.org
Tue Nov 1 14:08:52 PDT 2016


On 11/1/2016 1:49 PM, Peeter Joot via llvm-dev wrote:
> 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: 55push %rbp
>
> 1c1: 89 e5 mov%esp,%ebp
>
> 1c3: 89 7d fcmov%edi,-0x4(%rbp)
>
> 1c6: 8b 7d fcmov-0x4(%rbp),%edi
>
> 1c9: 67 8b 07mov(%edi),%eax
>
> 1cc: 5dpop%rbp
>
> 1cd: c3retq
>
> 1ce: 66 90 xchg %ax,%ax
>
>
> 00000000000001d0 <addr1>:
>
> 1d0: 55push %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: 5dpop%rbp
>
> 1de: c3retq
>
> 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.
>

sizeof(), as in the C sizeof() operator?  You probably need to override 
TargetInfo::getPointerWidthV() and TargetInfo::getPointerAlignV() for 
your target.  See clang/lib/Basic/Targets.cpp.

-Eli

-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project

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


More information about the llvm-dev mailing list