digitalmars.D.ldc - Naked functions
- Jack Applegame (3/6) Jul 23 2018 doesn't work.
- David Nadlinger (6/10) Jul 23 2018 asm {} is the x86-only DMD syntax.
- Jack Applegame (2/15) Jul 25 2018 It works. Thanks.
- Jack Applegame (10/39) Jul 27 2018 There is one strange thing.
- Jack Applegame (1/6) Jul 27 2018
- kinke (20/27) Jul 27 2018 In this case I'd think it has to, you're even using an explicit
- Jack Applegame (12/41) Jul 27 2018 My example is incorrect.
- Jack Applegame (3/10) Jul 27 2018 But now it compiles to
- kinke (8/18) Jul 27 2018 'Now' (current/yesterday's PR), this crashes the compiler for the
- kinke (3/5) Jul 27 2018 Ah wait, that remaining unreachable is apparently
- Jack Applegame (2/8) Jul 27 2018 Good work, thank you.
Hello. How to define a naked function on the ARM platform?asm { naked; }doesn't work.
Jul 23 2018
Hi Jack, On 23 Jul 2018, at 23:06, Jack Applegame via digitalmars-d-ldc wrote:asm {} is the x86-only DMD syntax. See https://github.com/ldc-developers/ldc/pull/2773 which adds a naked attribute; it would to great to hear whether this fits your use case. — Davidasm { naked; }doesn't work.
Jul 23 2018
On Monday, 23 July 2018 at 23:36:01 UTC, David Nadlinger wrote:Hi Jack, On 23 Jul 2018, at 23:06, Jack Applegame via digitalmars-d-ldc wrote:It works. Thanks.asm {} is the x86-only DMD syntax. See https://github.com/ldc-developers/ldc/pull/2773 which adds a naked attribute; it would to great to hear whether this fits your use case. — Davidasm { naked; }doesn't work.
Jul 25 2018
On Monday, 23 July 2018 at 23:36:01 UTC, David Nadlinger wrote:Hi Jack, On 23 Jul 2018, at 23:06, Jack Applegame via digitalmars-d-ldc wrote:There is one strange thing. Should the compiler to insert the return command for naked functions? I suppose it shouldn't. For example: naked.cppasm {} is the x86-only DMD syntax. See https://github.com/ldc-developers/ldc/pull/2773 which adds a naked attribute; it would to great to hear whether this fits your use case. — Davidasm { naked; }doesn't work.__attribute__ ((naked)) int sum(int a, int b) { return a + b; }$ arm-none-eabi-gcc -c naked.cpp -O3 -o naked_cpp.o $ arm-none-eabi-objdump -d naked_cpp.o00000000 <_Z3sumii>: 0: e0800001 add r0, r0, r1naked.dnaked int sum(int a, int b) { return a + b; }$ ldc2 -c -mtriple=thumb-none-linux-eabi -mcpu=cortex-m3 -O3 naked.d -of naked_d.o $ arm-none-eabi-objdump -d naked_d.o00000000 <_D5naked3sumFiiZi>: 0: 4408 add r0, r1 2: 4770 bx lr <------- WHY???Looks like LDC removes the prologue/epilogue, but not completely, leaving the return from function.
Jul 27 2018
$ arm-none-eabi-gcc -c -mcpu=cortex-m3 -mthumb naked.cpp -O3 -o naked_cpp.ogenerates00000000 <_Z3sumii>: 0: 4408 add r0, r1 2: bf00 nop
Jul 27 2018
On Friday, 27 July 2018 at 10:11:03 UTC, Jack Applegame wrote:There is one strange thing. Should the compiler to insert the return command for naked functions? I suppose it shouldn't. [...] Looks like LDC removes the prologue/epilogue, but not completely, leaving the return from function.In this case I'd think it has to, you're even using an explicit return statement. I'm not familiar with the ARM calling convention wrt. call/return, but gcc emitting no return seems very strange (where is it supposed to continue after the add instruction? the next function in the final binary?!). Did you test that it actually works as intended? I updated the PR yesterday, so that LDC's pro-/epilogue is excluded too, which allows the usage of params (not just in some cases like yours together with -O). [Your sample doesn't work anymore now, crashing the compiler, as it now requires __asm() and/or inlineIR() to work with params.] AFAIK, a return is required as we go through LLVM IR and not directly to the assembler (which for example allows you to write the function body in LLVM IR). Yesterday's variant probably crashes if there's no explicit return (e.g., with __asm() and a naked function returning void). I take it this is just a toy example for gcc/LDC comparison, or do you really need to omit a return instruction in real-world code?
Jul 27 2018
On Friday, 27 July 2018 at 17:53:51 UTC, kinke wrote:On Friday, 27 July 2018 at 10:11:03 UTC, Jack Applegame wrote:My example is incorrect. Actually, GCC documentation recommends to use only basic assembly in naked functions and Clang completely disallows the use of anything other than asm statement. But both remove the return instruction. Compare: https://godbolt.org/g/yVzpPx https://godbolt.org/g/fe9pNYThere is one strange thing. Should the compiler to insert the return command for naked functions? I suppose it shouldn't. [...] Looks like LDC removes the prologue/epilogue, but not completely, leaving the return from function.In this case I'd think it has to, you're even using an explicit return statement. I'm not familiar with the ARM calling convention wrt. call/return, but gcc emitting no return seems very strange (where is it supposed to continue after the add instruction? the next function in the final binary?!). Did you test that it actually works as intended? I updated the PR yesterday, so that LDC's pro-/epilogue is excluded too, which allows the usage of params (not just in some cases like yours together with -O). [Your sample doesn't work anymore now, crashing the compiler, as it now requires __asm() and/or inlineIR() to work with params.] AFAIK, a return is required as we go through LLVM IR and not directly to the assembler (which for example allows you to write the function body in LLVM IR). Yesterday's variant probably crashes if there's no explicit return (e.g., with __asm() and a naked function returning void).I take it this is just a toy example for gcc/LDC comparison, or do you really need to omit a return instruction in real-world code?I'm trying to write a simple kernel with multithreading support on bare metal (Cortex-M3). In the context switching function, the compiler-inserted return is unnecessary, but not a problem.
Jul 27 2018
This codeimport ldc.llvmasm; naked void foo() { __asm("mov lr, 0xfffffffd", ""); }Definitely should compile toBut now it compiles tobx lr
Jul 27 2018
On Friday, 27 July 2018 at 19:34:49 UTC, Jack Applegame wrote:This code'Now' (current/yesterday's PR), this crashes the compiler for the aforementioned reason. Interestingly, clang also goes through IR (see -emit-llvm and compare with LDC's -output-ll output) but appends an unreachable at the end, which gets rid of the error about non-terminated function. I've just implemented this, but the unreachable makes it to the final assembly, whereas it vanishes at some point for clang.import ldc.llvmasm; naked void foo() { __asm("mov lr, 0xfffffffd", ""); }Definitely should compile toBut now it compiles tobx lr
Jul 27 2018
On Friday, 27 July 2018 at 20:17:12 UTC, kinke wrote:I've just implemented this, but the unreachable makes it to the final assembly, whereas it vanishes at some point for clang.Ah wait, that remaining unreachable is apparently Windows-specific and vanishes for Linux.
Jul 27 2018
On Friday, 27 July 2018 at 20:28:11 UTC, kinke wrote:On Friday, 27 July 2018 at 20:17:12 UTC, kinke wrote:Good work, thank you.I've just implemented this, but the unreachable makes it to the final assembly, whereas it vanishes at some point for clang.Ah wait, that remaining unreachable is apparently Windows-specific and vanishes for Linux.
Jul 27 2018