простоты ЧЕГО? «комп мечты» железячника или программиста? их мечты часто вступают в противоречие
  • avatar aa-dav
  • 0
да просто для простоты. нет тут никаких микропрограмм — вся логика прямолинейна и однообразна.
а зачем вообще в опкод пихать такой флаг? опкод считай просто индекс для декодера, который вытащит из таблицы полную формулу команды/микропрограммы в общем виде со всеми флагами, где что муксить
  • avatar aa-dav
  • 0
Бит TI это прямой флаг для декордера инструкции нужно подгатавливать для АЛУ аргумент Y или нет. Всего инструкций 32, половина из них с зажжённым битом TI — половина нет. Но действительно бит TI уходит в АЛУ вместе с INSTR выступая как полный 5-битовый код инструкцуии, т.к. двухоперандные и однооперандные инструкции с одинаковым полем INSTR могут делать совершенно разные вещи.
рукалицо.жпг

ну, а здесь-то почему не судьба применить отдельную ОПЕРАЦИЮ инкремента на число, закодированнное в опкоде??

вместо того, чтобы сокращать количество доступных операций еще в два раза))))))
ты уж определись — либо у тебя бит TI определяет что-то отдельно, а само ДЕЙСТВИЕ, производимое в АЛУ с операндами, кодируется битами INSTR и тогда у тебя возможно, повторяю, ЛИШЬ 16 УНИКАЛЬНЫХ ОПЕРАЦИЙ АЛУ; либо у тебя 32 разных действия кодируются 5 битами, но тогда нет фактически никакого отдельного TI, просто нет
  • avatar aa-dav
  • 0
P.S.
Появился большой искус еще 1 бит поля INSTR откусить под «режим адресации immediate», когда поле SRC есть immediate-данное от 0 до 7, а TI — его знак. Тогда не нужны будут отдельные inc/dec 2/3/4/5/6/7, но надо подумать.
  • avatar aa-dav
  • 0
Так их и есть 32, бит TI просто для простоты определяет какие из них однооперандные, а какие — двухоперандные. Они не обязаны быть одинаковыми, это просто удобство для декодера.
в том, что ты на ровном месте потерял до половины нумерации для инструкций
у тебя сейчас возможно лишь 16 различных instr, а могло быть 32-(x<16)
  • avatar aa-dav
  • 0
а я пояснил, что тратить целый бит опкода на то не нужно
во всех случаях «существенного отличия» экономнее использовать другой instr
Эм… Так и есть. Просто по одному биту кода инструкции можно тут же понять нужен Y на входе или нет.
А в чём проблема то?
а я пояснил, что тратить целый бит опкода на то не нужно
во всех случаях «существенного отличия» экономнее использовать другой instr
  • avatar aa-dav
  • 0
вроде как [DST] читать не нужно только для load
Я только что выше подробнее пояснил.
Заполнение Y реально может быть не просто ненужным, но и времязатратным процессом.
вроде как [DST] читать не нужно только для load, что определяется по опкоду (лучше нулевому) и без TI
и второй раз в операциях типа [DST=SRC],[SRC=DST] — ну так там уже прочитано в первый раз

Я сильно над этим не задумывался еще, но т.к. есть 16 однооперандных инструкций (и они никак не обязаны быть теми же что и 16 двухоперандных), то возможно там будет и dec/inc-1/2/3/4 и возможно что-то еще.
лично я между любым кол-вом дополнительных инкрементов и обменом всегда выберу обмен
уже только ради одного обмена со стековым указателем, даже если больше не понадобится никак 8)
  • avatar aa-dav
  • 0
P.S.
Вообще однооперандные инструкции это такие в которых X пропускаясь через АЛУ перед записью в Y никак не зависит от Y.
Т.е. (используется синтаксис операторов похожий на синтаксис Си-подобных языков):
R0 = R1; move
R0 =+1 R1; inc1
R0 =<< R2; сдвиг влево на 1 бит
R0 =+2 R3; inc2
R0 ~= R4; побитовая инверсия
и так далее. т.е. над SRC производится операция и записывается в DST

Двухоперандные инструкции берут и SRC и DST и пропустив их оба через АЛУ записывают результат в DST:

R0 += R1; сумма R0 и R1 записывается в R0
R0 <<= R2; R0 сдвигается влево на R2 бит (существенное отличие с однооперандным аналогом!)
R0 cmp R3; R0 и R3 сравниваются — неизменность R0 достигается за счёт того, что АЛУ именно его (Y) выдаёт на выходе
и так далее.
  • avatar aa-dav
  • 0
это можно делать одновременно, и TI не нужен
если не понадобится Y, так не понадобится
Одновременно считывать из памяти не получится. Заполнение Y реально может быть не просто ненужным, но и времязатратным процессом.
(кстати, у тебя какой порядок слов-байтов? little/big endian?)
А тут это исключительно как захочет программист. Ячейка памяти 16-битная, регистры — 16-битные, если нужно компоновать 32-битные, то это пользовательский код целиком.
то inc1+inc2 ничем не лучше add3
Я сильно над этим не задумывался еще, но т.к. есть 16 однооперандных инструкций (и они никак не обязаны быть теми же что и 16 двухоперандных), то возможно там будет и dec/inc-1/2/3/4 и возможно что-то еще.
Если TI=1, то общая схема инструкции следующая:
1. SRC загружается в X
2. DST загружается в Y
это можно делать одновременно, и TI не нужен
если не понадобится Y, так не понадобится

