В настоящее время я разрабатываю эмулятор игрового себе и проверяю правильность своего эмулятора. Я использую GBDK для компиляции c-программ для моего эмулятора.Ошибка с умножением силы двух в компиляторе GBDK
Я заметил, что компилятор (как и ожидалось) оптимизирует умножения с константами, которые являются силой двух, делая вращения. Однако кажется, что он не генерирует правильное количество вращений для данной мощности.
Например, следующая очень простая программа:
#include <gb/gb.h>
unsigned char one() { return 1; }
void main()
{
unsigned char r;
// Force compiler to generate muliplication by deferring the '1'
r = one() * 32;
// Store result somewhere
*((unsigned char*)(0xFFFE)) = r;
}
Создает следующие сборки:
___main_start:
_main:
push bc
; reproduce.c 14
; genCall
call _one
ld c,e
; genLeftShift
ld a,c
rr a
rr a
rr a
and a,#0xE0
ld c,a
; reproduce.c 16
; genAssign
ld de,#0xFFFE
; genAssign (pointer)
ld a,c
ld (de),a
; genLabel
00101$:
; genEndFunction
pop bc
ret
___main_end:
.area _CODE
Что мне кажется неправильным, как команда RR на самом деле вращается через флаг переноса, эффективно что делает его 9-битным вращением. Это означает, что должен быть дополнительный поворот для получения правильного результата вместо текущего (0x40) неправильного результата.
Визуализация:
Start: A = 00000001 Carry = 0
RR A: A = 00000000 Carry = 1
RR A: A = 10000000 Carry = 0
RR A: A = 01000000 Carry = 0 <- WRONG!
Может кто-нибудь проверить, что это действительно ошибка в SDCC компилятор, который поставляется с GBDK? Я также заинтересован в использовании команды и инструкции после поворота.
Использование последней версии (3-2.93) версии GBDK для окон из исходной формы.
Версия SDCC, которая поставляется с GBDK, как представляется, 2.2.1, что-то вроде 15 лет , Последний стабильный выпуск SDCC - 3.4.0, который с апреля 2014 года. Получаете ли вы тот же сгенерированный код, если обновляете версию SDCC? – Michael
Я считаю, что SDCC, который поставляется с GBDK, является вилкой, которая модифицирована для создания gb-совместимого кода z80 (по крайней мере исходный код sdcc включен в источник gbdk). Но да, GBDK древний, но я бы подумал, что что-то общее, как это будет работать. – monoceres
Возможно, у проекта SDCC не было поддержки GB-Z80 в то время. Но я считаю, что это происходит сейчас. Я согласен, что это похоже на общий сценарий. OTOH, SDCC, очевидно, не имеет столько ресурсов разработчика, как, например, GCC или LLVM. В прошлом я столкнулся с странными ошибками в компиляторе SD80 от SDCC, например, чтобы заменить «memcpy» на петли, чтобы копия работала правильно. – Michael