PowerPC: как заставить div / 0 возвращать ноль в результате - PullRequest
1 голос
/ 24 июня 2011

Мы пытаемся перенести устаревшее приложение со старой монолитной ОСРВ на ОС ОС на базе Unix на PowerPC 8360. В старой системе наша большая кодовая база стала зависимой от 1/0, возвращающего ноль, и 0/0, возвращающего ноль , Теперь в новой операционной системе 1/0 возвращает inf, а 0/0 возвращает NaN, что нарушает наше приложение. Мы попытались поиграть с регистром FPSCR безрезультатно.

Во-вторых, если есть способ изменить его, могут ли изменения повлиять на процесс нашего приложения, а не на всю систему? Мы не хотим изменять поведение div / 0 других приложений в системе.

Предвидя неизбежный вопрос «почему ты так поступаешь», мы должны сохранить прежнее поведение, поэтому изменение приложения на фактическое деление на ноль исключено. Это больное место у нас, поэтому, пожалуйста, воздержитесь от вопросов. Заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 24 июня 2011

Примечание: прошло много времени с тех пор, как я работал над этим. Надеюсь, мой ответ на стадионе.

Вам нужно перехватить исключение div-0, которое возникает, когда это происходит, - я считаю, что MSR.FE0 и MSR.FE1, а также FPSCR.VE и FPSCR.ZE нужно будет манипулировать, чтобы обеспечить обрабатывать это так, как вы хотите.

Так что, как только вы настроите и заработаете, вам нужно:

  • взять на себя управление обработкой исключений для этих сценариев (0/0 и 1/0). В большинстве небольших ядер реального времени, которые я использую, со всем доступным исходным кодом, я бы знал, что делать. Не уверен, какой у вас ОСРВ или какой у вас контроль. Скорее всего, если это «тяжеловесная» ОС, она не позволит вам возиться с логикой обработчика исключений. Я думаю, что 0/0 вызовет исключение "недопустимая операция" (FPSCR.VE), тогда как 1/0 вызовет исключение IEEE с плавающей запятой с нулевым делением (FPSCR.ZE).

    • если вы получаете исключение Invalid Operation, вам нужно определить, была ли причина 0/0 или что-то еще. С 0/0, FPSCR.VXZDZ будет установлено (я думаю). Есть и другие способы вызвать это исключение, поэтому здесь FPSCR ваш друг.

    • если вы получаете исключение IEEE FP div-0, вам необходимо определить, была ли причина 1/0 или что-то еще (например, 2/0). Я думаю, что для этого вам нужно изучить регистры прерванного контекста, чтобы увидеть, был ли числитель 1 во время операции деления, которая вызвала исключение. FPU не волнует, если вы пытались 1/0 или 2/0, но, очевидно, ваше приложение делает.

  • Далее вам нужно изменить возвращаемый контекст, чтобы получить желаемый результат. Это может быть что-то вроде изменения регистров FP, используемых в операции, так что при возврате из исключения и повторном испытании деления FP он возвращает ноль. Например, сделать числитель 0 и делитель 1.

Затем, когда вы вернетесь из исключения, вы получите желаемый результат. Извините, я не справился с конкретными регистрами и значениями, надеюсь, этого достаточно, чтобы выполнить работу.

Вы также спрашивали о выборочном включении этого поведения только для вашего процесса приложения. Раньше мне приходилось делать подобные вещи, но больше в плоско-адресном пространстве, ядрах типа «один процесс, несколько потоков» (где каждая задача на самом деле является потоком, все выполняются в одном и том же плоском адресном пространстве). Я сделал это несколькими разными способами, вот несколько идей, которые могут работать для вас:

  • В обработчике исключений проверьте идентификатор процесса / идентификатор задачи и, если это процесс вашего приложения, обработайте его особым образом, в противном случае обработайте его стандартным "системным" способом.

  • В качестве альтернативы, при переключении контекста в вашем приложении установите «специальную» обработку для этого исключения. При переключении контекста из процесса приложения замените его на стандартную обработку. Обратите внимание, что само приложение не сможет сделать это, вам нужно будет подключиться к ядру, чтобы сделать это (возможно, вы можете использовать ловушку переключения контекста / callout, в противном случае вы, вероятно, будете изменять исходный код ядра). ).

Я унаследовал подобный код и чувствую вашу боль. Вы хотите потрясти кулаком людей, которые установили такое поведение с костью, но сейчас покачивание кулаком не помогает вам отправлять продукт. Вам нужно решение. Удачи.

0 голосов
/ 24 июня 2011

Если вы переходите на POSIX-совместимую систему (например, QNX или Linux), вы можете попробовать добавить код в ваше приложение, чтобы перехватить SIGFPE и обработать там условие.

Не знаю, какой язык вы используете, и (что более важно), не беспокоясь о перехвате сигналов в течение длительного времени, я не уверен, как именно вы добавите код, но, возможно, ответы на этот вопрос ( Как перехватить исключения системного уровня в Linux C ++? ) поможет.

...