Адрес локальной метки в GNU G CC Assembely - PullRequest
0 голосов
/ 26 мая 2020

Я пытаюсь использовать какой-нибудь ассемблерный код PP C в C, но у меня возникают проблемы с пониманием и переносом этой конкретной части ASM в формат GNU G CC:

...
   b 1f
1:   
   lis  p0, HI(2f)      
   ori  p0, p0, LO(2f)
   mtsrr0  p0
   rfi
2:
   mtssr0 p1 /* Restore srr0 & srr1 */
   mtssr1 p2
...

Речь идет о тех строках, которые ссылаются на 2f . Мне известно о Local Labels , и я могу только предположить, что это то, что подразумевается под 2f в этих двух инструкциях. Глядя на более общую инструкцию mtspr , параметр RS должен быть регистром.

EDIT: Питер Кордес помог мне понять назначение этого кода. Похоже, мы используем lis и ori для построения 32-битного адреса метки 2: для загрузки в ssr0. Следующая цитата из PowerP C Architecture Primer полностью объясняет назначение этой сборки.

Сохранение / восстановление регистров (SRR0 и SRR1) - SRR0 содержит адрес инструкции, в которой прерванный процесс должен продолжить. Когда выполняется rfi, выполнение инструкции продолжается по адресу в SRR0. В Книге E SRR0 используется для некритических прерываний. SRR1 содержит информацию о состоянии машины. Когда выполняется прерывание, содержимое MSR помещается в SRR1. Когда выполняется rfi, содержимое SRR1 помещается в MSR. В Книге E SRR1 используется для некритических прерываний.

Теперь, когда я понимаю, что делает код, мне нужно представить этот код с помощью GNU G CC в C:

__asm__ __volatile__ (
      "b 1f\n\t"
      "1:\n\t"
      "lis %2, %hi(2f)\n\t"
      "ori %2, %2, %lo(2f)\n\t"
      "mtsrr0 %2\n\t"
      "rfi\n\t"
      "2:\n\t"
      "mtsrr0 %0\n\t"   /* srr0 = p1 */
      "mtsrr1 %1\n\t"   /* srr1 = p2 */
      : "=r" (p1), "=r" (p2)
      : "r" (val), "r" (p1), "r" (p2));

Это дает следующую ошибку (дважды, для каждого экземпляра 2f, я полагаю: invalid 'asm': operand number missing after %-letter Комментирование строк с инструкциями lis и ori позволяет коду компилироваться без ошибок.

...