8.3. codgen7 (1134681), страница 2
Текст из файла (страница 2)
E
lSize<3>== AddrDisp<4>= AddrDisp<4>=
1,2,4,8 AddrDisp<0>- -Left<2>*ElSize<3>
AddrMode<3>!=D Left<2>*ElSize<3> AddrMode<4>=IndPost
Addreg<4>=Addreg<0> Addreg<4>= IndexReg<4>=GetFree (Addreg<0>==рабочий)
AddrMode<4>=IndPost ?Addreg<0>
Scale<4>=ElSize<3> :GetAddr
IndexReg<4>=GetFree()
MOVE Address<3>, Scale<4>=ElSize<3>
IndexReg<4>
LEA Address<0>,
Address<4>
MOVE Address<3>,
IndexReg<4>
ElSize<3> AddrDisp<4>= AddrDisp<4>:=
<>1,2,4,8 AddrDisp<0>- -Left<2>*ElSize
AddrMode<3><>D Left<2>*ElSize<3> AddrMode<4>=IndPre
Addreg<4>=Addreg<0> Addreg<4>= IndexReg<4>=GetFree (Addreg<0>==рабочий)
AddrMode<4>=IndPre ?Addreg<0>
Scale<4>=ElSize<3> :GetAddr
IndexReg<4>=GetFree()
MOVE Address<3>, Scale<4>=1
IndexReg<4>
MUL ElSize<3>, LEA Address<0>,
IndexReg<4> Address<4>
MOVE Address<3>,
IndexReg<4>
MUL ElSize<3>,
IndexReg<4>
Приведенная таблица реализуется следующим правилом:
RULE
VarTail ::= 'ARR' Number Typexpr VarTail
SEMANTICS
int Size;
bool Flag;
AddrType AddrTmp1,AddrTmp2;
Flag= ((Address<0>.AddrMode==IndPre)
|| (Address<0>.AddrMode==Direct))
&& (Address<0>.IndexReg==NO);
Size=Table[Val<2>];
if (Address<3>.AddrMode==D)
IndexReg<4>=Addreg<3>;
else IndexReg<4>=GetFree;
AddrMode<4>=IndPre;
if (Flag)
{Address<4>.AddrDisp=Address<0>.AddrDisp-Table[Val<2>]*Size;
Addreg<4>=Addreg<0>;
}
else {Address<4>.AddrDisp=-Table[Val<2>]*Size;
if (Address<0>.Addreg<=MaxReg)
Addreg<4>=Addreg<0>;
else Addreg<4>=GetAddr;
}
if (Size & 14) // 2,4,8
Address<4>.Scale=Size);
else Address<4>.Scale=1;
AddrTmp1.AddrMode=D;
AddrTmp1.Addreg=IndexReg<4>;
if (Flag) Emit2(LEA,Address<0>,Address<4>);
if (Address<3>.AddrMode!=D)
Emit2(MOVE,Address<3>,AddrTmp1);
AddrTmp2.AddrMode=IMM;
AddrTmp2.AddrDisp=ElSize<3>;
if (!(Size & 15)) // 1,2,4,8
Emit2(MUL,AddrTmp2,AddrTmp1).
8.5. Трансляция целых выражений
Трансляция выражений различных типов управляется синтаксически благодаря наличию указателя типа перед каждой операцией. Мы рассмотрим некоторые наиболее характерные проблемы генерации кода для выражений.
Система команд МС68020 обладает двумя особенностями, сказывающимися на генерации кода для арифметических выражений (то же можно сказать и о генерации кода для выражений типа "множества"):
1) один из операндов выражения (правый) должен при выполнении операции находиться на регистре, поэтому если оба операнда не на регистрах, то перед выполнением операции один из них надо загрузить на регистр;
2) система команд довольно "симметрична", т.е. нет специальных требований к регистрам при выполнении операций (таких, например, как пары регистров или требования четности и т.д.).
Поэтому выбор команд при генерации арифметических выражений определяется довольно простыми таблицами решений. Например, для целочисленного сложения такая таблица приведена на рис.8.12.
Правый операнд А2
R V
Левый R ADD A1,A2 ADD A2,A1
операнд
A1 V ADD A1,A2 MOVE A1,R
ADD A2,R
Рис. 8.12
Здесь имеется в виду, что R - операнд на регистре, V - операнд - переменная или константа. Такая таблица решений должна также учитывать коммутативность операций.
RULE
IntExpr ::= 'PLUS' IntExpr IntExpr
SEMANTICS
if (Address<2>.AddrMode!=D)
&& (Address<3>.AddrMode!=D)
{Address<0>.AddrMode=D;
Address<0>.Addreg=GetFree(RegSet<Block>);
Emit2(MOVE,Address<2>,Address<0>);
Emit2(ADD,Address<2>,Address<0>);
}
else if (Address<2>.AddrMode==D)
{Emit2(ADD,Address<3>,Address<2>);
Address<0>:=Address<2>);
}
else {Emit2(ADD,Address<2>,Address<3>);
Address<0>:=Address<3>);
}.
136