Так и есть — это пожалуй единственная «бесполезная» комбинация аргументов которая осталась и действительно сделать её каким то особым случаем выглядит привлекательно.
Но лично мне не нравится, что ломается общая схема работы Simpleton-а.
почему ломается? считай просто, что схема общая у тебя такая:
1) может быть, записать PC в стек
2) DST ?= SRC
и нет проблем :D

Ну зависит от задачи. Например, если первый элемент нам подходит — переходим к его хвосту, а если нет — пропускаем до следующего элемента.
это только если по первому слову ясно (кстати, у тебя какой порядок слов-байтов? little/big endian?)
но если нужно элемент проверить целиком и условно пропустить следующий, то inc1+inc2 ничем не лучше add3
  • avatar aa-dav
  • 0
также не совсем понимаю смысл необходимости флага TI — почему бы всегда не производить копирование в X,Y?
Если TI=0, то общая схема инструкции следующая:
1. SRC загружается в X
2. X пропускается через АЛУ с кодом инструкции и TI=0 (т.е. полный код инструкции это TI+INSTR — оба поля)
3. результат сохраняется в DST
Если TI=1, то общая схема инструкции следующая:
1. SRC загружается в X
2. DST загружается в Y
3. X и Y пропускаются через АЛУ с кодом инструкции и TI=1 (т.е. полный код инструкции это TI+INSTR — оба поля)
3. результат сохраняется в DST
Т.е. TI — это признак двухоперандной инструкции — в таковой нужно больше действий в первой фазе по загрузке второго входного аргумента в Y и поэтому лучше по одному биту сразу понимать надо или не надо этот шаг делать.
Но можно так же воспринимать это так, что TI+INSTR формируют 5-битный код инструкции половина из которых однооперандная, а половина — двухоперандная.

Подумай, так ли тебе нужно писать что-то в следующий опкод.
Так и есть — это пожалуй единственная «бесполезная» комбинация аргументов которая осталась и действительно сделать её каким то особым случаем выглядит привлекательно.
Но лично мне не нравится, что ломается общая схема работы Simpleton-а.
Однако есть еще одно соображение — генерация исключений. Сколько ни думаю, но получается что при генерации исключений реально схемотехника должна быть вот настолько замороченной — нужно уметь и PC и FLAGS сохранить в стек да еще и переход совершить. Надо еще подумать, возможно из-за того что такая схемотехника просто нужна для прерываний, то и команда такая не будет обременением по итогу. Посмотрим, когда будет интерес и время подумать еще над этим помозгую. Немного смотрел в ARM-ы и вроде как там генерация прерываний не сохраняет никак флаги, типа это должно быть первой инструкцией обработчика прерываний… В общем возможны варианты.

(а еще лучше адресацию [R+imm], но она не лезет в такую схему)
Да, нифига не лезет. Да и норм. На деле дотянуться до произвольной переменной в стеке не так уж и трудно:
R5 = offset
R5 += SP
и вот тут уже мы можем совершать с параметром действия типа R0 += [R5] — мы получили на него указатель двумя командами и тремя словами.

ИТЕРИРОВАНИЕ подразумевает использование каждого элемента
Ну зависит от задачи. Например, если первый элемент нам подходит — переходим к его хвосту, а если нет — пропускаем до следующего элемента.
и кстати, на z80 очень огорчает отсутствие операций ex sp,rr
из-за этого двухстековые схемы и шитый код намного реже применимы, чем могло быть
Главное откуда оно возникло — это минимизация и ускорение реализации CALL,
Кстати, лучшим вариантом именно минимизации с ускорением может быть отдать под однокомандный call в принципе небессмысленный, но на практике вряд ли нужный случай «op [PC],src» — то есть dst=PC всегда прямая адресация, а ID=1 в этом случае будет означать «перед выполнением сохранить PC в стек». Подумай, так ли тебе нужно писать что-то в следующий опкод.

помимо этого может быть применён для, допустим, быстрой адресации переменных близких к вершине стека
переменные нормально надо располагать, и не понадобятся лишние инкременты :D
(а еще лучше адресацию [R+imm], но она не лезет в такую схему)

может быть полезен при итерировании по массивам с таким размером ячейки и тому подобное.
ИТЕРИРОВАНИЕ подразумевает использование каждого элемента, то есть последовательный доступ ко всем его частям, то есть одинарный инкремент :P

также не совсем понимаю смысл необходимости флага TI — почему бы всегда не производить копирование в X,Y?
  • avatar aa-dav
  • 0
в какой массе? перечисли несколько хотя бы разумных случаев?
Главное откуда оно возникло — это минимизация и ускорение реализации CALL, как я писал, но помимо этого может быть применён для, допустим, быстрой адресации переменных близких к вершине стека (наряду с =+1) и может быть полезен при итерировании по массивам с таким размером ячейки и тому подобное.