c++templatesstringification

Stringify a template numeric argument


I have the following piece of code:

template<int maxRegNum> void f(MuliInstr instr);
template<> void f<0>(MuliInstr instr)
{
    if (instr.regA == 0) asm volatile ("mov r4, r0");
}

template<int maxRegNum> void f(MuliInstr instr)
{
    if (instr.regA == maxRegNum) asm volatile ("mov r4, r" ???);
    f<maxRegNum - 1>(instr);
}

The ??? is a place holder in the code where I want to stringify maxRegNum, is this somehow possible using C++11? A C-Preprocessor solution would be fine too :-)

I want to achieve to use this as a code generator avoiding to repeat writing this assembler move instruction 30 times if I need to make a choice out of 30 registers e.g.

Thanks for any hint on this question.

Kind Regards, Steve

EDIT: I want to achieve the following:

When I write f<31>(instr); somewhere in the code, I want the lines

if (instr.regA == 31) asm volatile ("mov r4, r31");
if (instr.regA == 30) asm volatile ("mov r4, r30");
if (instr.regA == 29) asm volatile ("mov r4, r29");
...
if (instr.regA == 0) asm volatile ("mov r4, r0");

being placed into thhe compilation result


Solution

  • Unfortunately, you probably require a string literal to be given asm, which you can't build with templates.

    You can use BOOST_PP_REPEAT_FROM_TO to do it easily with macros though:

    #include <boost/preprocessor/repetition/repeat_from_to.hpp>
    
    #define F_DEFINITION(_, maxRegNum, __)                                   \
    template<> void f<maxRegNum>(MuliInstr instr) {                          \
        if (instr.regA == maxRegNum) asm volatile ("mov r4, r" #maxRegNum);  \
        f<maxRegNum - 1>(instr);                                             \
    }
    
    
    BOOST_PP_REPEAT_FROM_TO(1, 30, F_DEFINITION, _)
    

    Without boost, you can still avoid some repetition by using macros. This should be equivalent code if your regA is an integer member:

    template<int maxRegNum> void f(MuliInstr instr) {
        static_assert(maxRegNum <= 31, "maxRegNum > 31 not supported");
        switch (instr.regA) {
    #define F_CASE(n) \
            case n: \
                if (maxRegNum >= n) asm volatile ( "mov r4, r" #n ); \
                break
    #define F_CASE_8(a, b, c, d, e, f, g, h) F_CASE(a); F_CASE(b); F_CASE(c); F_CASE(d); F_CASE(e); F_CASE(f); F_CASE(g); F_CASE(h)
            F_CASE_8(0, 1, 2, 3, 4, 5, 6, 7);
            F_CASE_8(8, 9, 10, 11, 12, 13, 14, 15);
            F_CASE_8(16, 17, 18, 19, 20, 21, 22, 23);
            F_CASE_8(24, 25, 26, 27, 28, 29, 30, 31);
        }
    }