www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - alloca without runtime?

reply =?UTF-8?B?5bKp5YCJIOa+qg==?= <mio.iwakura gmail.com> writes:
I've been playing around with using D with no runtime on Linux, 
but recently I was thinking it would be nice to have an alloca 
implementation. I was thinking I could just bump the stack 
pointer (with alignment considerations) but from what I 
understand compilers sometimes generate code that references 
variables relative to RSP instead of RBP? I've seen people saying 
that a proper alloca can't be implemented without help from the 
compiler...

I took a peek in druntime and found rt.alloca which has __alloca 
implemented with inline asm. I tried throwing that in my project 
and calling it but it segfaults on rep movsq. The comments in the 
code suggest it is trying to copy temps on the stack but I seem 
to get a really large garbage RCX, I don't fully follow what is 
going on yet.

Is there any way I can get a working alloca without using 
druntime, c runtime, etc?
Apr 29 2017
next sibling parent =?UTF-8?B?5bKp5YCJIOa+qg==?= <mio.iwakura gmail.com> writes:
On Sunday, 30 April 2017 at 05:07:31 UTC, 岩倉 澪 wrote:
 I've been playing around with using D with no runtime on Linux, 
 but recently I was thinking it would be nice to have an alloca 
 implementation. I was thinking I could just bump the stack 
 pointer (with alignment considerations) but from what I 
 understand compilers sometimes generate code that references 
 variables relative to RSP instead of RBP? I've seen people 
 saying that a proper alloca can't be implemented without help 
 from the compiler...

 I took a peek in druntime and found rt.alloca which has 
 __alloca implemented with inline asm. I tried throwing that in 
 my project and calling it but it segfaults on rep movsq. The 
 comments in the code suggest it is trying to copy temps on the 
 stack but I seem to get a really large garbage RCX, I don't 
 fully follow what is going on yet.

 Is there any way I can get a working alloca without using 
 druntime, c runtime, etc?
As a follow-up, here is a simple example of what I mean: first, let's create a main.d, we'll define our own entry point and make a call to alloca in main: extern (C): void _start() { asm nothrow nogc { naked; xor RBP, RBP; pop RDI; mov RSI, RSP; and RSP, -16; call main; mov RDI, RAX; mov RAX, 60; syscall; ret; } } pragma(startaddress, _start); int main(int argc, char** argv) { import rt.alloca; void* a = __alloca(42); return 0; } Next, let's make an rt directory and copy the source of druntime's rt.alloca into rt/alloca.d Now let's compile these: dmd -betterC -debuglib= -defaultlib= -boundscheck=off -vgc -vtls -c -gc main.d rt/alloca.d Great, now we need to strip symbols out to make this work, like so: objcopy -R '.data.*[0-9]TypeInfo_*' -R '.[cd]tors.*' -R .eh_frame -R minfo -R .group.d_dso -R .data.d_dso_rec -R .text.d_dso_init -R .dtors.d_dso_dtor -R .ctors.d_dso_ctor -N __start_minfo -N __stop_minfo main.o objcopy -R '.data.*[0-9]TypeInfo_*' -R '.[cd]tors.*' -R .eh_frame -R minfo -R .group.d_dso -R .data.d_dso_rec -R .text.d_dso_init -R .dtors.d_dso_dtor -R .ctors.d_dso_ctor -N __start_minfo -N __stop_minfo alloca.o With that out of the way, we are ready to link: ld main.o alloca.o And when we try to run ./a.out we get a segfault. What I want is a way to allocate on the stack (size of allocation not necessarily known at compile-time) and for the compiler to be aware that it can't generate code that refers to variables on the stack relative to rsp, or anything else that might break the naive implementation of alloca as simply bumping rsp with inline asm. Apparently this "magic" __alloca can't be used outside of the compiler, or is there a way to make it work?
May 04 2017
prev sibling parent reply Kagamin <spam here.lot> writes:
You can try ldc and llvm intrinsics
http://llvm.org/docs/LangRef.html#alloca-instruction
http://llvm.org/docs/LangRef.html#llvm-stacksave-intrinsic
May 04 2017
parent reply =?UTF-8?B?5bKp5YCJIOa+qg==?= <mio.iwakura gmail.com> writes:
On Thursday, 4 May 2017 at 12:50:02 UTC, Kagamin wrote:
 You can try ldc and llvm intrinsics
 http://llvm.org/docs/LangRef.html#alloca-instruction
 http://llvm.org/docs/LangRef.html#llvm-stacksave-intrinsic
Ah, yep! pragma(LDC_alloca) void* alloca(size_t); This appears to work with ldc. It would be nice if there was a way to do this with dmd/other compilers as well though. If it were up to me I'd have alloca defined by the language standard and every compiler would have to provide an implementation like this. At the very least I'd like to have an alloca that works with dmd, as I want to do debug builds with dmd and release builds with ldc.
May 04 2017
parent reply aberba <karabutaworld gmail.com> writes:
On Thursday, 4 May 2017 at 14:54:58 UTC, 岩倉 澪 wrote:
 On Thursday, 4 May 2017 at 12:50:02 UTC, Kagamin wrote:
 You can try ldc and llvm intrinsics
 http://llvm.org/docs/LangRef.html#alloca-instruction
 http://llvm.org/docs/LangRef.html#llvm-stacksave-intrinsic
Ah, yep! pragma(LDC_alloca) void* alloca(size_t); This appears to work with ldc. It would be nice if there was a way to do this with dmd/other compilers as well though. If it were up to me I'd have alloca defined by the language standard and every compiler would have to provide an implementation like this. At the very least I'd like to have an alloca that works with dmd, as I want to do debug builds with dmd and release builds with ldc.
embedded platform?
May 10 2017
parent =?UTF-8?B?5bKp5YCJIOa+qg==?= <mio.iwakura gmail.com> writes:
On Wednesday, 10 May 2017 at 20:25:45 UTC, aberba wrote:
 On Thursday, 4 May 2017 at 14:54:58 UTC, 岩倉 澪 wrote:
 On Thursday, 4 May 2017 at 12:50:02 UTC, Kagamin wrote:
 You can try ldc and llvm intrinsics
 http://llvm.org/docs/LangRef.html#alloca-instruction
 http://llvm.org/docs/LangRef.html#llvm-stacksave-intrinsic
Ah, yep! pragma(LDC_alloca) void* alloca(size_t); This appears to work with ldc. It would be nice if there was a way to do this with dmd/other compilers as well though. If it were up to me I'd have alloca defined by the language standard and every compiler would have to provide an implementation like this. At the very least I'd like to have an alloca that works with dmd, as I want to do debug builds with dmd and release builds with ldc.
embedded platform?
An embedded platform would be a good use-case for this, but I'm just trying to do this on Linux x86_64 personally. It's a fun experiment to see how far I can push D to give me low-level control without dependencies
May 10 2017