Действительно, вопрос понят не совсем правильно.
Цитата
когда мы пишем PORTD то компилятор точно знает что от него требуется и генерит то чего мы ждем от него.
например если написать
Код
(PORTD |= 0x30)
то это уже разложится на
Код
000096 B302 IN R16,PORTD
000098 6300 ORI R16,0x30
00009A BB02 OUT PORTD,R16
Когда мы пишем (PORTD |= 0x30), то компилятору в любом случае не остается ничего, кроме как представить это тремя командами (можно двумя, но это уже нюансы).
В данном случае везде используется вариант с установкой строго одного бита: (PORTD |= 0x10). И если PORTD - это стандартное определение порта, то будет sbi. Если вместо PORTD использовано стандартное определение DDRD, то тоже будет sbi. Но вот если использовано (применимое только к AVR) тайное знание того, что адрес DDRD = адрес PORTD-1, то как ни напиши - компилятор упорно не хочет использовать sbi, что приводит к замене одной команды тремя. Учитывая то, что это повторяется в коде несколько раз, мы заметно проигрываем в размере.
Вопрос состоял в том, как корректно получить экивалент стандартного определения порта DDRD, зная лишь базовый порт PORTD. Притом, так, чтобы компилятор понимал, что этот эквивалент - это точно такое же определение, как и его штатное, и работал с ним соответственно. Естественно, что всё это - константные выражения, адрес порта не меняется в run-time. От того и обидно, что мне пока не удалось этого сделать
Цитата
когда (&PORTD-1) то он знает лишь то что PORTD у нас __io (volatile) и более ничего, поэтому поступает с ним соответственно.
А, вот что имелось в виду... Понятно. Фокус тут в том, можно ли каким-либо путем убедить компилятор, что (&PORTD-1), хоть это и адрес volatile переменной, но сам он является const-антой. А дальше - что это - константный адрес __io переменной, которая сама по себе volatile, но такие ведь все порты. Возможно, какими-то приведениями типов и можно это сделать, но я пока не преуспел.
Цитата
собственно поэтому я и предложил решать это ASM вставкой, хотя я тоже не в восторге от такого подхода

Автор avr-usb - тем более. Он не склонен делать слишком много явно бросающихся в глаза модификаций текста для коммерческого компилятора, так как проект ориентирован (и сильно) на gcc-avr, и сильно под него оптимизирован без ассемблерных вставок. Заменить, скажем, __io(x) на пустую конструкцию для компиляции под gcc он согласится, а вот делать множество условных #if - нет, если в принципе проект собирается (а он собирается и работает). Но вопросы оптимизации формы представления - это уже вторично. Мне бы хоть под IAR понять, как выкрутиться из положения.
PS. После некоторого раздумья становится понятно, в чем может быть проблема (но не как ее решать). Ведь макро типа DDRD определяются через структуру, размещаемую по некоему фиксированному адресу в сегменте __io (образно говоря). В целом может быть так, что знание этого адреса во время трансляции штатных структур компилятору недоступно, а закладывается в информацию для линкера, который лишь на стадии линковки может прописать туда реальное значение, а также его же -1 - в те места, где на него ссылаются. Если так, то сделать более корректно и унифицированно не получится в принципе

Так что желающим оптимизировать и это придется заняться hand job (ручной работой по коверканью исходников, а не тем, что часто под этим подразумевают

)