I'm trying to create a template that emits a single line of ARM assembly with 
two register args and two immediate args. The asm statement's triple-quotes was 
causing a problem when the template expanded its arguments, so I put the asm 
statement in a proc and call that proc from the template. Here's my best 
attempt so far:
    
    
    {.push stackTrace:off.}
    proc setField[T](
        regVal: T, bitOffset: static int, bitWidth: static int, fieldVal: 
RegisterVal
    ): T {.asmNoStackFrame.} =
      asm """
        BFI `regVal`, `fieldVal`, #bitOffset, #bitWidth
      """
    {.pop.}
    
    # chained field modify
    template GPIOAEN*(regVal: RCC_AHB1ENR_Val, fieldVal: uint32): 
RCC_AHB1ENR_Val =
      setField[RCC_AHB1ENR_Val](regVal, 0, 1, fieldVal)
    
    
    Run

This results in the following error:
    
    
    /var/folders/_8/x78bn0wj3nz4gwnbtm47qsqw0000gn/T//ccBPqMCO.s: Assembler 
messages:
    /var/folders/_8/x78bn0wj3nz4gwnbtm47qsqw0000gn/T//ccBPqMCO.s:93: Error: ARM 
register expected -- `bfi regVal_p0,fieldVal_p3,#bitOffset,#bitWidth'
    Error: execution of an external compiler program 'arm-none-eabi-gcc -c -w 
-fmax-errors=4 -mthumb -march=armv7 -mtune=cortex-m4   
-I/opt/homebrew/Cellar/nim/2.0.0_1/nim/lib -I/Users/hidepath/code/nim/arm/src 
-o /Users/hidepath/code/nim/arm/build/nimcache/@mmain_7.nim.c.o 
/Users/dwhall/GoogleDrive/code/nim/arm/build/nimcache/@mmain_7.nim.c' failed 
with exit code: 1
    
    
    Run

Does anyone know a way to make this work? Even if I get past the 
argument-to-register error (above), I don't see how I'll ever get the 
argument-to-immediate-value conversion. I have read about, but never coded 
macros; do they hold any hope of resolving this?

If you want to play with it, see main_7.nim in: 
<https://github.com/dwhall/arm_sandbox> and use `nimble cross` to cross-compile 
with your local arm-none-eabi-gcc toolchain. The project may have MacOS and 
VSCode assumptions.

Reply via email to