Следующие два фрагмента кода отличаются только значением, загруженным в регистр x23, но количество инструкций minstret
(сообщаемое имитацией Verilator микросхемы Rocket) существенно различается. Это ошибка или я что-то не так делаю?
Функция read_csr()
взята из библиотеки сервера Frontend RISC-V (https://github.com/riscv/riscv-fesvr/blob/master/fesvr/encoding.h), а остальная часть кода [syscalls.c, crt.S, test.ld] похожа на тесты RISC-V (https://github.com/riscv/riscv-tests/tree/master/benchmarks/common).
Я проверил, что скомпилированные двоичные файлы содержат точно такие же инструкции, за исключением разницы в операндах.
Деление 0x0fffffff на 0xff, повторение 1024 раза: 3260 инструкций.
size_t instrs = 0 - read_csr(minstret);
asm volatile (
"mv x20, zero;"
"li x21, 1024;"
"li x22, 0xfffffff;"
"li x23, 0xff;"
"loop:"
"div x24, x22, x23;"
"addi x20, x20, 1;"
"bleu x20, x21, loop;"
::: "x20", "x21", "x22", "x23", "x24", "cc"
);
instrs += read_csr(minstret);
Деление 0x0fffffff на 0xffff, повторение 1024 раза: 3083 инструкции.
size_t instrs = 0 - read_csr(minstret);
asm volatile (
"mv x20, zero;"
"li x21, 1024;"
"li x22, 0xfffffff;"
"li x23, 0xffff;"
"loop:"
"div x24, x22, x23;"
"addi x20, x20, 1;"
"bleu x20, x21, loop;"
::: "x20", "x21", "x22", "x23", "x24", "cc"
);
instrs += read_csr(minstret);
Здесь 3083 инструкции кажутся правильными (1024 * 3 = 3072). Поскольку minstret
подсчитывает удаленные инструкции, кажется странным, что в первом примере было выполнено еще ~ 200 инструкций. Эти результаты всегда одинаковы, независимо от того, сколько раз я запускаю эти две программы.
loop
, вы сможете найти приведенные выше фрагменты. - person radiosonde   schedule 14.06.2018csrr a5,minstret
. - person radiosonde   schedule 14.06.2018li
находится вне цикла, поэтому, насколько я понимаю, она не должна быть виновником 200 дополнительных инструкций. Ассемблерный код, созданный objdump [termbin.com/p713, termbin.com/mrj9], к сожалению, не расширяет псевдоинструкциюli
. - person radiosonde   schedule 14.06.2018