Компилятор IAR 7.40 создает неверную сборку

У меня есть встроенный ассемблерный код для arm cortex-R5.

#include <stdio.h>

#define mtcpsr(v)   __asm volatile(\
              "msr  cpsr,%0\n"\
              : : "r" (v)\
            )

int mfcpsr (void)
{
    int rval;
    asm("mrs %0, cpsr" : "=r"(rval));
    return rval;
}


void main(void)
{

    /*
     * Enable interrupts in the ARM
     */

    mtcpsr(mfcpsr() & ~ ((0x80U) & (0x40U | 0x80U)));
}

При компиляции компилятором IAR 7.40 в режиме Thumb путем установки --cpu_mode=thumb в качестве флага компилятора сборка создается как

                `.text6`:
                mfcpsr:
  0xfffc040c: 0xf3ef 0x8000  MRS     R0, APSR
  0xfffc0410: 0x4770         BX      LR
  0xfffc0412: 0x0000         MOVS    R0, R0
                main:
  0xfffc0414: 0xb580         PUSH    {R7, LR}
  0xfffc0416: 0xf7ff 0xfff9  BL      mfcpsr                 ; 0xfffc040c
  0xfffc041a: 0xf020 0x0080  BIC.W   R0, R0, #128           ; 0x80
  0xfffc041e: 0xf380 0x8000  MSR     ??-0-0, R0
  0xfffc0422: 0xbd01         POP     {R0, PC}

MSR ??-0-0, R0 — недопустимая сборка. Я ожидаю это как MSR CPSR_fc, R0 (который я получил без опции большого пальца). Ребята, помогите найти проблему.


person kvnsk    schedule 22.02.2017    source источник
comment
Ваш asm говорит mrs, а не msr?   -  person David Wohlferd    schedule 22.02.2017
comment
Привет, Дэвид, исправил мой вопрос сейчас. Извините, что пропустил это.   -  person kvnsk    schedule 23.02.2017


Ответы (1)


Синтаксис инструкции MSR в вашем коде неверен. Инструкция MSR требует, чтобы имя регистра состояния, в вашем случае CPSR, сопровождалось суффиксом полей, которые должны быть обновлены. Поэтому, если вы измените макрос mtcpsr на следующий, вы получите ожидаемый результат.

#define mtcpsr(v)   __asm volatile(\
          "msr  CPSR_cxsf,%0\n"\
          : : "r" (v)\
        )

Я могу только догадываться, почему компилятор ведет себя по-разному в режиме руки и большого пальца или почему он не выдает предупреждение, но, вероятно, это ошибка.

В качестве примечания: если вы хотите разрешить только прерывания, вы можете использовать инструкцию CPSIE if или встроенную функцию __enable_interrupts().

person Johan    schedule 22.02.2017
comment
Привет, Йохан, я пропустил вставку кода. Извиняюсь. Сейчас исправил запрос. - person kvnsk; 23.02.2017