Когда загружать операнды в эмуляторе TriCore?

Это моя первая публикация на Stack Overflow, поэтому я надеюсь, что делаю это правильно.;-)

Я пытаюсь разработать эмулятор TriCore, но не могу выбрать стратегию, когда загружать операнды для инструкции. TriCore может быть довольно неясным видом микроконтроллера, поэтому позвольте мне немного объяснить архитектуру.

Существует два типа инструкций: 16-битные и 32-битные. Является ли это 16-битным или 32-битным, определяется битом 0 в последнем байте; поскольку порядок байтов имеет младший порядок следования, он всегда является первым байтом в памяти. Нет проблем там.

Эти два типа команд имеют несколько форматов кодов операций: 14 для 16-битных и 25 для 32-битных команд. Коды операций разделены на два отдельных поля кода операции, хотя большинство из 16-битных имеют только одно поле кода операции. Первое поле кода операции находится в младших 8 битах; он непосредственно описывает инструкцию для 16-битных инструкций и для многих из 32-битных инструкций он описывает кодирование операнда, тогда как второе поле описывает фактическую инструкцию (но, конечно, есть исключения).

Мой план состоял бы в том, чтобы всегда извлекать все поля кода операции (что немного раздражает, так как позиция второго поля не одинакова для всех форматов команд) и объединять их в 16-битное значение, которое будет использоваться в таблице указателей на функции,

В зависимости от этого значения я хотел бы извлечь операнды. Например, когда в 32-битной инструкции первый код операции 0x8B, операндами являются два регистра данных и одна 9-битная константа. НО, есть исключения, которые действительно утомительны:

ADD.A а также ADDSC.A обе инструкции имеют код операции 1 == 0x01, Но ADD.A использует три адресных регистра, тогда как ADDSC.A использует два адресных регистра, один регистр данных и индекс, закодированный в инструкции.

В конце мой вопрос: возможно ли вообще загрузить операнды в архитектуре, подобной этой, перед выполнением инструкции? Или лучше сначала вызвать функцию инструкции и извлечь там операнды?

Для всех, кто интересуется, руководство по набору инструкций находится здесь: http://www.infineon.com/dgdl/tc_v131_instructionset_v138.pdf?folderId=db3a304412b407950112b409b6cd0351&fileId=db3a304412b407950112b409b6dd0352

Спасибо за любую подсказку!

Кстати: язык выбора будет C или C++.


(По просьбе я вставил свои мысли в свой оригинальный вопрос.)

Ну, я много думал о различных вариантах, которые у меня есть, и думаю, что я согласен со следующим.

Я разделю весь процесс на две части:

  1. Анализ программы и извлечение операнда
  2. выполнение

На первом этапе каждая инструкция загружается и выравнивается до 32 бит. Затем загруженная инструкция сравнивается с набором битовых масок, чтобы определить правильный код операции, который говорит мне не только о том, что должно быть выполнено в конце, но и о том, как загружаются операнды. В специфичных для режима адреса функции операнды загружаются в указатели; инструкции немедленно сохраняются по мере необходимости.

Это сводится к структуре, подобной этой:

struct instruction_t {
    int32_t **operands;
    int32_t *immediates;
};

Это будет в основном выделено для каждой инструкции (самый большой недостаток: потребление памяти. Я рассчитал около 40 байтов для такой структуры как наихудший случай (с 64-битными указателями), что означает, что программа, которая обычно составляет 4 мегабайта и состоит только из 16-битных инструкций, будет В итоге потребуется около 80 мегабайт памяти. С другой стороны, я думаю, что скорость выполнения может быть достаточно высокой).

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

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

Буду очень признателен за некоторые комментарии по поводу моего подхода. Может быть, вы знаете лучший способ сделать это?

Спасибо!

1 ответ

(Перенес мой подход в исходный вопрос.)

Другие вопросы по тегам