Как включить новую строку в макрос C ++ или как использовать шаблоны C ++, чтобы сделать то же самое? - PullRequest
3 голосов
/ 10 октября 2009

я увидел следующий вопрос: Как создать новую строку в макросе cpp?

Позвольте мне дать краткое требование о необходимости новой строки в препроцессоре C ++. Я работаю над компилятором ARM Realview 3.1 над кодом, который использует встроенный ассемблерный код с кодом C ++.

#define DEFINE_FUNCTION(rtype, op, val) \
    __asm rtype nt_##op(void*) { \   
      str lr, [sp, ##val];bl vThunk_##op;ldr lr, [sp,##val];bx lr; \
    } \
   void vThunk_##op(void*)

DEFINE_FUNCTION(void*, mov_lt, #0x04)
{
     // do some operation
}

Приведенный выше макрос объявляет встроенную функцию сборки, которая принудительно требует новой строки между каждым оператором в теле функции.

Я думаю, это потому, что текст в теле функции отправляется вслепую ARM-ассемблеру компилятором ARM.

Почему препроцессор C ++ до сих пор не поддерживает многострочные замены? а также я не могу использовать # в строке замены. например, для этого вида сборки,

str lr, [sp, #0x04]

Я перепробовал множество методов и способов, но ничего не получилось. ARM ассемблер / компилятор настолько прост, что в GCC нет API, подобного asm volatile.

Макрос DEFINE_FUNCTION используется во многих местах, поэтому не может его игнорировать.

Итак, в крайнем случае подумайте о следующих решениях:

  • Использование препроцессора m4 вместо препроцессора C ++
  • Для достижения этой цели используйте шаблоны C ++ и замените DEFINE_FUNCTION с помощью grep / sed

Может кто-нибудь дать мне указатели или способы сделать вышеупомянутые вещи? Я не могу использовать любой компилятор, кроме компилятора ARM Realview 3.1.

Мне нужно некоторое расширение, как показано ниже, с новой строкой для, DEFINE_FUNCTION(void*, mov_lt, #0x04) {},

__asm void* nt_mov_lt(void*) {   
      str lr, [sp, 0x04];
      bl vThunk_mov_lt;
      ldr lr, [sp,0x04];
      bx lr;
    }
 void vThunk_mov_lt(void*)
 {
     // do something
  }

Ответы [ 3 ]

3 голосов
/ 12 октября 2009

Я успешно решил вышеуказанную проблему, используя препроцессор GNU m4.

m4_define('DEFINE_FUNCTION','
     __asm rtype nt_$2(void*) {  
      str lr, [sp, $3];
      bl vThunk_$1;
      ldr lr, [sp,$3];
      bx lr;
    } 
   void vThunk_$2(void*)')

DEFINE_FUNCTION(void*, mov_lt, 0x04)
{
}

Предварительная обработка вышеуказанного кода с использованием m4 решила мою проблему с требованием новой строки в коде. Запустил m4 -P в качестве события предварительной сборки, чтобы исходный файл обрабатывался еще до того, как начался этап препроцессора C и стадии компиляции.

Спасибо за помощь и извините за то, что много путаю. Но в последних компиляторах C ++ действительно есть место для хорошего препроцессора макросов.

1 голос
/ 29 января 2011

каждая газовая версия имеет другой символ замещения новой строки например AVR имеет $ ищите персонажа для газовой версии ARM

0 голосов
/ 10 октября 2009

Ваш пример очень запутанный, но разве это не сработает?

#define DEFINE_FUNCTION(rtype, op, val) \
    __asm rtype nt_##op(void*) { \   
      str lr, [sp, val];\
      bl vThunk_##op;\
      ldr lr, [sp,val];\
      bx lr;\
    }\
   void vThunk_##op(void*)

и при вызове как

DEFINE_FUNCTION(void*, mov_lt, 0x04)  // notice no # here
{
     // do some operation
}

вы получите

__asm void* nt_mov_lt(void*) {   
      str lr, [sp, 0x04];
      bl vThunk_mov_lt;
      ldr lr, [sp,0x04];
      bx lr;
    }
 void vThunk_mov_lt(void*)
 {
     // do something
 }

именно то, что вы просите.

...