Reducing source code: weak+alias values in array

Artur Skawina via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Apr 29 06:57:45 PDT 2015


On 04/27/15 19:49, Jens Bauer via Digitalmars-d-learn wrote:
> I was wondering if there's a way to reduce my bulky startup files a bit.
> 
> If using the GNU Assembler (GAS), then one can reduce the code using a macro like this:
> 
> 
> /* The EXC macro makes a weak+alias for the
>  * symbol 'value', then it stores the value in memory: */
>     .macro        EXC    value,defaultValue
>     .ifnb        \defaultValue
>     .weakref    \value,\defaultValue
>     .else
>     .weakref    \value,defaultExceptionVector
>     .endif
>     .4byte        \value
>     .endm
> 
> 
> /* The exception vector now looks quite simple: */
> isr_vector:
>     .4byte        _stack
>     EXC        Reset_Handler,defaultResetHandler
>     EXC        NMI_Handler
>     EXC        HardFault_Handler
>     EXC        MemManage_Handler
>     EXC        BusFault_Handler
>     EXC        UsageFault_Handler
>     .4byte        0
>     .4byte        0
>     .4byte        0
>     .4byte        0
>     EXC        SVC_Handler
>     EXC        DebugMon_Handler
>     .4byte        0
>     EXC        PendSV_Handler
>     EXC        SysTick_Handler
> 
> An example on one of my bulky startup files:
> https://github.com/jens-gpio/MCU/blob/master/startup/stm/stm32f439_startup.d

Just create a helper module, which the startup files can all
use to generate the data from a dsl. Eg

   import my.helper.mod;
   
   mixin(VectorFuncs!(q{
      PTR stack = {`_stack`};
      EXC Reset_Handler = {`defaultResetHandler`};
      EXC NMI_Handler;
      EXC HardFault_Handler;
      PAD pad01;
      PAD pad02;
      //...
   }));


// Then, in my.helper.mod:

   @property /*@section("discard.etc")*/ VectorFuncs(string dsl)() {
      static struct A {
         struct PTR { string n; @property s() {return `cast(VectorFunc)&`~n;} }
         struct PAD { string n; @property s() {return `cast(VectorFunc)null`;} }
         struct EXC { string n = `defaultExceptionHandler`; @property s() {return null;} }
         mixin(dsl);
      }
      string code;

      foreach (I, M; A.init.tupleof)
         static if (is(typeof(M)==A.EXC))
            code ~= `@weakalias("`~M.n~`") extern (C) void ` ~ __traits(identifier, A.tupleof[I]) ~ "();\n";

      code ~= "\n at isr_vector VectorFunc[] g_pfnVectors = [\n";
      foreach (I, M; A.init.tupleof)
            code ~= "   " ~ (M.s?M.s:"&"~__traits(identifier, A.tupleof[I])) ~ ",\n";
      code ~= "];\n";

      return code;
   }

and what the compiler will see when building the startup modules will look like

   @weakalias("defaultResetHandler") extern (C) void Reset_Handler();
   @weakalias("defaultExceptionHandler") extern (C) void NMI_Handler();
   @weakalias("defaultExceptionHandler") extern (C) void HardFault_Handler();

   @isr_vector VectorFunc[] g_pfnVectors = [
      cast(VectorFunc)&_stack,
      &Reset_Handler,
      &NMI_Handler,
      &HardFault_Handler,
      cast(VectorFunc)null,
      cast(VectorFunc)null,
   ];

artur


More information about the Digitalmars-d-learn mailing list