Imagine you want to define a C preprocessor statement like this:
#define NUM_NOPS(i) .....
and later on, in your code:
NUM_NOPS(5);
and you want your preprocessor to roll out the following code:
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
This is not as easy as it looks like. One possibility is to use Boost’s Preprocessor Repetition Utility: <boost/preprocessor/repetition/repeat.hpp>. But however, let’s assume you don’t want to use any third party libraries. There is one further possibility. You can use GCC’s unrool loops functionality:
#pragma GCC push_options
#pragma GCC optimize ("unroll-loops")
#pragma GCC optimize ("O2")
void nops() {
int i = 0;
for(; i < 10 ; i++) {
asm volatile("nop");
}
}
#pragma GCC pop_options
int main(void) {
nops();
}
You should compile it with:
gcc -c -o test.o -O3 test.c
Having a look at the disassembly proves, that your loop was rolled out:
objdump -d test.o test.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <nops>: 0: 90 nop 1: 90 nop 2: 90 nop 3: 90 nop 4: 90 nop 5: 90 nop 6: 90 nop 7: 90 nop 8: 90 nop 9: 90 nop a: c3 retq Disassembly of section .text.startup: 0000000000000000 <main>: 0: 31 c0 xor %eax,%eax 2: e8 00 00 00 00 callq 7 <main+0x7> 7: f3 c3 repz retq