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>