Я строю интерпретатор 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? Я прошу помощи Бит Хакеры...
Заранее спасибо
Update: Прежде всего: спасибо, ребята, вы были здоровы. Я тщательно проверю все ваши коды на скорости, и вы будете первыми, кто узнает, кто победитель.
@jalf: О вашем первом совете я фактически не вычислял CR0 в каждой инструкции. Я скорее сохранил переменную lastResult, и когда (и если) следующая инструкция запросила флаг, выполните сравнение. Три основных мотивации вернули меня к обновлению "everytime":
- В PPC вы не обязаны обновлять CR0, как на x86 (где ADD всегда меняет EFLAGS, даже если это не нужно), у вас есть два варианта ADD, одно обновление. Если компилятор хочет использовать обновление, это означает, что он будет использовать CR0 в какой-то момент, поэтому нет смысла задерживать...
- Там особенно болезненная инструкция называется mtcrf, которая позволяет вам произвольно изменить CR0. Вы даже можете установить его на 7, без арифметического значения... Это просто разрушает возможность сохранения переменной lastResult.