Модификация кода сборки Compipler RT для компиляции для Arm Cortex M3/M4 (обработка битов CPSR/APSR)

Я пытаюсь заставить математические процедуры Compiler RT работать с набором инструментов GCC для процессоров ARM Cortex M3/M4F (armv7m и armv7em с fpu).

У меня все компилируется (с минимальными изменениями), кроме двух строк кода (msr CPSR_f, ip и msr CPSR_f, #APSR_C) в функциях ниже

#define APSR_Z (1 << 30)
#define APSR_C (1 << 29)

DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmple)
    // Per the RTABI, this function must preserve r0-r11.
    // Save lr in the same instruction for compactness
    push {r0-r3, lr}

    bl __aeabi_fcmplt
    cmp r0, #1
    IT(eq)
    moveq ip, #0
    beq 1f

    ldm sp, {r0-r3}
    bl __aeabi_fcmpeq
    cmp r0, #1
    IT(eq)
    moveq ip, #(APSR_C | APSR_Z)
    IT(ne)
    movne ip, #(APSR_C)

1:
    msr CPSR_f, ip
    pop {r0-r3}
    POP_PC()
END_COMPILERRT_FUNCTION(__aeabi_cfcmple)

И другая функция:

DEFINE_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)
    push {r0-r3, lr}
    bl __aeabi_cfcmpeq_check_nan
    cmp r0, #1
    pop {r0-r3, lr}

    // NaN has been ruled out, so __aeabi_cfcmple can't trap
    bne __aeabi_cfcmple

    msr CPSR_f, #APSR_C
    JMP(lr)
END_COMPILERRT_FUNCTION(__aeabi_cfcmpeq)

Нотация CPSR_f недоступна в наборе инструкций armv7m. Как преобразовать msr CPSR_f, ip и msr CPSR_f, #APSR_C в код armv7m (должен быть таким же для armv7em)?


person TylerG    schedule 24.04.2016    source источник


Ответы (1)


Вам нужно использовать инструкцию MOV APSR, Rm. Процессоры Cortex-M практически не имеют CPSR, а APSR действует как его замена в том, что касается кодов условий.

Первую функцию легко исправить, так как она использует регистр в качестве исходного операнда. Просто замените msr CPSR_f, ip на msr APSR_nzcvq, ip. Вторая функция потребует прохождения через регистр. Предполагая, что регистр IP может быть затерт, как и в первой функции, которую вы можете использовать:

mov ip, #APSR_C
msr APSR_nzcvq, ip
person Ross Ridge    schedule 24.04.2016
comment
Как мне обрабатывать часть CPSR_f? _f означает, что он влияет только на верхние 8 бит (я думаю). Поэтому мне нужно было бы прочитать APSR, очистить верхние 8 бит, а затем записать его обратно. Является ли 3 инструкции самым быстрым и единственным способом сделать это? - person TylerG; 24.04.2016
comment
Часть _f означает, что она влияет только на биты флагов условий, для чего и используется APSR. Остальные части КПСР находятся в других регистрах или не существуют. Вам не нужно ничего, кроме того, что я описал. - person Ross Ridge; 24.04.2016
comment
Я пробую это. Я думаю, что мне нужно msr APSR, ip, а не mov APSR, ip, но тогда я получаю запись в APSR без указания битовой маски как устаревшей ошибки. Итак, я попробовал msr APSR_nzcvq, ip, и он скомпилировался нормально. Это выглядит правильно? - person TylerG; 24.04.2016
comment
@TylerG Да, исправил мою ошибку. Не знал, что вам нужен _nzcvq, в документации, которую я просматривал, об этом не упоминалось. - person Ross Ridge; 24.04.2016