Peeter Joot via llvm-dev
2016-Nov-01 20:49 UTC
[llvm-dev] do any targets use address space modifiers to implement "near" or "far" pointers?
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>
Friedman, Eli via llvm-dev
2016-Nov-01 21:08 UTC
[llvm-dev] do any targets use address space modifiers to implement "near" or "far" pointers?
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>