2010-07-13 5 views
3

Я пишу макрос сборки для C-программы, и, будучи совершенно новым с этим, я застрял на чем-то. Я пытаюсь написать макрос для перемещения данных из регистра общего назначения в регистр специального назначения.PowerPC, перемещающийся в переменную SPR

Моя проблема заключается в том, что синтаксис, который я нашел для перемещения данных из GPR в SPR, принимает значение постоянной SPR, в то время как я хочу использовать переменную, сохраненную в другом регистре.

# SPR is constant, rA is the value to be written 
mtspr SPR, rA 

Я после того, как что-то, что выглядит следующим образом:

# rA contains the number of the SPR, and rB the value to be moved. 
AWESOMEmtspr rA, rB 

Есть причина, есть в распоряжении нет таких макросов, и как бы я сделать это сам?

Большое спасибо заранее.

---- Edit: ---- Как это выглядит теперь у меня есть гигантский корпус выключателя в моей C-кода, который перескакивает к правильному mtspr сечению. У меня есть двадцать отдельных разделов для чтения и записи, которые содержат SPR: s, каждый из которых выглядит одинаково, но отличается постоянным значением.

ответ

4

Причина, по которой вы не можете этого сделать, заключается в том, что архитектура команды не поддерживает регистро-косвенный режим адресации для параметра register. Честно говоря, я никогда не видел машинной архитектуры, которая делает, поскольку количество регистров обычно довольно мало, поэтому регистр кодируется как часть самой инструкции. Если вам действительно не нравится решение, которое у вас есть, вы можете попытаться сами синтезировать инструкцию (возьмите базовый код операции, посмотрите, куда идет спецификатор регистра, и OR в соответствующем значении), а затем выполните его. В зависимости от вашей ОС и компилятора это может быть невозможно (самомодифицирующийся код часто запрещен).

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

MTPSR PSRx, val 
RET 
MTPSR PSRx+1, val 
RET 

Я не знаю, что считается «чище» для вас, просто подумал, что я его выброшу. Обратите внимание, что вам может потребоваться заполнить NOP, чтобы все выровнялось, у меня нет руководства PowerPC, поэтому я не знаю, что такое размеры инструкции или требования к выравниванию.

+0

Я полагаю, что вам будет не так хорошо, как с кодом. Я хотел бы сохранить как можно больше кода в C, но, полагаю, я соглашусь с тем, что у меня есть. Спасибо, в любом случае. – Nubsis

+0

Нет ничего плохого в динамически сгенерированном коде, но я думаю, что вы должны пометить исполняемые страницы и сбросить кеш команд для соответствующих адресов (icbf?). Накладные расходы на кеш-память, вероятно, не стоит того. –

0

Это кажется странным делом, но если вы уверены, что вам нужно это сделать по какой-то причине, вам нужно будет реализовать таблицу перехода или последовательность условных обозначений, посредством которых вы проверите rA и перейдете к соответствующему жестко закодированная инструкция mtspr. Вам также нужно подумать о том, как вы обрабатываете недействительные номера SPR.

+0

В настоящее время я делаю именно это. У меня есть огромный коммутационный регистр, основанный на перечислении в моем C-коде, который перескакивает на правильные инструкции. Как теперь выглядит, у меня есть тонна команд mtspr, которые отличаются только константами. Я был бы намного счастливее программистом, если бы мог избавиться от всего этого кода. – Nubsis

1

я нашел довольно элегантное решение этой проблемы с использованием stringizer макрокоманду:

#define stringify (ы) ToString (ы)

#define ToString (ы) #s

# определим mfspr (Rn) ({беззнаковое INT RVAL; \ ASM неустойчивыми ("mfspr% 0," stringify (гп) \ : "= г" (RVAL)); RVAL;})

#define mtspr (rn, v) asm volatil e ("mtspr" stringify (rn) ",% 0":: "r" (v))

Это код U-Boot для PowerPC.

+0

Помните, что это работает только в том случае, если 'rn' является константой времени компиляции. Вы не можете использовать, например, другой GPR для этого. –