68040 принимает неправильную ветвь If Else

Есть какие-нибудь хорошие программисты на 68k ассемблере ?? Я использую коммерческий компилятор Green Hills для Motorola 68040 и вижу очень странное поведение кода. Иногда код выполняет сравнение if / else и выбирает неправильную ветвь. Например:

float a = 1, b = 2;

if (a < b)
    do c;
else 
    do d;

Иногда код будет d !? Я обнаружил, что всякий раз, когда возникает эта ошибка, всегда есть одна конкретная ISR, которая прерывает сравнение. Я взглянул на сгенерированную сборку для ISR и увидел несколько вещей, которые не имеют для меня смысла. Во-первых, похоже, что регистры состояния с плавающей запятой, FPSR, FPCR и FPIAR, не сохраняются в ISR. Это могло бы объяснить, почему if / elses выбирают неправильную ветвь. Регистр FPSR используется для определения результата сравнения, и если этот регистр перезаписывается в ISR, ветвь может пойти по неправильному пути. Ниже приводится сборка входа и выхода, созданная компилятором:

isr_function:
    FSAVE   -(%SP)
    LINK    %A6,#-192
    MOVEM.L %D0/%D1/%D2/%A0/%A1,-(%SP)
    FMOVEM  %FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7,-(%SP)

    ; isr code ...

    FMOVEM  -308(%A6),%FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7
    MOVEM.L -212(%A6),%D0/%D1/%D2/%A0/%A1
    UNLK    %A6
    FRESTORE    (%SP)+
    RTE

Я просмотрел Справочное руководство программиста и не нашел ничего, что предполагало бы, что FSAVE или FMOVEM сохраняет регистры состояния FP. На самом деле, я видел один комментарий, который предполагает, что это не так: «FSAVE не сохраняет регистры модели программиста модуля с плавающей запятой; он сохраняет только невидимую для пользователя часть машины."Итак, я добавил некоторую собственную сборку, чтобы сохранить регистры в начале ISR и восстановить их в конце, и это значительно улучшило производительность, но я все еще вижу некоторые проблемы. Ниже приведены внесенные мной дополнения. ; переменные резервного копирования набираются как unsigned long в коде C:

isr_function:
    FSAVE   -(%SP)
    LINK    %A6,#-192
    MOVEM.L %D0/%D1/%D2/%A0/%A1,-(%SP)
    FMOVEM  %FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7,-(%SP)

    FMOVE %FPIAR,fpiar_backup
    FMOVE %FPSR,fpsr_backup
    FMOVE %FPCR,fpcr_backup

    ; isr code ...

    FMOVE fpiar_backup,%FPIAR
    FMOVE fpsr_backup,%FPSR
    FMOVE fpcr_backup,%FPCR

    FMOVEM  -308(%A6),%FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7
    MOVEM.L -212(%A6),%D0/%D1/%D2/%A0/%A1
    UNLK    %A6
    FRESTORE    (%SP)+
    RTE

Мне было трудно поверить, что компилятор действительно имел ошибку, не сохраняя регистры. Поэтому я начал смотреть на значения FPx и Dx, чтобы убедиться, что они восстанавливаются до правильного значения, и похоже, что это не так. Однако я не на 100% уверен, что не испортил код сборки своими модификациями. Ниже приведен код, который я добавил для сохранения регистров; переменные отладки набирается как unsigned longs:

isr_function:
    FMOVE   %FP0,debug3
    FMOVE   %FP1,debug5
    FMOVE   %FP2,debug7
    FMOVE   %FP3,debug9
    FMOVE   %FP4,debug11
    FMOVE   %FP5,debug13
    FMOVE   %FP6,debug15
    FMOVE   %FP7,debug17
    FMOVE   %FPCR,debug19
    FMOVE   %FPIAR,debug23
    FMOVE   %FPSR,debug25   

    FSAVE   -(%SP)
    LINK    %A6,#-192
    MOVEM.L %D0/%D1/%D2/%A0/%A1,-(%SP)
    FMOVEM  %FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7,-(%SP)

    ; isr code ...

    FMOVEM  -308(%A6),%FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7
    MOVEM.L -212(%A6),%D0/%D1/%D2/%A0/%A1
    UNLK    %A6

    FMOVE   %FP0,debug4
    FMOVE   %FP1,debug6
    FMOVE   %FP2,debug8
    FMOVE   %FP3,debug10
    FMOVE   %FP4,debug12
    FMOVE   %FP5,debug14
    FMOVE   %FP6,debug16
    FMOVE   %FP7,debug18
    FMOVE   %FPCR,debug20
    FMOVE   %FPIAR,debug24
    FMOVE   %FPSR,debug26

    FRESTORE    (%SP)+
    RTE

Короче говоря, мои вопросы:

1) есть ли проблема со сгенерированной сборкой в ​​том, что она не сохраняет регистры FPSR, FPCR и FPIAR, и

2) я правильно сохранять значения регистров, когда я вхожу в ISR и выхожу из него?

Было бы здорово, если бы у меня был другой компилятор сравнивать с. К сожалению, я не могу подключить к коду отладчик. У меня большой опыт работы с C / C ++ / C # / Java / Python / PHP / и т. Д., Но я далек от специалиста по сборке.

Любые идеи приветствуются!

8
задан Ranhiru Jude Cooray 14 November 2011 в 05:51
поделиться