You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Top level array type variables with initializers are translated to global array type variables with initializers in C lang when they are arrays of int.
But if they are arrays of pointers to int or function, they are translated to global array variables without initializer and initialized in the function.
Example code:
var
foo =123
bar =456
cvar {.importc.}: cintproctest0=discardproctest1=discardlet# Array of int is translated to a C global variable with the initializer .
intArray = [123, 456]
# Following arrays are translated to C global variables without initializer.
ptrIntArray = [foo.addr, bar.addr]
ptrProcArray = [test0, test1]
ptrProcArray2 = [cast[proc () {.nimcall.}](cvar.addr), test0]
Nim Version
Nim Compiler Version 2.1.99 [Linux: amd64]
Compiled at 2024-09-12
Copyright (c) 2006-2024 by Andreas Rumpf
git hash: 793cee4
active boot switches: -d:release
Current Output
N_LIB_PRIVATE NIM_CONST tyArray__HU7qaqKu9czJLT84iCBJnsA intArray__testinit_u6 = {((NI)123),
((NI)456)}
;
// Following variables are initialized in `NimMainModule` function
N_LIB_PRIVATE tyArray__GvHRlUg9a1sDoochCmNrKXg ptrIntArray__testinit_u7;
N_LIB_PRIVATE tyArray__DNFs9cfpFz9asZni0hv9amgOQ ptrProcArray__testinit_u8;
N_LIB_PRIVATE tyArray__DNFs9cfpFz9asZni0hv9amgOQ ptrProcArray2__testinit_u10;
Use emit pragma and write C global variables with initializer.
Additional Information
Background:
I'm trying to translate this arm32 assebly code in Raspberry Pi Pico SDK to Nim code in order to write a Raspberry Pi Pico program without using Raspberry Pi Pico SDK (because using the SDK requires writing a CMake file): https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/pico_crt0/crt0.S
This code runs before main function and contains the vector table.
The vector table is an array of pointers to functions (interrupt service routines, reset handler and etc) but the first element is the stack pointer.
The address of the stack pointer is set in the linker script.
The symbol __StackTop has the address of the stack and it is referenced in C as an external variable:
Thank you! const array of function pointers without pragma worked when all initializer are procedures.
But when I add codegenDecl pragma, I got compile error: invalid pragma: codegenDecl: "[[gnu::section(\".vectors\")]] $# $# ".
I need to add [[gnu::section(\".vectors\")]] C attribute to put the vector table at the specific section.
And I need to put the address of extern cint variable to the vector table, but using addr or cast in const expression causes compile error.
Example code:
import std/volatile
# If `stackTop` is const, `stackTop.addr` is compile error.# Error: expression has no address#const stackTop {.importc: "__StackTop".}: cint = 0# If `stackTop` is let, `cast[proc () {.noconv.}](stackTop.addr)` is compile error.# Error: VM does not support 'cast' from tyPtr to tyProclet stackTop {.importc: "__StackTop".}: cintproctest0 {.noconv.} =discardconst ptrProcArray2 = [cast[proc () {.noconv.}](stackTop.addr), test0]
# The address of the register holds the address of vector table.constPPBVTOR=cast[ptrptrUncheckedArray[proc() {.noconv.}]](0xe0000000'u+0x0000ed08'u)
procmain=volatileStorePPBVTOR, cast[ptrUncheckedArray[proc() {.noconv.}]](ptrProcArray2.addr)
main()
When ptrProcArray2 is declared with let or var instead of const, I can use codegenDecl and cast without compile errors.
The first element of the vector table is the stack pointer.
The address of the stack pointer is assigned to the symbol __StackTop in the linker script.
It is referenced in C as an external variable:
Description
This issue is related to this:
#12216
Top level array type variables with initializers are translated to global array type variables with initializers in C lang when they are arrays of int.
But if they are arrays of pointers to int or function, they are translated to global array variables without initializer and initialized in the function.
Example code:
Nim Version
Nim Compiler Version 2.1.99 [Linux: amd64]
Compiled at 2024-09-12
Copyright (c) 2006-2024 by Andreas Rumpf
git hash: 793cee4
active boot switches: -d:release
Current Output
Expected Output
Known Workarounds
Use emit pragma and write C global variables with initializer.
Additional Information
Background:
I'm trying to translate this arm32 assebly code in Raspberry Pi Pico SDK to Nim code in order to write a Raspberry Pi Pico program without using Raspberry Pi Pico SDK (because using the SDK requires writing a CMake file):
https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/pico_crt0/crt0.S
This code runs before main function and contains the vector table.
The vector table is an array of pointers to functions (interrupt service routines, reset handler and etc) but the first element is the stack pointer.
The address of the stack pointer is set in the linker script.
The symbol
__StackTop
has the address of the stack and it is referenced in C as an external variable:How to access a linker script defined variable from C code is explained here:
https://sourceware.org/binutils/docs/ld/Source-Code-Reference.html
The vector table is needed to be declared with the initializer so that it is placed on flash memory on Raspberry Pi Pico.
I think this issue is low prioprity as I can workaround it using emit pragma.
The text was updated successfully, but these errors were encountered: