Важная информация

User Tag List

Страница 1 из 10 12345 ... ПоследняяПоследняя
Показано с 1 по 10 из 100

Тема: Кодогенерация SDCC: пожелания об улучшении компилятора

  1. #1
    Veteran Аватар для Oleg N. Cher
    Регистрация
    24.08.2007
    Адрес
    Днепропетровская обл.
    Сообщений
    1,601
    Спасибо Благодарностей отдано 
    2,172
    Спасибо Благодарностей получено 
    133
    Поблагодарили
    99 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию Кодогенерация SDCC: пожелания об улучшении компилятора

    Начал набрасывать письмо Филиппу Клаусу Краузе (главному мэйнтейнеру кодогенератора Z80 для SDCC).

    Просьба высказаться желающим. Предложения по кодогенерации обязательно проверяйте на свежей версии SDCC, потому что в ней много чего изменилось по сравнению со старыми версиями. Идеи, высказанные здесь на форуме и на форуме ZXDev, я оформлю и вышлю Филиппу.

  2. #1
    С любовью к вам, Yandex.Direct
    Размещение рекламы на форуме способствует его дальнейшему развитию

  3. #2
    ZEK
    Гость

    По умолчанию

    В pephole логику добавить возможность работать по байтово с компонентами 32/16 битных циферок, можно хорошо подрезать код для библиотек от большого брата,
    а то
    long a = 0x12345678;
    a &= (char)0xFF;
    выливается в 4 операции and вместо одной, не считаю загрузку всех 4х компонент при участии индексного регистра из стека в память и запись обратно, по 5 (или что то около того) инструкций на 1 байт 32 битной циферки, мегатормоз и куча памяти

  4. #3
    Veteran
    Регистрация
    08.05.2007
    Адрес
    Dnepropetrovsk
    Сообщений
    1,055
    Спасибо Благодарностей отдано 
    219
    Спасибо Благодарностей получено 
    47
    Поблагодарили
    31 сообщений
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Скачал версию от 20 августа. К кодогенератору имеются следующие замечания:

    1) Инициализация данных. Объявив глобальную статическую переменную следующей инструкцией:

    static char s[] = "Hello world!";

    Я получил процедуру инициализации этой переменной вида:
    ld hl, _s
    LD (HL), 'H'
    ld hl, _s+1
    LD (HL),'e'
    Что чрезвычайно неэффективно как по скорости исполнения, так и по занимаемой памяти. Более оптимальное решение - это сохранить исходное значение константы в сегменте инициализированных (константных) данных, а потом копировать с помощью LDIR.

    ---------- Post added at 03:59 ---------- Previous post was at 03:48 ----------

    2) Деление на 2 переменной. Инструкция вида
    k/=2
    где k - стековая 8-битная переменная, привела к генерации кода:
    LD A,(IX+6)
    SRL A
    LD (IX+6),A
    Что лучше заменить на
    SRL (IX+6)

    3) Возведение в квадрат числа. Инструкция вида:
    t*=t
    где t - unsigned short, привела к генерации кода:
    PUSH HL
    LD C,(IX+4)
    LD B,(IX+5)
    PUSH BC
    LD C,(IX+4)
    LD B,(IX+5)
    PUSH BC
    CALL __mulint_rrx_s
    POP AF
    POP AF
    LD D,L
    LD E,H
    POP HL
    LD (IX+4),D
    LD (IX+5),E
    В этом коде, во-первых, нет необходимости загружать BC второй раз, потому что в него загружается одна и та же информация. Обе команды LD между PUSH BC можно выкинуть.
    Во-вторых, после возврата из подпрограммы умножения, результат сначала копируется в регистр DE, а потом сохраняется на фрейм. Вместо этого можно сначала сохранить результат прямо из HL, а потом выполнить POP HL. Экономится две команды LD.

    Вместе с тем отмечаю, что кодогенератор стал существенно лучше, чем был, и в некоторых моментах я был приятно удивлен результатами его работы. Почти как человек написал. Например, вот так получилась функция strlen:


    unsigned short mstrlen(const char* s)
    {
    unsigned short a = 0;
    while(*s++)
    a++;
    return a;
    }

    Сгенерированный код:

    ;test.c:21: unsigned short mstrlen(const char* s)
    ; ---------------------------------
    ; Function mstrlen
    ; ---------------------------------
    ._mstrlen_start
    ._mstrlen
    ;test.c:24: while(*s++)
    ld de,$0000
    pop bc
    pop hl
    push hl
    push bc

    .l_mstrlen00101
    ld a,(hl)
    inc hl
    or a, a
    jp Z,l_mstrlen00103
    ;test.c:25: a++;
    inc de
    jp l_mstrlen00101

    .l_mstrlen00103
    ;test.c:26: return a;
    ex de,hl

    .l_mstrlen00104
    ret
    ._mstrlen_end

    Что не оставляет желать ничего лучшего. Ну разве что можно было бы продублировать заголовок цикла, как это делается в некоторых современных компиляторах, но нельзя требовать всего сразу

  5. #4
    Veteran
    Регистрация
    06.05.2006
    Адрес
    Ливны, Орловская обл
    Сообщений
    1,169
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    На правах "мимопроходил"...
    Цитата Сообщение от Barmaley_m Посмотреть сообщение
    1) Инициализация данных...
    А почему, если у нас static данные в памяти уже лежат, нельзя просто забить на их инициализацию, зачем ещё копировать? Стандарт?
    Цитата Сообщение от Barmaley_m Посмотреть сообщение
    ;test.c:24: while(*s++)
    ld de,$0000
    pop bc
    pop hl
    push hl
    push bc
    Это загрузка параметров функции?
    Если у нас не PIC-код(а на спеке оно наверное так и будет), почему бы вместо push'ей не делать ld sp,#xx?

    ---------- Post added at 10:42 ---------- Previous post was at 09:37 ----------

    Цитата Сообщение от Oleg N. Cher
    ld hl, #2+0
    add hl, sp
    ...
    ret
    А вот в таких конструкциях надо проверять, не лучше ли делать INC/DEC.

  6. #5
    Guru Аватар для Дмитрий
    Регистрация
    01.01.2009
    Адрес
    Донецк, Украина
    Сообщений
    3,260
    Спасибо Благодарностей отдано 
    35
    Спасибо Благодарностей получено 
    9
    Поблагодарили
    8 сообщений
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от NovaStorm Посмотреть сообщение
    А вот в таких конструкциях надо проверять, не лучше ли делать INC/DEC.
    Вообще-то таким образом берется верхушка стека в HL, чтоб не делать что-то типа такого:

    Код:
          ...
          LD (bla+1),sp
    bla: LD HL,0
          ...

  7. #6
    Veteran
    Регистрация
    06.05.2006
    Адрес
    Ливны, Орловская обл
    Сообщений
    1,169
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от Дмитрий Посмотреть сообщение
    Вообще-то таким образом берется верхушка стека в HL, чтоб не делать что-то типа такого:
    Я думал(так как там дальше ret) тот код восстанавливает стек перед возвратом из функции.

  8. #7
    Vitamin C++ Аватар для Vitamin
    Регистрация
    14.01.2005
    Адрес
    Таганрог, Россия
    Сообщений
    4,254
    Спасибо Благодарностей отдано 
    9
    Спасибо Благодарностей получено 
    80
    Поблагодарили
    34 сообщений
    Mentioned
    7 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от NovaStorm Посмотреть сообщение
    А почему, если у нас static данные в памяти уже лежат, нельзя просто забить на их инициализацию, зачем ещё копировать?
    Потому что это не константная переменная с гарантированным для первого обращения значением. А значит лежит в секции, доступной на чтение-запись. А исходные данные лежат в секции "только на чтение". Хочешь сразу ссылаться на нужную секцию- подскажи компилятору (я вот только не помню, в С можно const писать или только в новом стандарте).

  9. #8
    Veteran
    Регистрация
    06.05.2006
    Адрес
    Ливны, Орловская обл
    Сообщений
    1,169
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Vitamin, про секции я вроде понимаю, но если указать const, изменять нам ничего не дадут?
    >А исходные данные лежат в секции "только на чтение".
    А почему R/W? Переменные ведь делятся на инициализированные и нет?

  10. #9
    Vitamin C++ Аватар для Vitamin
    Регистрация
    14.01.2005
    Адрес
    Таганрог, Россия
    Сообщений
    4,254
    Спасибо Благодарностей отдано 
    9
    Спасибо Благодарностей получено 
    80
    Поблагодарили
    34 сообщений
    Mentioned
    7 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от NovaStorm Посмотреть сообщение
    но если указать const, изменять нам ничего не дадут?
    Ну да.

    Цитата Сообщение от NovaStorm Посмотреть сообщение
    А почему R/W? Переменные ведь делятся на инициализированные и нет?
    "А почему светофор красный? Крокодил ведь зеленый!"

  11. #10
    Veteran
    Регистрация
    06.05.2006
    Адрес
    Ливны, Орловская обл
    Сообщений
    1,169
    Спасибо Благодарностей отдано 
    0
    Спасибо Благодарностей получено 
    0
    Поблагодарили
    0 сообщений
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Тьфу, _не_ R/W. Чем чтение/запись определяется? Или это уже специфично и компиляторо-линкеро зависимо?

Страница 1 из 10 12345 ... ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. SDCC - Small Device C Compiler
    от Valen в разделе Программирование
    Ответов: 52
    Последнее: 06.04.2012, 20:44
  2. Конструктор для компилятора с Си
    от Raydac в разделе Программирование
    Ответов: 0
    Последнее: 21.12.2009, 23:14
  3. Пожелания ваще
    от svofski в разделе Эмуляторы отечественных компьютеров
    Ответов: 7
    Последнее: 01.09.2009, 18:27
  4. SDCC вокруг да около
    от andrews в разделе Программирование
    Ответов: 8
    Последнее: 26.03.2008, 08:16
  5. Пожелания по сервисам форума
    от andrews в разделе Форум
    Ответов: 10
    Последнее: 14.08.2006, 13:47

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •