n отрицательное, положительное или нулевое значение? return 1, 2 или 4

Я создаю интерпретатор PowerPC, и он работает довольно хорошо. В архитектуре Power регистр условий CR0 (EFLAGS на x86) обновляется практически по любой инструкции. Он установлен так. Значение CR0 равно 1, если последний результат был отрицательным, 2, если последний результат был положительным, 4 в противном случае.

Мой первый наивный способ интерпретировать это:

if (n < 0)
    cr0 = 1
else if (n > 0)
    cr0 = 2;
else
    cr0 = 4;

Однако я понимаю, что все эти ветки не будут оптимальными, поскольку выполняются миллионы раз в секунду. Я видел несколько взломов SO, но ни один из них не казался подходящим. Например, я нашел много примеров преобразования числа в -1, 0 или 1 в соответствии со знаком или 0. Но как сделать -1 = 1, 1 = 2, 0 = 4? Я прошу помощи у Bit Hackers ...

Заранее спасибо

Обновление: Прежде всего: спасибо, ребята, вы молодцы. Я тщательно проверю все ваши коды на скорость, и вы первым узнаете, кто победил.

@jalf: О вашем первом совете, я на самом деле не вычислял CR0 для каждой инструкции. Я скорее держал переменную lastResult, и когда (и если) следующая инструкция запросила флаг, сделайте сравнение. Три основных мотивации вернули меня к обновлению «каждый раз»:

  1. На PPC вам не нужно обновлять CR0, как на x86 (где ADD всегда меняет EFLAGS, даже если он не нужен), у вас есть два варианта ADD, одно обновление .Если компилятор решит использовать обновляемый, это означает, что он собирается использовать CR0 в какой-то момент, поэтому нет смысла откладывать ...
  2. Есть особенно болезненная инструкция под названием mtcrf, которая позволяет вам изменить CR0 произвольно. Вы даже можете установить его на 7, без арифметического значения ... Это просто уничтожает возможность сохранения переменной "lastResult".
35
задан Francesco Boffa 4 March 2012 в 22:30
поделиться