Поскольку мы создаём компилятор только для архитектуры Itanium, у нас должны быть жёстко прописаны следующие моменты:
1) Register
2) Instruction
3) Template (на более раннем семинаре мы рассматривали такую запись {.mii - собственно, это и есть template)
4) Latency - задержки между операциями
5) Resource - какие устройства используются
1. Register
Для каждого регистра у нас должен быть создан единственный объект, содержащий свойства этого регистра:
- тип регистра
reg_type: float, int, app, … (типы регистров мы рассматривали раннее)
- доступа к регистру
access_mode: READ, WRITE, READ_WRITE,…
- отношение к стеку
stack_mode: STATIC, STACK
- значения для read-only регистров
value: "f0=0.0",…
2. Instruction
- мнемоническая запись, например "ld8"
- список всех параметров
- Сколько параметров
- Какого типа параметры
- список того, что эта инструкция пишет
(Замечание: можно делать 2 списка: для параметров читаемых и записываемых, но тогда возможны ситуации, когда один и тот же параметр будет являться и читаемым и записываемым, и соответственно должен присутствовать в обоих списках. Либо можно создать один список и указывать для каждого параметра способ доступа)
- ресурсы(какое устройство и сколько тактов)
Предлагается ввести списки устройств.
Ещё замечания:
1) Тому, кто будет это кодить нужно будет проботать два мануала по Itanium'у и по второму Itanium'у
2) Со списками вызываемых прерываний решено не связываться
Инструкция может принадлежать к 2 классам: Consumer и Producer
Для тех, куда она пишет - producer,
для тех, от кого читает - consumer,
Т.е. таблицу, наример, надо читать так: надо вычислить задержку между двумя операциями (оп1 и оп2), для этого рассматриваем оп1 как producer, оп2 как consumer и читаем значение из таблицы table[op1->producer_class][op2->consumer_class]
// Borique
- Соответственно должна быть таблица задержек.
producer\consumer | ALU | Mult | load |
ALU | 1 | 2 | 1 |
Mult | 1 | 1 | 1 |
load | M | M | M |
Таблица не обязана быть квадратно й и симметричной.
Кроме того, мы не можем точно знать задержку для load, когда она обращается к памяти (в таблице указано M)
3. Template
- stb.t: 0,1,2,3
- slot1 - типы операций
- slot2
- slot3
С темплэйтами не всё так просто. Например, есть template MLX, где LX - одна операция. Соответственно, в этом случае слот 2 определяет слот 3.
Реализация на плюсах
У нас должен быть enum{R0,R1,…} на все регистры
То же самое с Opcode'ом(add, …)
Ввести единый массив для регистров(глобальный, либо передавать через параметры каждый раз)
Registers[R1] = gcnew Reg(I, STATIC, READ)
Нужно будет забить в код очень много всего, поэтому потом надо будет этот процесс распараллелить.
Если инструкции, возможно, понадобятся не все, то регистры нужно прописать все, какие есть.
А также, для producers/consumers
создать enum Prod_Class{ALU, Mult, Float, …}
и забить таблицу.
//snark