var iNum: integer; {номенр триады по ссылке}
Triad: TTriad; {текущая триада}
begin
Triad:= listTriad[i]; { Запоминаем текущую триаду }
{ Выборка наименования операнда в зависимости от типа }
case Triad[iOp].OpType of
{ Если константа – значение константы }
OP_CONST: Result:= IntToStr(Triad[iOp].ConstVal);
{ Если переменная – ее имя из таблицы идентификаторов }
OP_VAR:
begin
Result:= Triad[iOp].VarLink.VarName;
{ Если имя совпадает с именем функции,
заменяем его на Result функции }
if Result = NAME_FUNCT then Result:= NAME_RESULT;
end; { Иначе – это регистр }
else { для временного хранения результатов триады }
begin { Запоминаем номер триады }
iNum:= Triad[iOp].TriadNum;
{ Если это предыдущая триада, то операнд не нужен }
if iNum = i-1 then Result:=
else
begin {Берем номер регистра, связанного с триадой}
iNum:= listTriad[iNum].Info;
{ Если регистра нет, то операнд не нужен }
if iNum = 0 then Result:=
{ Иначе имя операнда – это имя регистра }
else Result:= GetRegName(iNum);
end;
end;
end{case};
end;
function MakeMove(const sReg,{имя регистра}
sPrev,{предыдущая команда}
sVal{предыдущая величина в eax}: string;
flagOpt: Boolean{флаг оптимизации}): string;
{ Функция, генерящая код занесения значения в регистр eax }
begin { Если операнд был только что выгружен из eax
или необходимое значение уже есть в аккумуляторе,
нет необходимости записывать его туда снова }
if (Pos(Format(#9'mov'#9 %s,eax',[sReg]), sPrev) = 1)
or (sVal = sReg) then
begin
Result:= ; Exit;
end;
if flagOpt then { Если оптимизация команд включена }
begin
if sReg = 0 then { Если требуемое значение = 0, }
begin{его можно получить из –1 и 1 с помощью INC и DEC}
if sVal = -1 then Result:= #9'inc'#9'eax'
else
if sVal = 1 then Result:= #9'dec'#9'eax'
else Result:= #9'xor'#9'eax,eax'
end {иначе – с помощью XOR}
else
if sReg = 1 then { Если требуемое значение = 1, }
begin{его можно получить из –1 и 0 с помощью NEG и INC}
if sVal = -1 then Result:= #9'neg'#9'eax'
else
if sVal = 0 then Result:= #9'inc'#9'eax'
else
Result:= #9'xor'#9'eax,eax'#13#10#9'inc'#9'eax';
end {иначе – двумя командами: XOR и INC }
else
if sReg = -1 then { Если требуемое значение = -1, }
begin{его можно получить из 1 и 0 с помощью NEG и DEC}
if sVal = 1 then Result:= #9'neg'#9'eax'
else
if sVal = 0 then Result:= #9'dec'#9'eax'
else
Result:= #9'xor'#9'eax,eax'#13#10#9'dec'#9'eax';
end {иначе – двумя командами: XOR и DEC }
{ Иначе заполняем eax командой MOV }
else Result:= Format(#9'mov'#9'eax,%s',[sReg]);
end { Если оптимизация команд выключена,
всегда заполняем eax командой MOV }
else Result:= Format(#9'mov'#9'eax,%s',[sReg]);
end;
function MakeOpcode(i: integer;{номер текущей триады}
listTriad: TTriadList;{список триад}
const sOp,sReg,{код операции и операнд}
sPrev,{предыдущая команда}
sVal{предыдущая величина в eax}: string;
flagOpt: Boolean{флаг оптимизации}): string;
{ Функция, генерящая код линейных операций над eax }
var Triad: TTriad;{текущая триада}
begin { Запоминаем текущую триаду }
Triad:= listTriad[i];
if flagOpt then { Если оптимизация команд включена }
begin
if sReg = 0 then { Если операнд = 0 }
begin
case Triad.TrdType of
TRD_AND: { Для команды AND результат всегда = 0 }
Result:= MakeMove(0 ,sPrev,sVal,flagOpt);
{ Для OR, "+" и «-» ничего не надо делать }
TRD_OR,TRD_ADD,TRD_SUB: Result:= #9#9;
{ Иначе генерируем код выполняемой операции }
else Result:= Format(#9 %s'#9'eax,%s',[sOp,sReg]);
end{case};
end
else
if sReg = 1 then { Если операнд = 1 }
begin
case Triad.TrdType of
TRD_OR: { Для команды OR результат всегда = 1 }
Result:= MakeMove(1 ,sPrev,sVal,flagOpt);
{ Для AND ничего не надо делать }
TRD_AND: Result:= #9#9;
{ Для "+" генерируем операцию INC }
TRD_ADD: Result:= #9'inc'#9'eax';
{ Для «-» генерируем операцию DEC }
TRD_SUB: Result:= #9'dec'#9'eax';
{ Иначе генерируем код выполняемой операции }
else Result:= Format(#9 %s'#9'eax,%s',[sOp,sReg]);
end{case};
end
else
if sReg = -1 then { Если операнд = -1 }
begin
case Triad.TrdType of
{ Для "+" генерируем операцию DEC }
TRD_ADD: Result:= #9'dec'#9'eax';
{ Для «-» генерируем операцию INC }
TRD_SUB: Result:= #9'inc'#9'eax';
{ Иначе генерируем код выполняемой операции }
else Result:= Format(#9 %s'#9'eax,%s',[sOp,sReg]);
end{case};
end { Иначе генерируем код выполняемой операции }
else Result:= Format(#9 %s'#9'eax,%s',[sOp,sReg]);
end { Если оптимизация команд выключена,
всегда генерируем код выполняемой операции }
else Result:= Format(#9 %s'#9'eax,%s',[sOp,sReg]);
{ Добавляем к результату информацию о триаде
в качестве комментария }
Result:= Result + Format(#9 { %s },
[Triad.MakeString(i)]);
Читать дальше
Конец ознакомительного отрывка
Купить книгу