gen64bit.pas

Переключить прокрутку окна
Загрузить этот исходный код

{
    Этот исходный текст является частью Продвинутого векторного транслятора.

    Copyright © 2017 Малик Разработчик

    Это свободная программа: вы можете перераспространять её и/или
    изменять её на условиях Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она может быть полезна,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <http://www.gnu.org/licenses/>.
}

unit Gen64bit;

{$MODE DELPHI,EXTENDEDSYNTAX ON}

interface

uses
    Lang, Utils, IOStream, TranIntf, TranType, TranTree, BuildLex, BuildFTr,
    GenX86, Gen16bit, Gen32bit;

{$ASMMODE INTEL,CALLING REGISTER,INLINE ON,GOTO ON}
{$H+,I-,J-,M-,Q-,R-,T-}

type
    RegisterStack64bit = class;
    TranslatorBuilderOf64bitCode = class;

    RegisterStack64bit = class(RegisterStack32bit)
    public
        constructor create(const usingGPRS, usingXMMS: short_Array1d);
        procedure storeRegs(count: int; g: TextGenerator); override;
        procedure restoreRegs(g: TextGenerator); override;
        function getNextUsedGPR(regGPR: int): int; override;
        function changeToGPR64bit(index: int): int; override;
        function allocateGPR64bit(g: TextGenerator): int; override;
        function allocateGPRForArray(g: TextGenerator): int; override;
        function allocateGPRForIndex(g: TextGenerator): int; override;
        function allocateGPRForPointer(g: TextGenerator): int; override;
    protected
        procedure checkRegister(reg: int); override;
    end;

    TranslatorBuilderOf64bitCode = class(TranslatorBuilderOf32bitCode)
    public
        const LABEL_EXCEPTION_HANDLER = '.L.EH';
        const LABEL_POOL_LONG_LENGTH = 'L.P.LONG.LEN';
        const LABEL_POOL_LONG_CONTENT = 'L.P.LONG.CON';
        const LABEL_POOL_ULTRA_LENGTH = 'L.P.XULTRA.LEN';
        const LABEL_POOL_ULTRA_CONTENT = 'L.P.XULTRA.CON';
        const LABEL_POOL_XVECTOR_LENGTH = 'L.P.XVECT.LEN';
        const LABEL_POOL_XVECTOR_CONTENT = 'L.P.XVECT.CON';
        const FUNCTION_EXCEPTION_INHERITED_FROM = TranslatorTreeBuilder.NAMESPACE_SYSTEM +
                '.exceptionInheritedFrom';
        const FUNCTION_LONG_QMULHS = TranslatorTreeBuilder.NAMESPACE_SYSTEM +
                '.longQMULHS';
        const FUNCTION_ULTRA_EXTRACT = TranslatorTreeBuilder.NAMESPACE_SYSTEM +
                '.ultraExtract';
        const FUNCTION_ULTRA_QMULL = TranslatorTreeBuilder.NAMESPACE_SYSTEM +
                '.ultraQMULL';
        const FUNCTION_ULTRA_QMULH = TranslatorTreeBuilder.NAMESPACE_SYSTEM +
                '.ultraQMULH';
        const FUNCTION_ULTRA_OMULHS = TranslatorTreeBuilder.NAMESPACE_SYSTEM +
                '.ultraOMULHS';
        const FUNCTION_FLOAT_TO_LONG = TranslatorTreeBuilder.NAMESPACE_SYSTEM +
                '.floatToLong';
        const FUNCTION_DOUBLE_TO_LONG = TranslatorTreeBuilder.NAMESPACE_SYSTEM +
                '.doubleToLong';
        const FUNCTION_REAL_TO_LONG = TranslatorTreeBuilder.NAMESPACE_SYSTEM +
                '.realToLong';
        const FUNCTION_XVECTOR_EXTRACT = TranslatorTreeBuilder.NAMESPACE_SYSTEM +
                '.xvectorExtract';
        const FUNCTION_XVECTOR_TO_ULTRA = TranslatorTreeBuilder.NAMESPACE_SYSTEM +
                '.xvectorToUltra';

    public
        constructor create(extension: int; generator: TextGenerator64; owning: boolean);
        procedure buildTargetCode(programme: BuilderOfTrees; stream: Output); override;
    strict private
        fldExtension: int;
        poolOfLong: PoolLong;
        poolOfUltra: PoolUltra;
        poolOfXVector: PoolXVector;
        procedure translateEntryEquality(entry: NamespaceEntry);
        procedure translateEntryReadonly(entry: NamespaceEntry);
        procedure translateEntryVariable(entry: NamespaceEntry);
        procedure translateEntryFunction(entry: NamespaceEntry; programme: BuilderOfTrees);
        procedure translateStructure(structure: TypeStructure);
        procedure translateConstant(constant: GlobalConstant);
        procedure translateVariable(variable: GlobalVariable);
        procedure translateException(exception: GlobalException);
        procedure translateFunction(func: GlobalFunction; programme: BuilderOfTrees);
        procedure translateTree(tree: SyntaxTree);
        procedure translateNode(node: SyntaxNode; stack: RegisterStack);
        procedure translateSwitch(node: SyntaxNode; stack: RegisterStack);
        procedure translateExceptionHandler(root: SyntaxNode; argums, locals: int);
        procedure writePools();
        function insertArguments(args: TypeFunction; offset: int): int;
        function insertLocalVars(tree: SyntaxTree; offset: int): int;
        function getMemoryLocation(node: SyntaxNode; stack: RegisterStack;
                hasValueForWrite: boolean): MemoryLocation;
    protected
        property extension: int read fldExtension;
        property programmeLongs: PoolLong read poolOfLong;
        property programmeXUltras: PoolUltra read poolOfUltra;
        property programmeXVectors: PoolXVector read poolOfXVector;
    end;

implementation

{ RegisterStack64bit }

constructor RegisterStack64bit.create(const usingGPRS, usingXMMS: short_Array1d);
begin
    inherited create(usingGPRS, usingXMMS, -1, -1);
end;

procedure RegisterStack64bit.storeRegs(count: int; g: TextGenerator);
var
    nonPushable: boolean;
    i: int;
    j: int;
    ofs: int;
    reg1: int;
    sbase: int;
    ssize: int;
    stack: short_Array1d;
    sr1: String;
    sRSP: String;
begin
    { Инструкции, вставляемые этим методом, не модифицируют регистр флагов. }
    sbase := self.sbase;
    ssize := self.ssize;
    stack := self.stack;
    nonPushable :=  false;
    i := sbase;
    j := 0;
    ofs := 0;
    while (i < ssize) and (j < count) do begin
        reg1 := stack[i];
        case reg1 of
        R0..R15, R0D..R15D: begin
            inc(ofs, 8);
        end;
        (XMM0 + XSLONG)..(XMM15 + XSLONG), (XMM0 + XSDOUBLE)..(XMM15 + XSDOUBLE), MM0..MM7,
        (XMM0 + XSINT)..(XMM15 + XSINT), (XMM0 + XSFLOAT)..(XMM15 + XSFLOAT): begin
            nonPushable := true;
            inc(ofs, 8);
        end;
        ST0..ST7,
        (XMM0 + XPFLOAT)..(XMM15 + XPFLOAT), (XMM0 + XPDOUBLE)..(XMM15 + XPDOUBLE),
        (XMM0 + XPINT)..(XMM15 + XPINT), (XMM0 + XPLONG)..(XMM15 + XPLONG): begin
            nonPushable := true;
            inc(ofs, 16);
        end;
        end;
        inc(i);
        inc(j);
    end;
    sRSP := g.registerToString(RSP);
    if nonPushable then begin
        g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -ofs));
    end;
    i := sbase;
    j := 0;
    while (i < ssize) and (j < count) do begin
        reg1 := stack[i];
        sr1 := g.registerToString(reg1);
        case reg1 of
        R0..R15, R0D..R15D: begin
            if nonPushable then begin
                dec(ofs, 8);
                g.writeInstruction('mov', g.memoryToString(MNONE, RSP, ofs), sr1);
            end else begin
                g.writeInstruction('push', g.registerToString(R0 + (reg1 and $0f)));
            end;
        end;
        (XMM0 + XSINT)..(XMM15 + XSINT): begin
            dec(ofs, 8);
            g.writeInstruction('movd', g.memoryToString(MNONE, RSP, ofs), sr1);
        end;
        (XMM0 + XSFLOAT)..(XMM15 + XSFLOAT): begin
            dec(ofs, 8);
            g.writeInstruction('movss', g.memoryToString(MNONE, RSP, ofs), sr1);
        end;
        (XMM0 + XSLONG)..(XMM15 + XSLONG), MM0..MM7: begin
            dec(ofs, 8);
            g.writeInstruction('movq', g.memoryToString(MNONE, RSP, ofs), sr1);
        end;
        (XMM0 + XSDOUBLE)..(XMM15 + XSDOUBLE): begin
            dec(ofs, 8);
            g.writeInstruction('movsd', g.memoryToString(MNONE, RSP, ofs), sr1);
        end;
        ST: begin
            dec(ofs, 16);
            g.writeInstruction('fstp', g.memoryToString(MREAL, RSP, ofs));
            { g.writeInstruction('fdecstp'); }
        end;
        ST1..ST7: begin
            dec(ofs, 16);
            g.writeInstruction('fxch', sr1);
            g.writeInstruction('fstp', g.memoryToString(MREAL, RSP, ofs));
            if reg1 > ST1 then begin
                g.writeInstruction('fld', g.registerToString(reg1 - 1));
                g.writeInstruction('ffree', sr1);
            end;
        end;
        (XMM0 + XPINT)..(XMM15 + XPINT), (XMM0 + XPLONG)..(XMM15 + XPLONG): begin
            dec(ofs, 16);
            g.writeInstruction('movdqu', g.memoryToString(MNONE, RSP, ofs), sr1);
        end;
        (XMM0 + XPFLOAT)..(XMM15 + XPFLOAT): begin
            dec(ofs, 16);
            g.writeInstruction('movups', g.memoryToString(MNONE, RSP, ofs), sr1);
        end;
        (XMM0 + XPDOUBLE)..(XMM15 + XPDOUBLE): begin
            dec(ofs, 16);
            g.writeInstruction('movupd', g.memoryToString(MNONE, RSP, ofs), sr1);
        end;
        end;
        inc(i);
        inc(j);
    end;
    self.sbase := i;
end;

procedure RegisterStack64bit.restoreRegs(g: TextGenerator);
var
    nonPopable: boolean;
    i: int;
    nbs: int;
    ofs: int;
    reg1: int;
    reglf: int;
    sbase: int;
    limit: int;
    stack: short_Array1d;
    sr1: String;
    sRSP: String;
begin
    { Инструкции, вставляемые этим методом, не модифицируют регистр флагов. }
    sbase := self.sbase;
    limit := self.ssize - 1;
    stack := self.stack;
    reglf := ST - 1;
    for i := sbase to limit do begin
        reg1 := stack[i];
        if (reg1 >= ST0) and (reg1 <= ST7) then begin
            reglf := reg1;
            break;
        end;
    end;
    nonPopable := false;
    i := sbase;
    while i > 0 do begin
        reg1 := stack[i - 1];
        if (reg1 >= ST0) and (reg1 <= ST7) and (reglf < ST7) then begin
            inc(reglf);
            reg1 := reglf;
            stack[i - 1] := short(reg1);
        end;
        if isUsedRegister(reg1) then begin
            break;
        end;
        dec(i);
        self.sbase := i;
        case reg1 of
        MM0..MM7, ST0..ST7,
        (XMM0 + XPINT)..(XMM15 + XPINT), (XMM0 + XPLONG)..(XMM15 + XPLONG),
        (XMM0 + XSINT)..(XMM15 + XSINT), (XMM0 + XSLONG)..(XMM15 + XSLONG),
        (XMM0 + XPFLOAT)..(XMM15 + XPFLOAT), (XMM0 + XPDOUBLE)..(XMM15 + XPDOUBLE),
        (XMM0 + XSFLOAT)..(XMM15 + XSFLOAT), (XMM0 + XSDOUBLE)..(XMM15 + XSDOUBLE):
            nonPopable := true;
        R0..R15, R0D..R15D: ;
        end;
    end;
    nbs := i;
    ofs := 0;
    sRSP := g.registerToString(RSP);
    for i := sbase - 1 downto nbs do begin
        reg1 := stack[i];
        sr1 := g.registerToString(reg1);
        case reg1 of
        R0..R15, R0D..R15D: begin
            if nonPopable then begin
                g.writeInstruction('mov', sr1, g.memoryToString(MNONE, RSP, ofs));
                inc(ofs, 8);
            end else begin
                g.writeInstruction('pop', g.registerToString(R0 + (reg1 and $0f)));
            end;
        end;
        (XMM0 + XSINT)..(XMM15 + XSINT): begin
            g.writeInstruction('movd', sr1, g.memoryToString(MNONE, RSP, ofs));
            inc(ofs, 8);
        end;
        (XMM0 + XSFLOAT)..(XMM15 + XSFLOAT): begin
            g.writeInstruction('movss', sr1, g.memoryToString(MNONE, RSP, ofs));
            inc(ofs, 8);
        end;
        (XMM0 + XSLONG)..(XMM15 + XSLONG), MM0..MM7: begin
            g.writeInstruction('movq', sr1, g.memoryToString(MNONE, RSP, ofs));
            inc(ofs, 8);
        end;
        (XMM0 + XSDOUBLE)..(XMM15 + XSDOUBLE): begin
            g.writeInstruction('movsd', sr1, g.memoryToString(MNONE, RSP, ofs));
            inc(ofs, 8);
        end;
        ST0..ST6: begin
            g.writeInstruction('fld', g.memoryToString(MREAL, RSP, ofs));
            if reg1 > ST0 then begin
                g.writeInstruction('fstp', g.registerToString(reg1 + 1));
            end;
            inc(ofs, 16);
        end;
        ST7: begin
            g.writeInstruction('fld', g.memoryToString(MREAL, RSP, ofs));
            g.writeInstruction('fincstp');
            inc(ofs, 16);
        end;
        (XMM0 + XPINT)..(XMM15 + XPINT), (XMM0 + XPLONG)..(XMM15 + XPLONG): begin
            g.writeInstruction('movdqu', sr1, g.memoryToString(MNONE, RSP, ofs));
            inc(ofs, 16);
        end;
        (XMM0 + XPFLOAT)..(XMM15 + XPFLOAT): begin
            g.writeInstruction('movups', sr1, g.memoryToString(MNONE, RSP, ofs));
            inc(ofs, 16);
        end;
        (XMM0 + XPDOUBLE)..(XMM15 + XPDOUBLE): begin
            g.writeInstruction('movupd', sr1, g.memoryToString(MNONE, RSP, ofs));
            inc(ofs, 16);
        end;
        end;
    end;
    if nonPopable then begin
        g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, ofs));
    end;
end;

function RegisterStack64bit.getNextUsedGPR(regGPR: int): int;
var
    i: int;
    regcm: int;
    regus: int;
    using: short_Array1d;
begin
    using := self.usingGPRs;
    regcm := R0 + (regGPR and $0f);
    result := R0 + (using[0] and $0f);
    for i := length(using) - 1 downto 0 do begin
        regus := R0 + (using[i] and $0f);
        if regus = regcm then begin
            exit;
        end;
        result := regus;
    end;
end;

function RegisterStack64bit.changeToGPR64bit(index: int): int;
var
    ssize: int;
    stack: short_Array1d;
begin
    ssize := self.ssize;
    if (index < 0) or (index >= ssize) then begin
        raise IndexOutOfBoundsException.create(msgIndexOutOfBounds);
    end;
    stack := self.stack;
    index := ssize - index - 1;
    result := stack[index];
    if not isRegisterGP(result) then begin
        result := -1;
        exit;
    end;
    result := R0 + (result and $0f);
    stack[index] := short(result);
end;

function RegisterStack64bit.allocateGPR64bit(g: TextGenerator): int;
var
    i: int;
    regst: int;
    uslim: int;
    sbase: int;
    limit: int;
    stack: short_Array1d;
    using: short_Array1d;
begin
    result := -1;
    using := self.usingGPRs;
    stack := self.stack;
    limit := self.ssize - 1;
    sbase := self.sbase;
    uslim := length(using) - 1;
    for i := limit downto 0 do begin
        regst := getCommonRegister(stack[i]);
        if result < 0 then begin
            if isUsing(regst, using) then begin
                result := getCommonRegister(getNextUsedGPR(regst));
            end;
        end else begin
            if regst = result then begin
                regst := R0 + (regst and $0f);
                if i >= sbase then begin
                    storeRegs(i - sbase + 1, g);
                end;
                pushReg(regst);
                result := regst;
                exit;
            end;
        end;
    end;
    if result >= 0 then begin
        regst := R0 + (result and $0f);
        pushReg(regst);
        result := regst;
        exit;
    end;
    for i := 0 to uslim do begin
        regst := R0 + (using[i] and $0f);
        if not isUsedRegister(regst) then begin
            pushReg(regst);
            result := regst;
            exit;
        end;
    end;
    for i := sbase to limit do begin
        regst := getCommonRegister(stack[i]);
        if isUsing(regst, using) then begin
            regst := R0 + (regst and $0f);
            storeRegs(i - sbase + 1, g);
            pushReg(regst);
            result := regst;
            exit;
        end;
    end;
    result := -1;
end;

function RegisterStack64bit.allocateGPRForArray(g: TextGenerator): int;
begin
    result := allocateGPR64bit(g);
end;

function RegisterStack64bit.allocateGPRForIndex(g: TextGenerator): int;
begin
    result := allocateGPR64bit(g);
end;

function RegisterStack64bit.allocateGPRForPointer(g: TextGenerator): int;
begin
    result := allocateGPR64bit(g);
end;

procedure RegisterStack64bit.checkRegister(reg: int);
begin
    case reg of
    R0..R15, R0D..R15D, MM0..MM7, ST0..ST7,
    (XMM0 + XPINT)..(XMM15 + XPINT), (XMM0 + XPLONG)..(XMM15 + XPLONG),
    (XMM0 + XSINT)..(XMM15 + XSINT), (XMM0 + XSLONG)..(XMM15 + XSLONG),
    (XMM0 + XPFLOAT)..(XMM15 + XPFLOAT), (XMM0 + XPDOUBLE)..(XMM15 + XPDOUBLE),
    (XMM0 + XSFLOAT)..(XMM15 + XSFLOAT), (XMM0 + XSDOUBLE)..(XMM15 + XSDOUBLE): ;
    else
        raise IllegalArgumentException.create(msgIllegalRegisters);
    end;
end;

{ TranslatorBuilderOf64bitCode }

constructor TranslatorBuilderOf64bitCode.create(extension: int;
        generator: TextGenerator64; owning: boolean);
begin
    inherited create(generator, owning);
    self.fldExtension := extension;
    self.poolOfLong := TranslatorPoolLong.create();
    self.poolOfUltra := TranslatorPoolUltra.create();
    self.poolOfXVector := TranslatorPoolXVector.create();
end;

procedure TranslatorBuilderOf64bitCode.buildTargetCode(programme: BuilderOfTrees; stream: Output);
var
    i: int;
    j: int;
    elimit: int;
    mlimit: int;
    module: Namespace;
    pentry: GlobalFunction;
    g: TextGenerator;
begin
    g := self.generator;
    g.clear();
    try
        programmeReals.clear();
        programmeFloats.clear();
        programmeDoubles.clear();
        programmeStrings.clear();
        programmeFunctions.clear();
        programmeLongs.clear();
        programmeXUltras.clear();
        programmeXVectors.clear();
        pentry := programme.entryPoint;
        g.writeDirectives(MODE_64_BIT, 0, encode(pentry.name));
        g.writeEmptyLine();
        g.writeEmptyLine();
        g.writeCommentToLineEnd('constant of boolean type');
        g.writeEquality('false', g.immediateToString(0));
        g.writeEquality('true', g.immediateToString(1));
        g.writeEmptyLine();
        g.writeEmptyLine();
        g.writeCommentToLineEnd('constant null');
        g.writeEquality('null', g.immediateToString(0));
        g.writeEmptyLine();
        mlimit := programme.getNamespacesCount() - 1;
        for j := 0 to mlimit do begin
            module := programme.getNamespace(j);
            if length(module.name) <= 0 then begin
                continue;
            end;
            elimit := module.getEntriesCount() - 1;
            for i := 0 to elimit do begin
                translateEntryEquality(module.getEntry(i));
            end;
        end;
        g.beginCodeSection();
        translateFunction(pentry, programme);
        for j := 0 to mlimit do begin
            module := programme.getNamespace(j);
            if length(module.name) <= 0 then begin
                continue;
            end;
            elimit := module.getEntriesCount() - 1;
            for i := 0 to elimit do begin
                translateEntryFunction(module.getEntry(i), programme);
            end;
        end;
        g.beginDataSection();
        for j := 0 to mlimit do begin
            module := programme.getNamespace(j);
            if length(module.name) <= 0 then begin
                continue;
            end;
            elimit := module.getEntriesCount() - 1;
            for i := 0 to elimit do begin
                translateEntryVariable(module.getEntry(i));
            end;
        end;
        g.beginPoolSection();
        for j := 0 to mlimit do begin
            module := programme.getNamespace(j);
            if length(module.name) <= 0 then begin
                continue;
            end;
            elimit := module.getEntriesCount() - 1;
            for i := 0 to elimit do begin
                translateEntryReadonly(module.getEntry(i));
            end;
        end;
        writePools();
        g.writeProgrammeTail();
        g.writeEmptyLine();
        g.writeCommentToLineEnd('programme end');
        g.writeAlignGlobal(8);
        g.writeLabelLong(LABEL_PROG_END);
        g.optimize();
    finally
        stream.write(stringToByteArray(g.toString()));
    end;
end;

procedure TranslatorBuilderOf64bitCode.translateEntryEquality(entry: NamespaceEntry);
begin
    if entry is TypeStructure then begin
        translateStructure(entry as TypeStructure);
    end else
    if entry is GlobalConstant then begin
        translateConstant(entry as GlobalConstant);
    end;
end;

procedure TranslatorBuilderOf64bitCode.translateEntryReadonly(entry: NamespaceEntry);
begin
    if entry is GlobalException then begin
        translateException(entry as GlobalException);
    end;
end;

procedure TranslatorBuilderOf64bitCode.translateEntryVariable(entry: NamespaceEntry);
begin
    if not (entry is GlobalConstant) and (entry is GlobalVariable) then begin
        translateVariable(entry as GlobalVariable);
    end;
end;

procedure TranslatorBuilderOf64bitCode.translateEntryFunction(entry: NamespaceEntry;
        programme: BuilderOfTrees);
begin
    if entry is GlobalFunction then begin
        translateFunction(entry as GlobalFunction, programme);
    end;
end;

procedure TranslatorBuilderOf64bitCode.translateStructure(structure: TypeStructure);
var
    i: int;
    limit: int;
    field: StructureField;
    g: TextGenerator;
    ename: String;
    fname: String;
begin
    g := self.generator;
    ename := getEntryFullName(structure as NamespaceEntry);
    g.writeEmptyLine();
    g.writeCommentToLineEnd('structure ' + ename);
    repeat
        limit := structure.getFieldsCount() - 1;
        for i := 0 to limit do begin
            field := structure.getField(i);
            fname := encode(field.name);
            if length(fname) > 0 then begin
                g.writeEquality(ename + '.' + fname, g.immediateToString(field.offset));
            end;
        end;
        structure := structure.ancestor;
    until structure = nil;
    g.writeEmptyLine();
end;

procedure TranslatorBuilderOf64bitCode.translateConstant(constant: GlobalConstant);
var
    g: TextGenerator;
    ename: String;
begin
    g := self.generator;
    ename := getEntryFullName(constant);
    g.writeEmptyLine();
    g.writeCommentToLineEnd('constant ' + ename);
    case constant.dataType.kind of
    TranslatorType.KIND_BOOLEAN:
        if constant.booleanValue = true then begin
            g.writeEquality(ename, 'true');
        end else begin
            g.writeEquality(ename, 'false');
        end;
    TranslatorType.KIND_CHAR:
        g.writeEquality(ename, g.immediateToString(constant.charValue));
    TranslatorType.KIND_BYTE:
        g.writeEquality(ename, g.immediateToString(constant.byteValue));
    TranslatorType.KIND_SHORT:
        g.writeEquality(ename, g.immediateToString(constant.shortValue));
    TranslatorType.KIND_INT:
        g.writeEquality(ename, g.immediateToString(constant.intValue));
    TranslatorType.KIND_LONG:
        g.writeEquality(ename, g.memoryToString(MLONG, LABEL_POOL_LONG_CONTENT,
                programmeLongs.indexAcquire(constant.longValue) * 8));
    TranslatorType.KIND_ULTRA:
        g.writeEquality(ename, g.memoryToString(MNONE, LABEL_POOL_ULTRA_CONTENT,
                programmeXUltras.indexAcquire(constant.getUltraValue()) * 16));
    TranslatorType.KIND_FLOAT:
        g.writeEquality(ename, g.memoryToString(MFLOAT, LABEL_POOL_FLOAT_CONTENT,
                programmeFloats.indexAcquire(realToFloat(constant.realValue)) * 4));
    TranslatorType.KIND_DOUBLE:
        g.writeEquality(ename, g.memoryToString(MDOUBLE, LABEL_POOL_DOUBLE_CONTENT,
                programmeDoubles.indexAcquire(realToDouble(constant.realValue)) * 8));
    TranslatorType.KIND_REAL:
        g.writeEquality(ename, g.memoryToStringDecOffset(MREAL, LABEL_POOL_REAL_CONTENT,
                programmeReals.indexAcquire(constant.realValue) * 10));
    TranslatorType.KIND_XVECTOR:
        g.writeEquality(ename, g.memoryToString(MNONE, LABEL_POOL_XVECTOR_CONTENT,
                programmeXVectors.indexAcquire(constant.getXVectorValue()) * 16));
    end;
    g.writeEmptyLine();
end;

procedure TranslatorBuilderOf64bitCode.translateVariable(variable: GlobalVariable);
var
    vtype: TypeDescriptor;
    g: TextGenerator;
    ename: String;
    szero: String;
begin
    g := self.generator;
    ename := getEntryFullName(variable);
    vtype := variable.dataType;
    g.writeAlignGlobal(8);
    g.writeLabelGlobal(ename);
    g.writeCommentToLineEnd(vtype.toString());
    case vtype.kind of
    TranslatorType.KIND_BOOLEAN, TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
    TranslatorType.KIND_SHORT, TranslatorType.KIND_INT, TranslatorType.KIND_FLOAT:
        g.writeInstruction('dd', g.immediateToStringInt(0));
    TranslatorType.KIND_STRUCT, TranslatorType.KIND_ARRAY, TranslatorType.KIND_FUNC,
    TranslatorType.KIND_LONG, TranslatorType.KIND_DOUBLE:
        g.writeInstruction('dq', g.immediateToStringLong(0));
    TranslatorType.KIND_ULTRA, TranslatorType.KIND_XVECTOR: begin
        szero := g.immediateToStringLong(0);
        g.writeInstruction('dq', szero, szero);
    end;
    TranslatorType.KIND_REAL: begin
        szero := g.immediateToStringShort(0);
        g.writeInstruction('dw', String_Array1d_create([
            szero, szero, szero, szero, szero
        ]));
    end;
    end;
    g.writeEmptyLine();
end;

procedure TranslatorBuilderOf64bitCode.translateException(exception: GlobalException);
var
    g: TextGenerator;
    ename: String;
begin
    g := self.generator;
    ename := getEntryFullName(exception);
    g.writeAlignGlobal(4);
    g.writeLabelGlobal(ename);
    g.writeCommentToLineEnd('exception');
    exception := exception.ancestor;
    if exception <> nil then begin
        g.writeInstruction('dd', g.labelRelativeToString(getEntryFullName(exception), 0));
    end else begin
        g.writeInstruction('dd', g.immediateToStringInt(0));
    end;
    g.writeEmptyLine();
end;

procedure TranslatorBuilderOf64bitCode.translateFunction(func: GlobalFunction;
        programme: BuilderOfTrees);
var
    interruptWithError: boolean;
    functionWithSFrame: boolean;
    functionIsEntry: boolean;
    funcassembler: boolean;
    pureassembler: boolean;
    i: int;
    limit: int;
    pcount: int;
    pstart: int;
    pfinish: int;
    argumsSize: int;
    localsSize: int;
    lexemes: Lexer;
    tree: SyntaxTree;
    root: SyntaxNode;
    module: Namespace;
    entry: NamespaceEntry;
    ftype: TypeFunction;
    g: TextGenerator;
    comment: String;
    ename: String;
begin
    if func.publicObject then begin
        programmeFunctions.addElement(func);
    end;
    g := self.generator;
    ename := getEntryFullName(func);
    ftype := func.functionType;
    module := func.owner;
    funcassembler := func.isAssembler();
    pureassembler := func.isPureAssembler();
    functionIsEntry := length(module.name) <= 0;
    if functionIsEntry = false then begin
        g.writeAlignGlobal(4);
    end;
    g.writeLabelGlobal(ename);
    limit := ftype.getArgumentsCount() - 1;
    { вставка типа возвращаемого значения и аргументов функции }
    comment := ftype.getReturnType().toString();
    if limit >= 0 then begin
        g.writeCommentToLineEnd(comment + '(');
        for i := 0 to limit do with ftype.getArgument(i) do begin
            comment := dataType.toString() + #$20 + encode(name);
            if i < limit then begin
                g.writeCommentWithIdent(comment + ',');
            end else begin
                g.writeCommentWithIdent(comment + ')');
            end;
        end;
    end else begin
        g.writeCommentToLineEnd(comment + '()');
    end;
    { определение границ функции в исходном тексте }
    lexemes := module.lexemes;
    pcount := 1;
    pstart := func.startPosition + 1;
    pfinish := pstart - 1;
    repeat
        inc(pfinish);
        case lexemes.getType(pfinish) of
        TranslatorLexer.OPENED_CURLY_BRACKET:
            inc(pcount);
        TranslatorLexer.CLOSED_CURLY_BRACKET:
            dec(pcount);
        end;
    until pcount = 0;
    if func.isInterrupt() then begin
        { чтобы функция-прерывание имела параметр «код ошибки», нужно чтобы четвёртый параметр
          начинался с "error" (например: error, errorCode, errorSegment, errorFlags и т. п.).
          Регистр символов учитывается, т. е. имена вроде ErrorCode не распознаются как параметр
          «код ошибки». }
        inc(limit);
        interruptWithError := (limit >= 6) and
                stringStartsWith(UnicodeString('error'), ftype.getArgument(5).name);
        tree := programme.buildSyntaxTree(func) as SyntaxTree;
        if interruptWithError then begin
            argumsSize := insertArguments(ftype, (22 - limit) shl 3);
        end else begin
            argumsSize := insertArguments(ftype, (21 - limit) shl 3);
        end;
        localsSize := insertLocalVars(tree, 0);
        if pureassembler then begin
            g.writeAssembler(stringTrim(encode(lexemes.getSourceFragment(
                    lexemes.getLine(pstart), lexemes.getChar(pstart),
                    lexemes.getLine(pfinish), lexemes.getChar(pfinish)))));
        end else begin
            g.writeInstruction('pushq', g.immediateToString(0));
            g.writeInstruction('push', g.registerToString(R0));
            g.writeInstruction('push', g.registerToString(R1));
            g.writeInstruction('push', g.registerToString(R2));
            g.writeInstruction('push', g.registerToString(R3));
            g.writeInstruction('push', g.registerToString(R6));
            g.writeInstruction('push', g.registerToString(R7));
            g.writeInstruction('push', g.registerToString(R8));
            g.writeInstruction('push', g.registerToString(R9));
            g.writeInstruction('push', g.registerToString(R10));
            g.writeInstruction('push', g.registerToString(R11));
            g.writeInstruction('push', g.registerToString(R12));
            g.writeInstruction('push', g.registerToString(R13));
            g.writeInstruction('push', g.registerToString(R14));
            g.writeInstruction('push', g.registerToString(R15));
            if funcassembler = false then begin
                g.writeInstruction('lea', g.registerToString(R15),
                        g.memoryToString(MNONE, LABEL_EXCEPTION_HANDLER, 0));
            end;
            g.writeInstruction('enter', g.immediateToStringShort(localsSize),
                    g.immediateToStringByte(0));
            g.writeInstruction('mov', g.registerToString(R0), g.registerToString(RBP));
            g.writeInstruction('mov', g.memoryToString(MNONE, R0, $78), g.registerToString(RBP));
            if funcassembler then begin
                g.writeAssembler(stringTrim(encode(lexemes.getSourceFragment(
                        lexemes.getLine(pstart), lexemes.getChar(pstart),
                        lexemes.getLine(pfinish), lexemes.getChar(pfinish)))));
            end else begin
                translateTree(tree);
            end;
            g.writeInstruction('leave');
            g.writeInstruction('pop', g.registerToString(R15));
            g.writeInstruction('pop', g.registerToString(R14));
            g.writeInstruction('pop', g.registerToString(R13));
            g.writeInstruction('pop', g.registerToString(R12));
            g.writeInstruction('pop', g.registerToString(R11));
            g.writeInstruction('pop', g.registerToString(R10));
            g.writeInstruction('pop', g.registerToString(R9));
            g.writeInstruction('pop', g.registerToString(R8));
            g.writeInstruction('pop', g.registerToString(R7));
            g.writeInstruction('pop', g.registerToString(R6));
            g.writeInstruction('pop', g.registerToString(R3));
            g.writeInstruction('pop', g.registerToString(R2));
            g.writeInstruction('pop', g.registerToString(R1));
            g.writeInstruction('pop', g.registerToString(R0));
            if interruptWithError then begin
                g.writeInstruction('add', g.registerToString(RSP), g.immediateToString($10));
            end else begin
                g.writeInstruction('add', g.registerToString(RSP), g.immediateToString($08));
            end;
            g.writeInstruction('iretq');
        end;
    end else begin
        tree := programme.buildSyntaxTree(func) as SyntaxTree;
        if funcassembler then begin
            argumsSize := insertArguments(ftype, $10);
        end else
        if functionIsEntry and (g.exitMethod = TextGenerator.EXIT_RETF) then begin
            argumsSize := insertArguments(ftype, $20);
        end else begin
            argumsSize := insertArguments(ftype, $18);
        end;
        localsSize := insertLocalVars(tree, 0);
        if pureassembler then begin
            g.writeAssembler(stringTrim(encode(lexemes.getSourceFragment(
                    lexemes.getLine(pstart), lexemes.getChar(pstart),
                    lexemes.getLine(pfinish), lexemes.getChar(pfinish)))));
        end else begin
            functionWithSFrame := (argumsSize > 0) or (localsSize > 0) or (funcassembler = false);
            if funcassembler = false then begin
                g.writeInstruction('push', g.registerToString(R15));
                g.writeInstruction('lea', g.registerToString(R15),
                        g.memoryToString(MNONE, LABEL_EXCEPTION_HANDLER, 0));
            end;
            if functionWithSFrame then begin
                g.writeInstruction('enter', g.immediateToStringShort(localsSize),
                        g.immediateToStringByte(0));
            end;
            if funcassembler then begin
                g.writeAssembler(stringTrim(encode(lexemes.getSourceFragment(
                        lexemes.getLine(pstart), lexemes.getChar(pstart),
                        lexemes.getLine(pfinish), lexemes.getChar(pfinish)))));
            end else begin
                translateTree(tree);
            end;
            if functionIsEntry then begin
                entry := programme.systemNamespace.findEntry(VARIABLE_RESULT, false);
                if entry is GlobalVariable then begin
                    g.writeInstruction('mov', g.registerToString(R0),
                            g.memoryToString(MNONE, getEntryFullName(entry), 0));
                end;
            end else begin
                entry := nil;
            end;
            if functionWithSFrame then begin
                g.writeInstruction('leave');
            end;
            if funcassembler = false then begin
                g.writeInstruction('pop', g.registerToString(R15));
            end;
            if functionIsEntry then begin
                case g.exitMethod of
                TextGenerator.EXIT_RETF: begin
                    if argumsSize > 0 then begin
                        g.writeInstruction('retf', g.immediateToString(argumsSize));
                    end else begin
                        g.writeInstruction('retf');
                    end;
                end;
                TextGenerator.EXIT_CALL: begin
                    if entry is GlobalVariable then begin
                        g.writeInstruction('push', g.registerToString(R0));
                    end else begin
                        g.writeInstruction('pushq', g.immediateToString(0));
                    end;
                    g.writeInstruction('call', FUNCTION_EXIT);
                end;
                else
                    if argumsSize > 0 then begin
                        g.writeInstruction('ret', g.immediateToString(argumsSize));
                    end else begin
                        g.writeInstruction('ret');
                    end;
                end;
            end else begin
                if argumsSize > 0 then begin
                    g.writeInstruction('ret', g.immediateToString(argumsSize));
                end else begin
                    g.writeInstruction('ret');
                end;
            end;
        end;
    end;
    if tree <> nil then begin
        root := tree.root as SyntaxNode;
    end else begin
        root := nil;
    end;
    if funcassembler = false then begin
        { вставка обработчика исключений }
        translateExceptionHandler(root, argumsSize, localsSize);
    end;
    if tree <> nil then begin
        { очистка памяти }
        tree.deleteChildrens(root);
        root.clearData();
    end;
    g.writeEmptyLine();
end;

procedure TranslatorBuilderOf64bitCode.translateTree(tree: SyntaxTree);
var
    i: int;
    limit: int;
    aLabelNumber: int;
    nodePosition: int;
    oldLineNumber: int;
    newLineNumber: int;
    node: BuilderNode;
    g: TextGenerator;
    lexemes: Lexer;
    stack: RegisterStack;
    sourceName: String;
begin
    g := self.generator;
    lexemes := ((tree.root as SyntaxNode).associate as GlobalFunction).owner.lexemes;
    stack := RegisterStack64bit.create(short_Array1d_create([
        R0, R6, R7, R8, R9, R10, R11, R12, R13, R14
    ]), short_Array1d_create([
        XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, XMM8, XMM9, XMM10, XMM11
    ]));
    oldLineNumber := 0;
    sourceName := encode(lexemes.sourceName);
    limit := tree.getNodesWithLabelNumberCount() - 1;
    for i := 1 to limit do begin
        node := tree.getNodeWithLabelNumber(i) as BuilderNode;
        nodePosition := node.position;
        if nodePosition >= 0 then begin
            newLineNumber := lexemes.getLine(nodePosition);
            if (newLineNumber > 0) and (oldLineNumber <> newLineNumber) then begin
                g.writeCommentWithIdent(sourceName + '[' + intToString(newLineNumber) + ']: ' +
                        encode(lexemes.getSourceLine(newLineNumber)));
                oldLineNumber := newLineNumber;
            end;
        end;
        aLabelNumber := node.assignedLabelNumber;
        if aLabelNumber >= 0 then begin
            g.writeLabelShort(LABEL_LOCAL + intToString(aLabelNumber));
        end;
        translateNode(node, stack);
    end;
end;

procedure TranslatorBuilderOf64bitCode.translateNode(node: SyntaxNode; stack: RegisterStack);
var
    regInUse: boolean;
    reg1: int;
    reg2: int;
    count: int;
    buffer: int;
    buffer1: int;
    buffer2: int;
    buffer3: int;
    nodeIndex: int;
    nodeValue: int;
    nodeLN: int;
    parent: SyntaxNode;
    nodeAsoc: _Interface;
    nodeType: TypeDescriptor;
    mem: MemoryLocation;
    child: SyntaxNode;
    current: SyntaxNode;
    funcNode: SyntaxNode;
    funcType: TypeFunction;
    funcReturn: TypeDescriptor;
    gotoNode: BuilderNode;
    goAlwaysTo: BuilderNode;
    goIfTrueTo: BuilderNode;
    goIfFalseTo: BuilderNode;
    g: TextGenerator;
    slbl: String;
    simm: String;
    smmb: String;
    smmw: String;
    smmd: String;
    smmq: String;
    smmt: String;
    smm: String;
    srb: String;
    srw: String;
    srd: String;
    srq: String;
    sr1: String;
    sr2: String;
    sR0B: String;
    sR1B: String;
    sR2B: String;
    sR3B: String;
    sR0S: String;
    sR2S: String;
    sR3S: String;
    sR0I: String;
    sR1I: String;
    sR2I: String;
    sR3I: String;
    sR0L: String;
    sR1L: String;
    sR2L: String;
    sR3L: String;
    sRSP: String;
    sST0: String;
    sST1: String;
    sXMM0: String;
    sXMM12: String;
    sXMM13: String;
begin
    g := self.generator;
    sR0B := g.registerToString(R0B);
    sR1B := g.registerToString(R1B);
    sR2B := g.registerToString(R2B);
    sR3B := g.registerToString(R3B);
    sR0S := g.registerToString(R0W);
    sR2S := g.registerToString(R2W);
    sR3S := g.registerToString(R3W);
    sR0I := g.registerToString(R0D);
    sR1I := g.registerToString(R1D);
    sR2I := g.registerToString(R2D);
    sR3I := g.registerToString(R3D);
    sR0L := g.registerToString(R0);
    sR1L := g.registerToString(R1);
    sR2L := g.registerToString(R2);
    sR3L := g.registerToString(R3);
    sRSP := g.registerToString(RSP);
    sST0 := g.registerToString(ST0);
    sST1 := g.registerToString(ST1);
    sXMM0 := g.registerToString(XMM0);
    sXMM12 := g.registerToString(XMM12);
    sXMM13 := g.registerToString(XMM13);
    nodeIndex := node.index;
    nodeValue := node.value;
    nodeLN := node.labelNumber;
    nodeAsoc := node.associate;
    nodeType := node.dataType;
    goAlwaysTo := node.goAlwaysToNode as BuilderNode;
    goIfTrueTo := node.goIfTrueToNode as BuilderNode;
    goIfFalseTo := node.goIfFalseToNode as BuilderNode;
    parent := node.parent as SyntaxNode;
    { Узлы дерева разбора, которые возвращают значения не boolean типа и
      не порождают инструкций, указаны в этом цикле: }
    while (parent <> nil) and (parent.labelNumber < 0) do begin
        buffer := parent.value;
        if (buffer <> TranslatorTreeBuilder.EXPR_QUESTION) and
                (buffer <> TranslatorTreeBuilder.EXPR_TYPE_CAST) then begin
            break;
        end;
        nodeIndex := parent.index;
        parent := parent.parent as SyntaxNode;
    end;
    case nodeValue of
    TranslatorTreeBuilder.OPERATOR_VARIABLE,
    TranslatorTreeBuilder.BLOCK_WITH: begin
        reg2 := stack.getRegAt(0);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        with nodeAsoc as LocalVariable do begin
            nodeType := dataType;
            mem := MemoryLocationTfasm.create(g, 0, '.' + encode(name));
        end;
        smm := mem.memoryToString(MNONE, 0);
        smmt := mem.memoryToString(MREAL, 0);
        case nodeType.kind of
        TranslatorType.KIND_BOOLEAN, TranslatorType.KIND_BYTE: begin
            sr2 := g.registerToString(R0B + (reg2 and $0f));
            g.writeInstruction('mov', smm, sr2);
        end;
        TranslatorType.KIND_CHAR, TranslatorType.KIND_SHORT: begin
            sr2 := g.registerToString(R0W + (reg2 and $0f));
            g.writeInstruction('mov', smm, sr2);
        end;
        TranslatorType.KIND_STRUCT, TranslatorType.KIND_ARRAY, TranslatorType.KIND_FUNC,
        TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
            g.writeInstruction('mov', smm, sr2);
        TranslatorType.KIND_ULTRA:
            g.writeInstruction('movdqu', smm, sr2);
        TranslatorType.KIND_FLOAT:
            g.writeInstruction('movss', smm, sr2);
        TranslatorType.KIND_DOUBLE:
            g.writeInstruction('movsd', smm, sr2);
        TranslatorType.KIND_REAL:
            g.writeInstruction('fstp', smmt);
        TranslatorType.KIND_XVECTOR:
            g.writeInstruction('movups', smm, sr2);
        end;
    end;
    TranslatorTreeBuilder.OPERATOR_DISPOSE: begin
        stack.storeRegs(1, g);
        stack.popRegs(1);
        g.writeInstruction('call', FUNCTION_DISPOSE);
    end;
    TranslatorTreeBuilder.OPERATOR_SWITCH: begin
        translateSwitch(node, stack);
    end;
    TranslatorTreeBuilder.OPERATOR_THROW: begin
        g.writeInstruction('lea', sR2L,
                g.memoryToString(MNONE, g.labelCurrentOffsetToString(0), 0));
        g.writeInstruction('lea', sR1L,
                g.memoryToString(MNONE, getEntryFullName(nodeAsoc as GlobalException), 0));
        g.writeInstruction('jmp', LABEL_EXCEPTION_HANDLER);
    end;
    TranslatorTreeBuilder.OPERATOR_RETURN,
    TranslatorTreeBuilder.TF_OPERATOR_RETURN: begin
        buffer := stack.size();
        if buffer > 0 then begin
            reg1 := stack.getRegAt(0);
        end else begin
            reg1 := -1;
        end;
        sr1 := g.registerToString(reg1);
        stack.popRegs(buffer);
        if nodeValue = TranslatorTreeBuilder.TF_OPERATOR_RETURN then begin
            case reg1 of
            R0..R15, R0D..R15D: begin
                g.writeInstruction('push', g.registerToString(R0 + (reg1 and $0f)));
            end;
            ST: begin
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -$10));
                g.writeInstruction('fstp', g.memoryToString(MREAL, RSP, 0));
            end;
            (XMM0 + XPINT)..(XMM15 + XPINT), (XMM0 + XPLONG)..(XMM15 + XPLONG): begin
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -$10));
                g.writeInstruction('movdqu', g.memoryToString(MNONE, RSP, 0), sr1);
            end;
            (XMM0 + XPFLOAT)..(XMM15 + XPFLOAT): begin
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -$10));
                g.writeInstruction('movups', g.memoryToString(MNONE, RSP, 0), sr1);
            end;
            (XMM0 + XPDOUBLE)..(XMM15 + XPDOUBLE): begin
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -$10));
                g.writeInstruction('movupd', g.memoryToString(MNONE, RSP, 0), sr1);
            end;
            (XMM0 + XSINT)..(XMM15 + XSINT): begin
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -$08));
                g.writeInstruction('movd', g.memoryToString(MNONE, RSP, 0), sr1);
            end;
            (XMM0 + XSLONG)..(XMM15 + XSLONG): begin
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -$08));
                g.writeInstruction('movq', g.memoryToString(MNONE, RSP, 0), sr1);
            end;
            (XMM0 + XSFLOAT)..(XMM15 + XSFLOAT): begin
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -$08));
                g.writeInstruction('movss', g.memoryToString(MNONE, RSP, 0), sr1);
            end;
            (XMM0 + XSDOUBLE)..(XMM15 + XSDOUBLE): begin
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -$08));
                g.writeInstruction('movsd', g.memoryToString(MNONE, RSP, 0), sr1);
            end;
            end;
            current := node.parent as SyntaxNode;
            repeat
                if current.value = TranslatorTreeBuilder.OPERATOR_TRY_FINALLY then begin
                    gotoNode := (current.getChild(current.getChildrensCount() - 1) as SyntaxNode).
                            goAlwaysToNode as BuilderNode;
                    if gotoNode <> nil then begin
                        g.writeInstruction('call',
                                LABEL_LOCAL + intToString(gotoNode.assignedLabelNumber));
                    end;
                end;
                current := current.parent as SyntaxNode;
            until current = nil;
            case reg1 of
            R0..R15, R0D..R15D: begin
                g.writeInstruction('pop', g.registerToString(R0 + (reg1 and $0f)));
            end;
            ST: begin
                g.writeInstruction('fld', g.memoryToString(MREAL, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, $10));
            end;
            (XMM0 + XPINT)..(XMM15 + XPINT), (XMM0 + XPLONG)..(XMM15 + XPLONG): begin
                g.writeInstruction('movdqu', sr1, g.memoryToString(MNONE, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, $10));
            end;
            (XMM0 + XPFLOAT)..(XMM15 + XPFLOAT): begin
                g.writeInstruction('movups', sr1, g.memoryToString(MNONE, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, $10));
            end;
            (XMM0 + XPDOUBLE)..(XMM15 + XPDOUBLE): begin
                g.writeInstruction('movupd', sr1, g.memoryToString(MNONE, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, $10));
            end;
            (XMM0 + XSINT)..(XMM15 + XSINT): begin
                g.writeInstruction('movd', sr1, g.memoryToString(MNONE, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, $08));
            end;
            (XMM0 + XSLONG)..(XMM15 + XSLONG): begin
                g.writeInstruction('movq', sr1, g.memoryToString(MNONE, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, $08));
            end;
            (XMM0 + XSFLOAT)..(XMM15 + XSFLOAT): begin
                g.writeInstruction('movss', sr1, g.memoryToString(MNONE, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, $08));
            end;
            (XMM0 + XSDOUBLE)..(XMM15 + XSDOUBLE): begin
                g.writeInstruction('movsd', sr1, g.memoryToString(MNONE, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, $08));
            end;
            end;
        end;
        if (goAlwaysTo <> nil) and (goAlwaysTo.labelNumber <> nodeLN + 1) then begin
            g.writeInstruction('jmp', LABEL_LOCAL + intToString(goAlwaysTo.assignedLabelNumber));
        end;
    end;
    TranslatorTreeBuilder.BLOCK_FINALLY_RETURN: begin
        g.writeInstruction('ret');
    end;
    TranslatorTreeBuilder.EXPR_VALUE_NULL: begin
        reg1 := stack.allocateGPR64bit(g);
        sr1 := g.registerToString(reg1);
        g.writeInstruction('xor', sr1, sr1);
    end;
    TranslatorTreeBuilder.EXPR_VALUE_BOOLEAN: begin
        if goAlwaysTo = nil then begin
            reg1 := stack.allocateGPR32bit(g);
            sr1 := g.registerToString(reg1);
            if (nodeAsoc as BooleanAsObject).booleanValue() = true then begin
                g.writeInstruction('mov', sr1, 'true');
            end else begin
                g.writeInstruction('mov', sr1, 'false');
            end;
        end else begin
            g.writeInstruction('jmp', LABEL_LOCAL + intToString(goAlwaysTo.assignedLabelNumber));
        end;
    end;
    TranslatorTreeBuilder.EXPR_VALUE_INT: begin
        reg1 := stack.allocateGPR32bit(g);
        sr1 := g.registerToString(reg1);
        buffer := (nodeAsoc as IntegerAsObject).intValue();
        if buffer = 0 then begin
            g.writeInstruction('xor', sr1, sr1);
        end else begin
            g.writeInstruction('mov', sr1, g.immediateToStringInt(buffer));
        end;
    end;
    TranslatorTreeBuilder.EXPR_VALUE_LONG: begin
        reg1 := stack.allocateGPR64bit(g);
        sr1 := g.registerToString(reg1);
        with (nodeAsoc as LongAsObject).longValue() do begin
            buffer := ints[0];
            buffer1 := ints[1];
        end;
        if (buffer or buffer1) = 0 then begin
            g.writeInstruction('xor', sr1, sr1);
        end else begin
            g.writeInstruction('mov', sr1, g.memoryToString(MNONE, LABEL_POOL_LONG_CONTENT,
                    programmeLongs.indexAcquire(longBuild(buffer1, buffer)) * 8));
        end;
    end;
    TranslatorTreeBuilder.EXPR_VALUE_ULTRA: begin
        reg1 := stack.allocateXMM(XPINT, g);
        sr1 := g.registerToString(reg1);
        with (nodeAsoc as UltraAsObject).ultraValue() do begin
            buffer := ints[0];
            buffer1 := ints[1];
            buffer2 := ints[2];
            buffer3 := ints[3];
        end;
        if (buffer or buffer1 or buffer2 or buffer3) = 0 then begin
            g.writeInstruction('pxor', sr1, sr1);
        end else begin
            g.writeInstruction('movdqu', sr1, g.memoryToString(MNONE,
                    LABEL_POOL_ULTRA_CONTENT, programmeXUltras.indexAcquire(
                    ultraBuild(buffer3, buffer2, buffer1, buffer)) * 16));
        end;
    end;
    TranslatorTreeBuilder.EXPR_VALUE_REAL: begin
        case nodeType.kind of
        TranslatorType.KIND_FLOAT: begin
            reg1 := stack.allocateXMM(XSFLOAT, g);
            sr1 := g.registerToString(reg1);
            g.writeInstruction('movss', sr1, g.memoryToString(MNONE,
                    LABEL_POOL_FLOAT_CONTENT, programmeFloats.indexAcquire(
                    (nodeAsoc as FloatAsObject).floatValue()) * 4));
        end;
        TranslatorType.KIND_DOUBLE: begin
            reg1 := stack.allocateXMM(XSDOUBLE, g);
            sr1 := g.registerToString(reg1);
            g.writeInstruction('movsd', sr1, g.memoryToString(MNONE,
                    LABEL_POOL_DOUBLE_CONTENT, programmeDoubles.indexAcquire(
                    (nodeAsoc as DoubleAsObject).doubleValue()) * 8));
        end;
        TranslatorType.KIND_REAL: begin
            stack.allocateFPU(1, g);
            g.writeInstruction('fld', g.memoryToStringDecOffset(MREAL,
                    LABEL_POOL_REAL_CONTENT, programmeReals.indexAcquire(
                    (nodeAsoc as RealAsObject).realValue()) * 10));
        end;
        end;
    end;
    TranslatorTreeBuilder.EXPR_VALUE_XVECTOR: begin
        reg1 := stack.allocateXMM(XPFLOAT, g);
        sr1 := g.registerToString(reg1);
        g.writeInstruction('movups', sr1, g.memoryToString(MNONE,
                LABEL_POOL_XVECTOR_CONTENT, programmeXVectors.indexAcquire(
                (nodeAsoc as XVectorAsObject).xvectorValue()) * 16));
    end;
    TranslatorTreeBuilder.EXPR_VALUE_STRING: begin
        reg1 := stack.allocateGPR64bit(g);
        sr1 := g.registerToString(reg1);
        g.writeInstruction('lea', sr1, g.memoryToString(MNONE,
                LABEL_POOL_STRING_CONTENT, programmeStrings.indexAcquire(
                (nodeAsoc as UnicodeStringAsObject).unicodeStringValue()) * 16));
    end;
    TranslatorTreeBuilder.EXPR_GLOBAL_FUNCTION: begin
        reg1 := stack.allocateGPR64bit(g);
        sr1 := g.registerToString(reg1);
        g.writeInstruction('lea', sr1, g.memoryToString(MNONE,
                getEntryFullName(nodeAsoc as GlobalFunction), 0));
    end;
    TranslatorTreeBuilder.EXPR_GLOBAL_VARIABLE,
    TranslatorTreeBuilder.EXPR_LOCAL_VARIABLE,
    TranslatorTreeBuilder.EXPR_ARRAY,
    TranslatorTreeBuilder.EXPR_FIELD: begin
        mem := getMemoryLocation(node, stack, false);
        smm := mem.memoryToString(MNONE, 0);
        smmb := mem.memoryToString(MBYTE, 0);
        smmw := mem.memoryToString(MWORD, 0);
        smmt := mem.memoryToString(MREAL, 0);
        case nodeType.kind of
        TranslatorType.KIND_BOOLEAN: begin
            if (goIfTrueTo <> nil) and (goIfFalseTo <> nil) then begin
                g.writeInstruction('movzx', sR1I, smmb);
                g.writeInstruction('test', sR1I, sR1I);
                stack.restoreRegs(g); { регистр флагов – без изменений }
                if goIfTrueTo.labelNumber = nodeLN + 1 then begin
                    g.writeInstruction('jz',
                            LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                end else
                if goIfFalseTo.labelNumber = nodeLN + 1 then begin
                    g.writeInstruction('jnz',
                            LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
                end else begin
                    g.writeInstruction('jz',
                            LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                    g.writeInstruction('jmp',
                            LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
                end;
            end else begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movzx', sr1, smmb);
                stack.restoreRegs(g);
            end;
        end;
        TranslatorType.KIND_CHAR: begin
            reg1 := stack.allocateGPR32bit(g);
            sr1 := g.registerToString(reg1);
            g.writeInstruction('movzx', sr1, smmw);
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_BYTE: begin
            reg1 := stack.allocateGPR32bit(g);
            sr1 := g.registerToString(reg1);
            g.writeInstruction('movsx', sr1, smmb);
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_SHORT: begin
            reg1 := stack.allocateGPR32bit(g);
            sr1 := g.registerToString(reg1);
            g.writeInstruction('movsx', sr1, smmw);
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_INT: begin
            reg1 := stack.allocateGPR32bit(g);
            sr1 := g.registerToString(reg1);
            g.writeInstruction('mov', sr1, smm);
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_STRUCT, TranslatorType.KIND_ARRAY,
        TranslatorType.KIND_FUNC, TranslatorType.KIND_LONG: begin
            reg1 := stack.allocateGPR64bit(g);
            sr1 := g.registerToString(reg1);
            g.writeInstruction('mov', sr1, smm);
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_ULTRA: begin
            reg1 := stack.allocateXMM(XPINT, g);
            sr1 := g.registerToString(reg1);
            g.writeInstruction('movdqu', sr1, smm);
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_FLOAT: begin
            reg1 := stack.allocateXMM(XSFLOAT, g);
            sr1 := g.registerToString(reg1);
            g.writeInstruction('movss', sr1, smm);
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_DOUBLE: begin
            reg1 := stack.allocateXMM(XSDOUBLE, g);
            sr1 := g.registerToString(reg1);
            g.writeInstruction('movsd', sr1, smm);
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_REAL: begin
            stack.allocateFPU(1, g);
            g.writeInstruction('fld', smmt);
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_XVECTOR: begin
            reg1 := stack.allocateXMM(XPFLOAT, g);
            sr1 := g.registerToString(reg1);
            g.writeInstruction('movups', sr1, smm);
            stack.restoreRegs(g);
        end;
        end;
    end;
    TranslatorTreeBuilder.EXPR_NEW_STRUCT: begin
        stack.storeRegs(stack.base(), g);
        buffer := (nodeType as TypeStructure).structureSize;
        g.writeInstruction('pushq', g.immediateToString(buffer));
        g.writeInstruction('call', FUNCTION_NEW_STRUCT);
        reg1 := stack.allocateGPR64bit(g);
        if reg1 <> R0 then begin
            sr1 := g.registerToString(reg1);
            g.writeInstruction('mov', sr1, sR0L);
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_NEW_ARRAY_BY_ELEMENTS: begin
        stack.storeRegs(stack.base(), g);
        count := node.getChildrensCount();
        buffer := (nodeType as TypeArray).elementType.size;
        g.writeInstruction('pushq', g.immediateToString(count));
        g.writeInstruction('pushq', g.immediateToString(buffer));
        g.writeInstruction('call', FUNCTION_NEW_ARRAY);
        reg1 := stack.allocateGPR64bit(g);
        if reg1 <> R0 then begin
            sr1 := g.registerToString(reg1);
            g.writeInstruction('mov', sr1, sR0L);
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_NEW_ARRAY_BY_LENGTH: begin
        stack.storeRegs(stack.base(), g);
        stack.popRegs(1);
        buffer := (nodeType as TypeArray).elementType.size;
        g.writeInstruction('pushq', g.immediateToString(buffer));
        g.writeInstruction('call', FUNCTION_NEW_ARRAY);
        reg1 := stack.allocateGPR64bit(g);
        if reg1 <> R0 then begin
            sr1 := g.registerToString(reg1);
            g.writeInstruction('mov', sr1, sR0L);
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_NEW_ULTRA: begin
        g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -$10));
        reg1 := stack.getRegAt(3);
        g.writeInstruction('mov', g.memoryToString(MNONE, RSP, $00), g.registerToString(reg1));
        reg1 := stack.getRegAt(2);
        g.writeInstruction('mov', g.memoryToString(MNONE, RSP, $04), g.registerToString(reg1));
        reg1 := stack.getRegAt(1);
        g.writeInstruction('mov', g.memoryToString(MNONE, RSP, $08), g.registerToString(reg1));
        reg1 := stack.getRegAt(0);
        g.writeInstruction('mov', g.memoryToString(MNONE, RSP, $0c), g.registerToString(reg1));
        stack.popRegs(4);
        reg1 := stack.allocateXMM(XPINT, g);
        sr1 := g.registerToString(reg1);
        g.writeInstruction('movdqu', sr1, g.memoryToString(MNONE, RSP, 0));
        g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, $10));
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_NEW_XVECTOR: begin
        g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -$10));
        reg1 := stack.getRegAt(3);
        g.writeInstruction('movss', g.memoryToString(MNONE, RSP, $00), g.registerToString(reg1));
        reg1 := stack.getRegAt(2);
        g.writeInstruction('movss', g.memoryToString(MNONE, RSP, $04), g.registerToString(reg1));
        reg1 := stack.getRegAt(1);
        g.writeInstruction('movss', g.memoryToString(MNONE, RSP, $08), g.registerToString(reg1));
        reg1 := stack.getRegAt(0);
        g.writeInstruction('movss', g.memoryToString(MNONE, RSP, $0c), g.registerToString(reg1));
        stack.popRegs(4);
        reg1 := stack.allocateXMM(XPFLOAT, g);
        sr1 := g.registerToString(reg1);
        g.writeInstruction('movups', sr1, g.memoryToString(MNONE, RSP, 0));
        g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, $10));
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_FIELD_ASSIGN: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr2 := g.registerToString(reg2);
        mem := MemoryLocationTfasm.create(g, reg2, reg1,
                getFieldFullName(nodeAsoc as StructureField));
        smm := mem.memoryToString(MNONE, 0);
        smmt := mem.memoryToString(MREAL, 0);
        stack.popRegs(1);
        case nodeType.kind of
        TranslatorType.KIND_BOOLEAN, TranslatorType.KIND_BYTE: begin
            sr2 := g.registerToString(R0B + (reg2 and $0f));
            g.writeInstruction('mov', smm, sr2);
        end;
        TranslatorType.KIND_CHAR, TranslatorType.KIND_SHORT: begin
            sr2 := g.registerToString(R0W + (reg2 and $0f));
            g.writeInstruction('mov', smm, sr2);
        end;
        TranslatorType.KIND_STRUCT, TranslatorType.KIND_ARRAY, TranslatorType.KIND_FUNC,
        TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
            g.writeInstruction('mov', smm, sr2);
        TranslatorType.KIND_ULTRA:
            g.writeInstruction('movdqu', smm, sr2);
        TranslatorType.KIND_FLOAT:
            g.writeInstruction('movss', smm, sr2);
        TranslatorType.KIND_DOUBLE:
            g.writeInstruction('movsd', smm, sr2);
        TranslatorType.KIND_REAL:
            g.writeInstruction('fstp', smmt);
        TranslatorType.KIND_XVECTOR:
            g.writeInstruction('movups', smm, sr2);
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_ARRAY_ASSIGN: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        g.writeInstruction('mov', sR1L, sr1);
        if nodeIndex = 0 then begin
            g.writeInstruction('xor', sR2I, sR2I);
        end else begin
            g.writeInstruction('mov', sR2I, g.immediateToStringInt(nodeIndex));
        end;
        g.writeInstruction('call', FUNCTION_CHECK_ARRAY_INDEX);
        case nodeType.kind of
        TranslatorType.KIND_BOOLEAN, TranslatorType.KIND_BYTE: begin
            sr2 := g.registerToString(R0B + (reg2 and $0f));
            mem := MemoryLocationTfasm.create(g, reg2, R1, R2, 1, '');
            smm := mem.memoryToString(MNONE, 0);
            g.writeInstruction('mov', smm, sr2);
        end;
        TranslatorType.KIND_CHAR, TranslatorType.KIND_SHORT: begin
            sr2 := g.registerToString(R0W + (reg2 and $0f));
            mem := MemoryLocationTfasm.create(g, reg2, R1, R2, 2, '');
            smm := mem.memoryToString(MNONE, 0);
            g.writeInstruction('mov', smm, sr2);
        end;
        TranslatorType.KIND_INT: begin
            mem := MemoryLocationTfasm.create(g, reg2, R1, R2, 4, '');
            smm := mem.memoryToString(MNONE, 0);
            g.writeInstruction('mov', smm, sr2);
        end;
        TranslatorType.KIND_STRUCT, TranslatorType.KIND_ARRAY,
        TranslatorType.KIND_FUNC, TranslatorType.KIND_LONG: begin
            mem := MemoryLocationTfasm.create(g, reg2, R1, R2, 8, '');
            smm := mem.memoryToString(MNONE, 0);
            g.writeInstruction('mov', smm, sr2);
        end;
        TranslatorType.KIND_ULTRA: begin
            mem := MemoryLocationTfasm.create(g, reg2, R1, R2, 8, '');
            smm := mem.memoryToString(MNONE, 0);
            g.writeInstruction('shl', sR2L, g.immediateToString(1));
            g.writeInstruction('movdqu', smm, sr2);
        end;
        TranslatorType.KIND_FLOAT: begin
            mem := MemoryLocationTfasm.create(g, reg2, R1, R2, 4, '');
            smm := mem.memoryToString(MNONE, 0);
            g.writeInstruction('movss', smm, sr2);
        end;
        TranslatorType.KIND_DOUBLE: begin
            mem := MemoryLocationTfasm.create(g, reg2, R1, R2, 8, '');
            smm := mem.memoryToString(MNONE, 0);
            g.writeInstruction('movsd', smm, sr2);
        end;
        TranslatorType.KIND_REAL: begin
            mem := MemoryLocationTfasm.create(g, reg2, R1, R2, '');
            smmt := mem.memoryToString(MREAL, 0);
            g.writeInstruction('imul', sR2L, sR2L, g.immediateToString(10));
            g.writeInstruction('fstp', smmt);
        end;
        TranslatorType.KIND_XVECTOR: begin
            mem := MemoryLocationTfasm.create(g, reg2, R1, R2, 8, '');
            smm := mem.memoryToString(MNONE, 0);
            g.writeInstruction('shl', sR2L, g.immediateToString(1));
            g.writeInstruction('movups', smm, sr2);
        end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_CALL: begin
        funcNode := node.getChild(node.getChildrensCount() - 1) as SyntaxNode;
        funcType := funcNode.dataType as TypeFunction;
        funcReturn := funcType.getReturnType();
        if funcNode.value = TranslatorTreeBuilder.EXPR_GLOBAL_FUNCTION then begin
            stack.storeRegs(stack.base(), g);
            g.writeInstruction('call', getEntryFullName(funcNode.associate as GlobalFunction));
        end else begin
            reg1 := stack.getRegAt(0);
            sr1 := g.registerToString(reg1);
            stack.popRegs(1);
            stack.storeRegs(stack.base(), g);
            g.writeInstruction('call', sr1);
        end;
        stack.popRegs(funcType.getArgumentsCount());
        case TranslatorTreeBuilder.getTypeKind(nodeType) of
        TranslatorType.KIND_BOOLEAN: begin
            if (goIfTrueTo <> nil) and (goIfFalseTo <> nil) then begin
                g.writeInstruction('test', sR0I, sR0I);
                stack.restoreRegs(g); { регистр флагов – без изменений }
                if goIfTrueTo.labelNumber = nodeLN + 1 then begin
                    g.writeInstruction('jz',
                            LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                end else
                if goIfFalseTo.labelNumber = nodeLN + 1 then begin
                    g.writeInstruction('jnz',
                            LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
                end else begin
                    g.writeInstruction('jz',
                            LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                    g.writeInstruction('jmp',
                            LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
                end;
            end else begin
                reg1 := stack.allocateGPR32bit(g);
                if reg1 <> R0D then begin
                    sr1 := g.registerToString(reg1);
                    g.writeInstruction('mov', sr1, sR0I);
                end;
                stack.restoreRegs(g);
            end;
        end;
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
        TranslatorType.KIND_SHORT, TranslatorType.KIND_INT: begin
            reg1 := stack.allocateGPR32bit(g);
            if reg1 <> R0D then begin
                sr1 := g.registerToString(reg1);
                g.writeInstruction('mov', sr1, sR0I);
            end;
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_LONG, TranslatorType.KIND_STRUCT,
        TranslatorType.KIND_ARRAY, TranslatorType.KIND_FUNC: begin
            reg1 := stack.allocateGPR64bit(g);
            if reg1 <> R0 then begin
                sr1 := g.registerToString(reg1);
                g.writeInstruction('mov', sr1, sR0L);
            end;
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_ULTRA: begin
            reg1 := stack.allocateXMM(XPINT, g);
            if reg1 <> XMM0 + XPINT then begin
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movdqu', sr1, sXMM0);
            end;
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_FLOAT: begin
            reg1 := stack.allocateXMM(XSFLOAT, g);
            if reg1 <> XMM0 + XSFLOAT then begin
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movss', sr1, sXMM0);
            end;
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_DOUBLE: begin
            reg1 := stack.allocateXMM(XSDOUBLE, g);
            if reg1 <> XMM0 + XSDOUBLE then begin
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movsd', sr1, sXMM0);
            end;
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_REAL: begin
            stack.allocateFPU(1, g);
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_XVECTOR: begin
            reg1 := stack.allocateXMM(XPFLOAT, g);
            if reg1 <> XMM0 + XPFLOAT then begin
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movups', sr1, sXMM0);
            end;
            stack.restoreRegs(g);
        end;
        else
            if (nodeType = nil) and (funcReturn <> nil) and
                    (funcReturn.kind = TranslatorType.KIND_REAL) then begin
                g.writeInstruction('ffree', sST0);
                g.writeInstruction('fincstp');
            end;
            stack.restoreRegs(g);
        end;
    end;
    TranslatorTreeBuilder.EXPR_COMPOUND: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(2);
        case (node.getChild(0) as SyntaxNode).dataType.kind of
        TranslatorType.KIND_ULTRA: begin
            g.writeInstruction('movdqu', sXMM12, sr1);
            g.writeInstruction('mov', sR1I, sr2);
            g.writeInstruction('call', FUNCTION_ULTRA_EXTRACT);
            reg1 := stack.allocateGPR32bit(g);
            sr1 := g.registerToString(reg1);
            g.writeInstruction('mov', sr1, sR1I);
        end;
        TranslatorType.KIND_XVECTOR: begin
            g.writeInstruction('movups', sXMM12, sr1);
            g.writeInstruction('mov', sR1I, sr2);
            g.writeInstruction('call', FUNCTION_XVECTOR_EXTRACT);
            reg1 := stack.allocateXMM(XSFLOAT, g);
            sr1 := g.registerToString(reg1);
            g.writeInstruction('movss', sr1, sXMM12);
        end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_INCR_POST,
    TranslatorTreeBuilder.EXPR_DECR_POST,
    TranslatorTreeBuilder.EXPR_INCR_PRED,
    TranslatorTreeBuilder.EXPR_DECR_PRED: begin
        regInUse := (nodeValue = TranslatorTreeBuilder.EXPR_INCR_POST) or
                (nodeValue = TranslatorTreeBuilder.EXPR_DECR_POST);
        child := node.getChild(0) as SyntaxNode;
        mem := getMemoryLocation(child, stack, false);
        smm := mem.memoryToString(MNONE, 0);
        smmb := mem.memoryToString(MBYTE, 0);
        smmw := mem.memoryToString(MWORD, 0);
        smmd := mem.memoryToString(MDWORD, 0);
        smmq := mem.memoryToString(MQWORD, 0);
        smmt := mem.memoryToString(MREAL, 0);
        case child.dataType.kind of
        TranslatorType.KIND_CHAR: begin
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                if regInUse then begin
                    g.writeInstruction('movzx', sR3I, smmw);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_POST:
                        g.writeInstruction('inc', smmw);
                    TranslatorTreeBuilder.EXPR_DECR_POST:
                        g.writeInstruction('dec', smmw);
                    end;
                    g.writeInstruction('mov', sr1, sR3I);
                end else begin
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_PRED:
                        g.writeInstruction('inc', smmw);
                    TranslatorTreeBuilder.EXPR_DECR_PRED:
                        g.writeInstruction('dec', smmw);
                    end;
                    g.writeInstruction('movzx', sr1, smmw);
                end;
            end else begin
                case nodeValue of
                TranslatorTreeBuilder.EXPR_INCR_POST,
                TranslatorTreeBuilder.EXPR_INCR_PRED:
                    g.writeInstruction('inc', smmw);
                TranslatorTreeBuilder.EXPR_DECR_POST,
                TranslatorTreeBuilder.EXPR_DECR_PRED:
                    g.writeInstruction('dec', smmw);
                end;
            end;
        end;
        TranslatorType.KIND_BYTE: begin
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                if regInUse then begin
                    g.writeInstruction('movsx', sR3I, smmb);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_POST:
                        g.writeInstruction('inc', smmb);
                    TranslatorTreeBuilder.EXPR_DECR_POST:
                        g.writeInstruction('dec', smmb);
                    end;
                    g.writeInstruction('mov', sr1, sR3I);
                end else begin
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_PRED:
                        g.writeInstruction('inc', smmb);
                    TranslatorTreeBuilder.EXPR_DECR_PRED:
                        g.writeInstruction('dec', smmb);
                    end;
                    g.writeInstruction('movsx', sr1, smmb);
                end;
            end else begin
                case nodeValue of
                TranslatorTreeBuilder.EXPR_INCR_POST,
                TranslatorTreeBuilder.EXPR_INCR_PRED:
                    g.writeInstruction('inc', smmb);
                TranslatorTreeBuilder.EXPR_DECR_POST,
                TranslatorTreeBuilder.EXPR_DECR_PRED:
                    g.writeInstruction('dec', smmb);
                end;
            end;
        end;
        TranslatorType.KIND_SHORT: begin
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                if regInUse then begin
                    g.writeInstruction('movsx', sR3I, smmw);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_POST:
                        g.writeInstruction('inc', smmw);
                    TranslatorTreeBuilder.EXPR_DECR_POST:
                        g.writeInstruction('dec', smmw);
                    end;
                    g.writeInstruction('mov', sr1, sR3I);
                end else begin
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_PRED:
                        g.writeInstruction('inc', smmw);
                    TranslatorTreeBuilder.EXPR_DECR_PRED:
                        g.writeInstruction('dec', smmw);
                    end;
                    g.writeInstruction('movsx', sr1, smmw);
                end;
            end else begin
                case nodeValue of
                TranslatorTreeBuilder.EXPR_INCR_POST,
                TranslatorTreeBuilder.EXPR_INCR_PRED:
                    g.writeInstruction('inc', smmw);
                TranslatorTreeBuilder.EXPR_DECR_POST,
                TranslatorTreeBuilder.EXPR_DECR_PRED:
                    g.writeInstruction('dec', smmw);
                end;
            end;
        end;
        TranslatorType.KIND_INT: begin
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                if regInUse then begin
                    g.writeInstruction('mov', sR3I, smm);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_POST:
                        g.writeInstruction('inc', smmd);
                    TranslatorTreeBuilder.EXPR_DECR_POST:
                        g.writeInstruction('dec', smmd);
                    end;
                    g.writeInstruction('mov', sr1, sR3I);
                end else begin
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_PRED:
                        g.writeInstruction('inc', smmd);
                    TranslatorTreeBuilder.EXPR_DECR_PRED:
                        g.writeInstruction('dec', smmd);
                    end;
                    g.writeInstruction('mov', sr1, smm);
                end;
            end else begin
                case nodeValue of
                TranslatorTreeBuilder.EXPR_INCR_POST,
                TranslatorTreeBuilder.EXPR_INCR_PRED:
                    g.writeInstruction('inc', smmd);
                TranslatorTreeBuilder.EXPR_DECR_POST,
                TranslatorTreeBuilder.EXPR_DECR_PRED:
                    g.writeInstruction('dec', smmd);
                end;
            end;
        end;
        TranslatorType.KIND_LONG: begin
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR64bit(g);
                sr1 := g.registerToString(reg1);
                if regInUse then begin
                    g.writeInstruction('mov', sR3L, smm);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_POST:
                        g.writeInstruction('inc', smmq);
                    TranslatorTreeBuilder.EXPR_DECR_POST:
                        g.writeInstruction('dec', smmq);
                    end;
                    g.writeInstruction('mov', sr1, sR3L);
                end else begin
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_PRED:
                        g.writeInstruction('inc', smmq);
                    TranslatorTreeBuilder.EXPR_DECR_PRED:
                        g.writeInstruction('dec', smmq);
                    end;
                    g.writeInstruction('mov', sr1, smm);
                end;
            end else begin
                case nodeValue of
                TranslatorTreeBuilder.EXPR_INCR_POST,
                TranslatorTreeBuilder.EXPR_INCR_PRED:
                    g.writeInstruction('inc', smmq);
                TranslatorTreeBuilder.EXPR_DECR_POST,
                TranslatorTreeBuilder.EXPR_DECR_PRED:
                    g.writeInstruction('dec', smmq);
                end;
            end;
        end;
        TranslatorType.KIND_FLOAT: begin
            if nodeType <> nil then begin
                reg1 := stack.allocateXMM(XSFLOAT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movss', sr1, smm);
                if regInUse then begin
                    g.writeInstruction('movss', sXMM12, sr1);
                    g.writeInstruction('movss', sXMM13, g.memoryToString(MNONE,
                            LABEL_POOL_FLOAT_CONTENT, programmeFloats.indexAcquire(1) * 4));
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_POST:
                        g.writeInstruction('addss', sXMM12, sXMM13);
                    TranslatorTreeBuilder.EXPR_DECR_POST:
                        g.writeInstruction('subss', sXMM12, sXMM13);
                    end;
                    g.writeInstruction('movss', smm, sXMM12);
                end else begin
                    g.writeInstruction('movss', sXMM12, g.memoryToString(MNONE,
                            LABEL_POOL_FLOAT_CONTENT, programmeFloats.indexAcquire(1) * 4));
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_PRED:
                        g.writeInstruction('addss', sr1, sXMM12);
                    TranslatorTreeBuilder.EXPR_DECR_PRED:
                        g.writeInstruction('subss', sr1, sXMM12);
                    end;
                    g.writeInstruction('movss', smm, sr1);
                end;
            end else begin
                g.writeInstruction('movss', sXMM12, smm);
                g.writeInstruction('movss', sXMM13, g.memoryToString(MNONE,
                        LABEL_POOL_FLOAT_CONTENT, programmeFloats.indexAcquire(1) * 4));
                case nodeValue of
                TranslatorTreeBuilder.EXPR_INCR_POST,
                TranslatorTreeBuilder.EXPR_INCR_PRED:
                    g.writeInstruction('addss', sXMM12, sXMM13);
                TranslatorTreeBuilder.EXPR_DECR_POST,
                TranslatorTreeBuilder.EXPR_DECR_PRED:
                    g.writeInstruction('subss', sXMM12, sXMM13);
                end;
                g.writeInstruction('movss', smm, sXMM12);
            end;
        end;
        TranslatorType.KIND_DOUBLE: begin
            if nodeType <> nil then begin
                reg1 := stack.allocateXMM(XSDOUBLE, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movsd', sr1, smm);
                if regInUse then begin
                    g.writeInstruction('movsd', sXMM12, sr1);
                    g.writeInstruction('movsd', sXMM13, g.memoryToString(MNONE,
                            LABEL_POOL_DOUBLE_CONTENT, programmeDoubles.indexAcquire(1) * 8));
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_POST:
                        g.writeInstruction('addsd', sXMM12, sXMM13);
                    TranslatorTreeBuilder.EXPR_DECR_POST:
                        g.writeInstruction('subsd', sXMM12, sXMM13);
                    end;
                    g.writeInstruction('movsd', smm, sXMM12);
                end else begin
                    g.writeInstruction('movsd', sXMM12, g.memoryToString(MNONE,
                            LABEL_POOL_DOUBLE_CONTENT, programmeDoubles.indexAcquire(1) * 8));
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_PRED:
                        g.writeInstruction('addsd', sr1, sXMM12);
                    TranslatorTreeBuilder.EXPR_DECR_PRED:
                        g.writeInstruction('subsd', sr1, sXMM12);
                    end;
                    g.writeInstruction('movsd', smm, sr1);
                end;
            end else begin
                g.writeInstruction('movsd', sXMM12, smm);
                g.writeInstruction('movsd', sXMM13, g.memoryToString(MNONE,
                        LABEL_POOL_DOUBLE_CONTENT, programmeDoubles.indexAcquire(1) * 8));
                case nodeValue of
                TranslatorTreeBuilder.EXPR_INCR_POST,
                TranslatorTreeBuilder.EXPR_INCR_PRED:
                    g.writeInstruction('addsd', sXMM12, sXMM13);
                TranslatorTreeBuilder.EXPR_DECR_POST,
                TranslatorTreeBuilder.EXPR_DECR_PRED:
                    g.writeInstruction('subsd', sXMM12, sXMM13);
                end;
                g.writeInstruction('movsd', smm, sXMM12);
            end;
        end;
        TranslatorType.KIND_REAL: begin
            if nodeType <> nil then begin
                if regInUse then begin
                    stack.allocateFPU(2, g);
                    stack.popRegs(1);
                    g.writeInstruction('fld', smmt);
                    g.writeInstruction('fld', sST0);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_POST:
                        g.writeInstruction('fadd', g.memoryToString(MFLOAT,
                                LABEL_POOL_FLOAT_CONTENT, programmeFloats.indexAcquire(1) * 4));
                    TranslatorTreeBuilder.EXPR_DECR_POST:
                        g.writeInstruction('fsub', g.memoryToString(MFLOAT,
                                LABEL_POOL_FLOAT_CONTENT, programmeFloats.indexAcquire(1) * 4));
                    end;
                    g.writeInstruction('fstp', smmt);
                end else begin
                    stack.allocateFPU(1, g);
                    g.writeInstruction('fld', smmt);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_INCR_PRED:
                        g.writeInstruction('fadd', g.memoryToString(MFLOAT,
                                LABEL_POOL_FLOAT_CONTENT, programmeFloats.indexAcquire(1) * 4));
                    TranslatorTreeBuilder.EXPR_DECR_PRED:
                        g.writeInstruction('fsub', g.memoryToString(MFLOAT,
                                LABEL_POOL_FLOAT_CONTENT, programmeFloats.indexAcquire(1) * 4));
                    end;
                    g.writeInstruction('fstp', smmt);
                    g.writeInstruction('fld', smmt);
                end;
            end else begin
                stack.allocateFPU(1, g);
                stack.popRegs(1);
                g.writeInstruction('fld', smmt);
                case nodeValue of
                TranslatorTreeBuilder.EXPR_INCR_POST,
                TranslatorTreeBuilder.EXPR_INCR_PRED:
                    g.writeInstruction('fadd', g.memoryToString(MFLOAT,
                            LABEL_POOL_FLOAT_CONTENT, programmeFloats.indexAcquire(1) * 4));
                TranslatorTreeBuilder.EXPR_DECR_POST,
                TranslatorTreeBuilder.EXPR_DECR_PRED:
                    g.writeInstruction('fsub', g.memoryToString(MFLOAT,
                            LABEL_POOL_FLOAT_CONTENT, programmeFloats.indexAcquire(1) * 4));
                end;
                g.writeInstruction('fstp', smmt);
            end;
        end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_TYPE_CAST: begin
        reg2 := stack.getRegAt(0);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        case (node.getChild(0) as SyntaxNode).dataType.kind of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
        TranslatorType.KIND_INT: {%region исходный тип данных – int}
            case nodeType.kind of
            TranslatorType.KIND_CHAR: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                srw := g.registerToString(R0W + (reg2 and $0f));
                g.writeInstruction('movzx', sr1, srw);
            end;
            TranslatorType.KIND_BYTE: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                srb := g.registerToString(R0B + (reg2 and $0f));
                g.writeInstruction('movsx', sr1, srb);
            end;
            TranslatorType.KIND_SHORT: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                srw := g.registerToString(R0W + (reg2 and $0f));
                g.writeInstruction('movsx', sr1, srw);
            end;
            TranslatorType.KIND_LONG: begin
                reg1 := stack.allocateGPR64bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movsxd', sr1, sr2);
            end;
            TranslatorType.KIND_ULTRA: begin
                reg1 := stack.allocateXMM(XPINT, g);
                sr1 := g.registerToString(reg1);
                srq := g.registerToString(R0 + (reg2 and $0f));
                g.writeInstruction('movsxd', srq, sr2);
                g.writeInstruction('movq', sr1, srq);
            end;
            TranslatorType.KIND_FLOAT: begin
                reg1 := stack.allocateXMM(XSFLOAT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('cvtsi2ss', sr1, sr2);
            end;
            TranslatorType.KIND_DOUBLE: begin
                reg1 := stack.allocateXMM(XSDOUBLE, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('cvtsi2sd', sr1, sr2);
            end;
            TranslatorType.KIND_REAL: begin
                stack.allocateFPU(1, g);
                srq := g.registerToString(R0 + (reg2 and $0f));
                g.writeInstruction('push', srq);
                g.writeInstruction('fild', g.memoryToString(MINT, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, 8));
            end;
            TranslatorType.KIND_XVECTOR: begin
                reg1 := stack.allocateXMM(XPFLOAT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('pxor', sr1, sr1);
                g.writeInstruction('cvtsi2ss', sr1, sr2);
            end;
            end;
        {%endregion}
        TranslatorType.KIND_LONG: {%region исходный тип данных – long}
            case nodeType.kind of
            TranslatorType.KIND_CHAR: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                srw := g.registerToString(R0W + (reg2 and $0f));
                g.writeInstruction('movzx', sr1, srw);
            end;
            TranslatorType.KIND_BYTE: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                srb := g.registerToString(R0B + (reg2 and $0f));
                g.writeInstruction('movsx', sr1, srb);
            end;
            TranslatorType.KIND_SHORT: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                srw := g.registerToString(R0W + (reg2 and $0f));
                g.writeInstruction('movsx', sr1, srw);
            end;
            TranslatorType.KIND_INT: begin
                reg1 := stack.allocateGPR32bit(g);
                if (reg1 and $0f) <> (reg2 and $0f) then begin
                    sr1 := g.registerToString(reg1);
                    srd := g.registerToString(R0D + (reg2 and $0f));
                    g.writeInstruction('mov', sr1, srd);
                end;
            end;
            TranslatorType.KIND_ULTRA: begin
                reg1 := stack.allocateXMM(XPINT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movq', sr1, sr2);
            end;
            TranslatorType.KIND_FLOAT: begin
                reg1 := stack.allocateXMM(XSFLOAT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('cvtsi2ss', sr1, sr2);
            end;
            TranslatorType.KIND_DOUBLE: begin
                reg1 := stack.allocateXMM(XSDOUBLE, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('cvtsi2sd', sr1, sr2);
            end;
            TranslatorType.KIND_REAL: begin
                stack.allocateFPU(1, g);
                g.writeInstruction('push', sr2);
                g.writeInstruction('fild', g.memoryToString(MLONG, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, 8));
            end;
            TranslatorType.KIND_XVECTOR: begin
                reg1 := stack.allocateXMM(XPFLOAT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('pxor', sr1, sr1);
                g.writeInstruction('cvtsi2ss', sr1, sr2);
            end;
            end;
        {%endregion}
        TranslatorType.KIND_ULTRA: {%region исходный тип данных – ultra}
            case nodeType.kind of
            TranslatorType.KIND_CHAR: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                srw := g.registerToString(R0W + (reg1 and $0f));
                g.writeInstruction('movd', sr1, sr2);
                g.writeInstruction('movzx', sr1, srw);
            end;
            TranslatorType.KIND_BYTE: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                srb := g.registerToString(R0B + (reg1 and $0f));
                g.writeInstruction('movd', sr1, sr2);
                g.writeInstruction('movsx', sr1, srb);
            end;
            TranslatorType.KIND_SHORT: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                srw := g.registerToString(R0W + (reg1 and $0f));
                g.writeInstruction('movd', sr1, sr2);
                g.writeInstruction('movsx', sr1, srw);
            end;
            TranslatorType.KIND_INT: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movd', sr1, sr2);
            end;
            TranslatorType.KIND_LONG: begin
                reg1 := stack.allocateGPR64bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movq', sr1, sr2);
            end;
            TranslatorType.KIND_FLOAT: begin
                reg1 := stack.allocateXMM(XSFLOAT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movq', sR1L, sr2);
                g.writeInstruction('cvtsi2ss', sr1, sR1L);
            end;
            TranslatorType.KIND_DOUBLE: begin
                reg1 := stack.allocateXMM(XSDOUBLE, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movq', sR1L, sr2);
                g.writeInstruction('cvtsi2sd', sr1, sR1L);
            end;
            TranslatorType.KIND_REAL: begin
                stack.allocateFPU(1, g);
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -8));
                g.writeInstruction('movq', g.memoryToString(MNONE, RSP, 0), sr2);
                g.writeInstruction('fild', g.memoryToString(MLONG, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, 8));
            end;
            TranslatorType.KIND_XVECTOR: begin
                reg1 := stack.allocateXMM(XPFLOAT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('cvtdq2ps', sr1, sr2);
            end;
            end;
        {%endregion}
        TranslatorType.KIND_FLOAT: {%region исходный тип данных – float}
            case nodeType.kind of
            TranslatorType.KIND_CHAR: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movss', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_FLOAT_TO_INT);
                g.writeInstruction('movzx', sr1, sR2S);
            end;
            TranslatorType.KIND_BYTE: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movss', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_FLOAT_TO_INT);
                g.writeInstruction('movsx', sr1, sR2B);
            end;
            TranslatorType.KIND_SHORT: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movss', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_FLOAT_TO_INT);
                g.writeInstruction('movsx', sr1, sR2S);
            end;
            TranslatorType.KIND_INT: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movss', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_FLOAT_TO_INT);
                g.writeInstruction('mov', sr1, sR2I);
            end;
            TranslatorType.KIND_LONG: begin
                reg1 := stack.allocateGPR64bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movss', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_FLOAT_TO_LONG);
                g.writeInstruction('mov', sr1, sR2L);
            end;
            TranslatorType.KIND_ULTRA: begin
                reg1 := stack.allocateXMM(XPINT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movss', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_FLOAT_TO_LONG);
                g.writeInstruction('movq', sr1, sR2L);
            end;
            TranslatorType.KIND_DOUBLE: begin
                reg1 := stack.allocateXMM(XSDOUBLE, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('cvtss2sd', sr1, sr2);
            end;
            TranslatorType.KIND_REAL: begin
                stack.allocateFPU(1, g);
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -8));
                g.writeInstruction('movss', g.memoryToString(MNONE, RSP, 0), sr2);
                g.writeInstruction('fld', g.memoryToString(MFLOAT, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, 8));
            end;
            TranslatorType.KIND_XVECTOR: begin
                reg1 := stack.allocateXMM(XPFLOAT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -8));
                g.writeInstruction('movss', g.memoryToString(MNONE, RSP, 0), sr2);
                g.writeInstruction('movss', sr1, g.memoryToString(MNONE, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, 8));
            end;
            end;
        {%endregion}
        TranslatorType.KIND_DOUBLE: {%region исходный тип данных – double}
            case nodeType.kind of
            TranslatorType.KIND_CHAR: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movsd', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_DOUBLE_TO_INT);
                g.writeInstruction('movzx', sr1, sR2S);
            end;
            TranslatorType.KIND_BYTE: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movsd', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_DOUBLE_TO_INT);
                g.writeInstruction('movsx', sr1, sR2B);
            end;
            TranslatorType.KIND_SHORT: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movsd', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_DOUBLE_TO_INT);
                g.writeInstruction('movsx', sr1, sR2S);
            end;
            TranslatorType.KIND_INT: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movsd', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_DOUBLE_TO_INT);
                g.writeInstruction('mov', sr1, sR2I);
            end;
            TranslatorType.KIND_LONG: begin
                reg1 := stack.allocateGPR64bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movsd', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_DOUBLE_TO_LONG);
                g.writeInstruction('mov', sr1, sR2L);
            end;
            TranslatorType.KIND_ULTRA: begin
                reg1 := stack.allocateXMM(XPINT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movsd', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_DOUBLE_TO_LONG);
                g.writeInstruction('movq', sr1, sR2L);
            end;
            TranslatorType.KIND_FLOAT: begin
                reg1 := stack.allocateXMM(XSFLOAT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('cvtsd2ss', sr1, sr2);
            end;
            TranslatorType.KIND_REAL: begin
                stack.allocateFPU(1, g);
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -8));
                g.writeInstruction('movsd', g.memoryToString(MNONE, RSP, 0), sr2);
                g.writeInstruction('fld', g.memoryToString(MDOUBLE, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, 8));
            end;
            TranslatorType.KIND_XVECTOR: begin
                reg1 := stack.allocateXMM(XPFLOAT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('cvtsd2ss', sr2, sr2);
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -8));
                g.writeInstruction('movss', g.memoryToString(MNONE, RSP, 0), sr2);
                g.writeInstruction('movss', sr1, g.memoryToString(MNONE, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, 8));
            end;
            end;
        {%endregion}
        TranslatorType.KIND_REAL: {%region исходный тип данных – real}
            case nodeType.kind of
            TranslatorType.KIND_CHAR: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('call', FUNCTION_REAL_TO_INT);
                g.writeInstruction('movzx', sr1, sR2S);
            end;
            TranslatorType.KIND_BYTE: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('call', FUNCTION_REAL_TO_INT);
                g.writeInstruction('movsx', sr1, sR2B);
            end;
            TranslatorType.KIND_SHORT: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('call', FUNCTION_REAL_TO_INT);
                g.writeInstruction('movsx', sr1, sR2S);
            end;
            TranslatorType.KIND_INT: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('call', FUNCTION_REAL_TO_INT);
                g.writeInstruction('mov', sr1, sR2I);
            end;
            TranslatorType.KIND_LONG: begin
                reg1 := stack.allocateGPR64bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('call', FUNCTION_REAL_TO_LONG);
                g.writeInstruction('mov', sr1, sR2L);
            end;
            TranslatorType.KIND_ULTRA: begin
                reg1 := stack.allocateXMM(XPINT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('call', FUNCTION_REAL_TO_LONG);
                g.writeInstruction('movq', sr1, sR2L);
            end;
            TranslatorType.KIND_FLOAT: begin
                reg1 := stack.allocateXMM(XSFLOAT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -8));
                g.writeInstruction('fstp', g.memoryToString(MFLOAT, RSP, 0));
                g.writeInstruction('movss', sr1, g.memoryToString(MNONE, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, 8));
            end;
            TranslatorType.KIND_DOUBLE: begin
                reg1 := stack.allocateXMM(XSDOUBLE, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -8));
                g.writeInstruction('fstp', g.memoryToString(MDOUBLE, RSP, 0));
                g.writeInstruction('movsd', sr1, g.memoryToString(MNONE, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, 8));
            end;
            TranslatorType.KIND_XVECTOR: begin
                reg1 := stack.allocateXMM(XPFLOAT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -8));
                g.writeInstruction('fstp', g.memoryToString(MFLOAT, RSP, 0));
                g.writeInstruction('movss', sr1, g.memoryToString(MNONE, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, 8));
            end;
            end;
        {%endregion}
        TranslatorType.KIND_XVECTOR: {%region исходный тип данных – xvector}
            case nodeType.kind of
            TranslatorType.KIND_CHAR: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movss', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_FLOAT_TO_INT);
                g.writeInstruction('movzx', sr1, sR2S);
            end;
            TranslatorType.KIND_BYTE: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movss', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_FLOAT_TO_INT);
                g.writeInstruction('movsx', sr1, sR2B);
            end;
            TranslatorType.KIND_SHORT: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movss', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_FLOAT_TO_INT);
                g.writeInstruction('movsx', sr1, sR2S);
            end;
            TranslatorType.KIND_INT: begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movss', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_FLOAT_TO_INT);
                g.writeInstruction('mov', sr1, sR2I);
            end;
            TranslatorType.KIND_LONG: begin
                reg1 := stack.allocateGPR64bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movss', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_FLOAT_TO_LONG);
                g.writeInstruction('mov', sr1, sR2L);
            end;
            TranslatorType.KIND_ULTRA: begin
                reg1 := stack.allocateXMM(XPINT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movups', sXMM12, sr2);
                g.writeInstruction('call', FUNCTION_XVECTOR_TO_ULTRA);
                g.writeInstruction('movdqu', sr1, sXMM12);
            end;
            TranslatorType.KIND_FLOAT: begin
                reg1 := stack.allocateXMM(XSFLOAT, g);
                if (reg1 and $1f) <> (reg2 and $1f) then begin
                    sr1 := g.registerToString(reg1);
                    g.writeInstruction('movss', sr1, sr2);
                end;
            end;
            TranslatorType.KIND_DOUBLE: begin
                reg1 := stack.allocateXMM(XSDOUBLE, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('cvtss2sd', sr1, sr2);
            end;
            TranslatorType.KIND_REAL: begin
                stack.allocateFPU(1, g);
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, -8));
                g.writeInstruction('movss', g.memoryToString(MNONE, RSP, 0), sr2);
                g.writeInstruction('fld', g.memoryToString(MFLOAT, RSP, 0));
                g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RSP, 8));
            end;
            end;
        {%endregion}
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_SNOTB: begin
        reg1 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        g.writeInstruction('not', sr1);
    end;
    TranslatorTreeBuilder.EXPR_SNEG: begin
        reg1 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        case (node.getChild(0) as SyntaxNode).dataType.kind of
        TranslatorType.KIND_INT, TranslatorType.KIND_LONG: begin
            g.writeInstruction('neg', sr1);
        end;
        TranslatorType.KIND_FLOAT: begin
            g.writeInstruction('movss', sXMM12, sr1);
            g.writeInstruction('movss', sr1, g.memoryToString(MNONE,
                    LABEL_POOL_FLOAT_CONTENT, programmeFloats.indexAcquire(0) * 4));
            g.writeInstruction('subss', sr1, sXMM12);
        end;
        TranslatorType.KIND_DOUBLE: begin
            g.writeInstruction('movsd', sXMM12, sr1);
            g.writeInstruction('movsd', sr1, g.memoryToString(MNONE,
                    LABEL_POOL_DOUBLE_CONTENT, programmeDoubles.indexAcquire(0) * 8));
            g.writeInstruction('subsd', sr1, sXMM12);
        end;
        TranslatorType.KIND_REAL: begin
            g.writeInstruction('fchs');
        end;
        end;
    end;
    TranslatorTreeBuilder.EXPR_QPACKUS: begin
        reg1 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        case (node.getChild(0) as SyntaxNode).dataType.kind of
        TranslatorType.KIND_LONG: begin
            reg1 := stack.changeToGPR32bit(0);
            srd := g.registerToString(reg1);
            g.writeInstruction('movq', sXMM12, sr1);
            g.writeInstruction('packuswb', sXMM12, sXMM12);
            g.writeInstruction('movd', srd, sXMM12);
        end;
        TranslatorType.KIND_ULTRA: begin
            { SSE4.1-инструкция }
            stack.popRegs(1);
            reg2 := stack.allocateGPR64bit(g);
            sr2 := g.registerToString(reg2);
            g.writeInstruction('packusdw', sr1, sr1);
            g.writeInstruction('movq', sr2, sr1);
            stack.restoreRegs(g);
        end;
        end;
    end;
    TranslatorTreeBuilder.EXPR_QUNPCKL: begin
        reg1 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        case (node.getChild(0) as SyntaxNode).dataType.kind of
        TranslatorType.KIND_INT: begin
            reg1 := stack.changeToGPR64bit(0);
            srq := g.registerToString(reg1);
            g.writeInstruction('movd', sXMM12, sr1);
            g.writeInstruction('pxor', sXMM13, sXMM13);
            g.writeInstruction('punpcklbw', sXMM12, sXMM13);
            g.writeInstruction('movq', srq, sXMM12);
        end;
        TranslatorType.KIND_LONG: begin
            stack.popRegs(1);
            reg2 := stack.allocateXMM(XPINT, g);
            sr2 := g.registerToString(reg2);
            g.writeInstruction('movq', sr2, sr1);
            g.writeInstruction('pxor', sXMM12, sXMM12);
            g.writeInstruction('punpcklwd', sr2, sXMM12);
            stack.restoreRegs(g);
        end;
        end;
    end;
    TranslatorTreeBuilder.EXPR_QUNPCKH: begin
        reg1 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        case (node.getChild(0) as SyntaxNode).dataType.kind of
        TranslatorType.KIND_INT: begin
            reg1 := stack.changeToGPR64bit(0);
            srq := g.registerToString(reg1);
            g.writeInstruction('pxor', sXMM12, sXMM12);
            g.writeInstruction('movd', sXMM13, sr1);
            g.writeInstruction('punpcklbw', sXMM12, sXMM13);
            g.writeInstruction('movq', srq, sXMM12);
        end;
        TranslatorType.KIND_LONG: begin
            stack.popRegs(1);
            reg2 := stack.allocateXMM(XPINT, g);
            sr2 := g.registerToString(reg2);
            g.writeInstruction('pxor', sr2, sr2);
            g.writeInstruction('movq', sXMM12, sr1);
            g.writeInstruction('punpcklwd', sr2, sXMM12);
            stack.restoreRegs(g);
        end;
        end;
    end;
    TranslatorTreeBuilder.EXPR_QNEG: begin
        reg1 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        case (node.getChild(0) as SyntaxNode).dataType.kind of
        TranslatorType.KIND_LONG: begin
            g.writeInstruction('pxor', sXMM12, sXMM12);
            g.writeInstruction('movq', sXMM13, sr1);
            g.writeInstruction('psubw', sXMM12, sXMM13);
            g.writeInstruction('movq', sr1, sXMM12);
        end;
        TranslatorType.KIND_ULTRA: begin
            g.writeInstruction('movdqu', sXMM12, sr1);
            g.writeInstruction('pxor', sr1, sr1);
            g.writeInstruction('psubd', sr1, sXMM12);
        end;
        TranslatorType.KIND_XVECTOR: begin
            g.writeInstruction('movups', sXMM12, sr1);
            g.writeInstruction('movups', sr1, g.memoryToString(MNONE,
                    LABEL_POOL_XVECTOR_CONTENT, programmeXVectors.indexAcquire(
                    xvectorBuild(0, 0, 0, 0)) * 16));
            g.writeInstruction('subps', sr1, sXMM12);
        end;
        end;
    end;
    TranslatorTreeBuilder.EXPR_OPACKUS: begin
        reg1 := stack.getRegAt(0);
        stack.popRegs(1);
        reg2 := stack.allocateGPR64bit(g);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        g.writeInstruction('packuswb', sr1, sr1);
        g.writeInstruction('movq', sr2, sr1);
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_OUNPCKL: begin
        reg1 := stack.getRegAt(0);
        stack.popRegs(1);
        reg2 := stack.allocateXMM(XPINT, g);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        g.writeInstruction('movq', sr2, sr1);
        g.writeInstruction('pxor', sXMM12, sXMM12);
        g.writeInstruction('punpcklbw', sr2, sXMM12);
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_OUNPCKH: begin
        reg1 := stack.getRegAt(0);
        stack.popRegs(1);
        reg2 := stack.allocateXMM(XPINT, g);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        g.writeInstruction('pxor', sr2, sr2);
        g.writeInstruction('movq', sXMM12, sr1);
        g.writeInstruction('punpcklbw', sr2, sXMM12);
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_ONEG: begin
        reg1 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        g.writeInstruction('movdqu', sXMM12, sr1);
        g.writeInstruction('pxor', sr1, sr1);
        g.writeInstruction('psubw', sr1, sXMM12);
    end;
    TranslatorTreeBuilder.EXPR_SADD,
    TranslatorTreeBuilder.EXPR_SSUB,
    TranslatorTreeBuilder.EXPR_SMULL: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        case (node.getChild(0) as SyntaxNode).dataType.kind of
        TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
            case nodeValue of
            TranslatorTreeBuilder.EXPR_SADD:
                g.writeInstruction('add', sr1, sr2);
            TranslatorTreeBuilder.EXPR_SSUB:
                g.writeInstruction('sub', sr1, sr2);
            TranslatorTreeBuilder.EXPR_SMULL:
                g.writeInstruction('imul', sr1, sr2);
            end;
        TranslatorType.KIND_FLOAT:
            case nodeValue of
            TranslatorTreeBuilder.EXPR_SADD:
                g.writeInstruction('addss', sr1, sr2);
            TranslatorTreeBuilder.EXPR_SSUB:
                g.writeInstruction('subss', sr1, sr2);
            TranslatorTreeBuilder.EXPR_SMULL:
                g.writeInstruction('mulss', sr1, sr2);
            end;
        TranslatorType.KIND_DOUBLE:
            case nodeValue of
            TranslatorTreeBuilder.EXPR_SADD:
                g.writeInstruction('addsd', sr1, sr2);
            TranslatorTreeBuilder.EXPR_SSUB:
                g.writeInstruction('subsd', sr1, sr2);
            TranslatorTreeBuilder.EXPR_SMULL:
                g.writeInstruction('mulsd', sr1, sr2);
            end;
        TranslatorType.KIND_REAL:
            case nodeValue of
            TranslatorTreeBuilder.EXPR_SADD:
                g.writeInstruction('faddp');
            TranslatorTreeBuilder.EXPR_SSUB:
                g.writeInstruction('fsubp');
            TranslatorTreeBuilder.EXPR_SMULL:
                g.writeInstruction('fmulp');
            end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_SDIVS,
    TranslatorTreeBuilder.EXPR_SDIVU: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        case (node.getChild(0) as SyntaxNode).dataType.kind of
        TranslatorType.KIND_INT: begin
            stack.popRegs(1);
            regInUse := stack.isUsedRegister(R0D);
            stack.pushReg(reg1);
            if reg2 = R0D then begin
                g.writeInstruction('xchg', sr1, sr2);
                case nodeValue of
                TranslatorTreeBuilder.EXPR_SDIVS: begin
                    g.writeInstruction('cdq');
                    g.writeInstruction('idiv', sr1);
                end;
                TranslatorTreeBuilder.EXPR_SDIVU: begin
                    g.writeInstruction('xor', sR2I, sR2I);
                    g.writeInstruction('div', sr1);
                end;
                end;
                g.writeInstruction('mov', sr1, sr2);
            end else begin
                if regInUse then begin
                    g.writeInstruction('mov', sR3L, sR0L);
                end;
                if reg1 <> R0D then begin
                    g.writeInstruction('mov', sR0I, sr1);
                end;
                case nodeValue of
                TranslatorTreeBuilder.EXPR_SDIVS: begin
                    g.writeInstruction('cdq');
                    g.writeInstruction('idiv', sr2);
                end;
                TranslatorTreeBuilder.EXPR_SDIVU: begin
                    g.writeInstruction('xor', sR2I, sR2I);
                    g.writeInstruction('div', sr2);
                end;
                end;
                if reg1 <> R0D then begin
                    g.writeInstruction('mov', sr1, sR0I);
                end;
                if regInUse then begin
                    g.writeInstruction('mov', sR0L, sR3L);
                end;
            end;
        end;
        TranslatorType.KIND_LONG: begin
            stack.popRegs(1);
            regInUse := stack.isUsedRegister(R0);
            stack.pushReg(reg1);
            if reg2 = R0 then begin
                g.writeInstruction('xchg', sr1, sr2);
                case nodeValue of
                TranslatorTreeBuilder.EXPR_SDIVS: begin
                    g.writeInstruction('cqo');
                    g.writeInstruction('idiv', sr1);
                end;
                TranslatorTreeBuilder.EXPR_SDIVU: begin
                    g.writeInstruction('xor', sR2L, sR2L);
                    g.writeInstruction('div', sr1);
                end;
                end;
                g.writeInstruction('mov', sr1, sr2);
            end else begin
                if regInUse then begin
                    g.writeInstruction('mov', sR3L, sR0L);
                end;
                if reg1 <> R0 then begin
                    g.writeInstruction('mov', sR0L, sr1);
                end;
                case nodeValue of
                TranslatorTreeBuilder.EXPR_SDIVS: begin
                    g.writeInstruction('cqo');
                    g.writeInstruction('idiv', sr2);
                end;
                TranslatorTreeBuilder.EXPR_SDIVU: begin
                    g.writeInstruction('xor', sR2L, sR2L);
                    g.writeInstruction('div', sr2);
                end;
                end;
                if reg1 <> R0 then begin
                    g.writeInstruction('mov', sr1, sR0L);
                end;
                if regInUse then begin
                    g.writeInstruction('mov', sR0L, sR3L);
                end;
            end;
        end;
        TranslatorType.KIND_FLOAT:
            g.writeInstruction('divss', sr1, sr2);
        TranslatorType.KIND_DOUBLE:
            g.writeInstruction('divsd', sr1, sr2);
        TranslatorType.KIND_REAL:
            g.writeInstruction('fdivp');
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_SREMS,
    TranslatorTreeBuilder.EXPR_SREMU: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        case (node.getChild(0) as SyntaxNode).dataType.kind of
        TranslatorType.KIND_INT: begin
            stack.popRegs(1);
            regInUse := stack.isUsedRegister(R0D);
            stack.pushReg(reg1);
            if reg2 = R0D then begin
                g.writeInstruction('xchg', sr1, sr2);
                case nodeValue of
                TranslatorTreeBuilder.EXPR_SREMS: begin
                    g.writeInstruction('cdq');
                    g.writeInstruction('idiv', sr1);
                end;
                TranslatorTreeBuilder.EXPR_SREMU: begin
                    g.writeInstruction('xor', sR2I, sR2I);
                    g.writeInstruction('div', sr1);
                end;
                end;
                g.writeInstruction('mov', sr1, sR2I);
            end else begin
                if regInUse then begin
                    g.writeInstruction('mov', sR3L, sR0L);
                end;
                if reg1 <> R0D then begin
                    g.writeInstruction('mov', sR0I, sr1);
                end;
                case nodeValue of
                TranslatorTreeBuilder.EXPR_SREMS: begin
                    g.writeInstruction('cdq');
                    g.writeInstruction('idiv', sr2);
                end;
                TranslatorTreeBuilder.EXPR_SREMU: begin
                    g.writeInstruction('xor', sR2I, sR2I);
                    g.writeInstruction('div', sr2);
                end;
                end;
                g.writeInstruction('mov', sr1, sR2I);
                if regInUse then begin
                    g.writeInstruction('mov', sR0L, sR3L);
                end;
            end;
        end;
        TranslatorType.KIND_LONG: begin
            stack.popRegs(1);
            regInUse := stack.isUsedRegister(R0);
            stack.pushReg(reg1);
            if reg2 = R0 then begin
                g.writeInstruction('xchg', sr1, sr2);
                case nodeValue of
                TranslatorTreeBuilder.EXPR_SREMS: begin
                    g.writeInstruction('cqo');
                    g.writeInstruction('idiv', sr1);
                end;
                TranslatorTreeBuilder.EXPR_SREMU: begin
                    g.writeInstruction('xor', sR2L, sR2L);
                    g.writeInstruction('div', sr1);
                end;
                end;
                g.writeInstruction('mov', sr1, sR2L);
            end else begin
                if regInUse then begin
                    g.writeInstruction('mov', sR3L, sR0L);
                end;
                if reg1 <> R0 then begin
                    g.writeInstruction('mov', sR0L, sr1);
                end;
                case nodeValue of
                TranslatorTreeBuilder.EXPR_SREMS: begin
                    g.writeInstruction('cqo');
                    g.writeInstruction('idiv', sr2);
                end;
                TranslatorTreeBuilder.EXPR_SREMU: begin
                    g.writeInstruction('xor', sR2L, sR2L);
                    g.writeInstruction('div', sr2);
                end;
                end;
                g.writeInstruction('mov', sr1, sR2L);
                if regInUse then begin
                    g.writeInstruction('mov', sR0L, sR3L);
                end;
            end;
        end;
        TranslatorType.KIND_REAL: begin
            regInUse := stack.isUsedRegister(R0W);
            if regInUse then begin
                g.writeInstruction('mov', sR3L, sR0L);
            end;
            g.writeInstruction('fxch');
            g.writeLabelShort(LABEL_ANONYMOUS);
            g.writeInstruction('fprem');
            g.writeInstruction('fnstsw', sR0S);
            g.writeInstruction('test', sR0I, g.immediateToStringShort($0400));
            g.writeInstruction('jnz', LABEL_PRECEDING);
            g.writeInstruction('fstp', sST1);
            if regInUse then begin
                g.writeInstruction('mov', sR0L, sR3L);
            end;
        end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_QMULL: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        case (node.getChild(0) as SyntaxNode).dataType.kind of
        TranslatorType.KIND_LONG: begin
            g.writeInstruction('movq', sXMM12, sr1);
            g.writeInstruction('movq', sXMM13, sr2);
            g.writeInstruction('pmullw', sXMM12, sXMM13);
            g.writeInstruction('movq', sr1, sXMM12);
        end;
        TranslatorType.KIND_ULTRA: begin
            if extension < TranslatorTreeBuilder.EXTENSION_SSE4_1 then begin
                g.writeInstruction('movdqu', sXMM12, sr1);
                g.writeInstruction('movdqu', sXMM13, sr2);
                g.writeInstruction('call', FUNCTION_ULTRA_QMULL);
                g.writeInstruction('movdqu', sr1, sXMM12);
            end else begin
                g.writeInstruction('pmulld', sr1, sr2);
            end;
        end;
        TranslatorType.KIND_XVECTOR: begin
            g.writeInstruction('mulps', sr1, sr2);
        end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_QMULH: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        case (node.getChild(0) as SyntaxNode).dataType.kind of
        TranslatorType.KIND_LONG: begin
            g.writeInstruction('movq', sXMM12, sr1);
            g.writeInstruction('movq', sXMM13, sr2);
            g.writeInstruction('pmulhuw', sXMM12, sXMM13);
            g.writeInstruction('movq', sr1, sXMM12);
        end;
        TranslatorType.KIND_ULTRA: begin
            g.writeInstruction('movdqu', sXMM12, sr1);
            g.writeInstruction('movdqu', sXMM13, sr2);
            g.writeInstruction('call', FUNCTION_ULTRA_QMULH);
            g.writeInstruction('movdqu', sr1, sXMM12);
        end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_QMULHS: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        g.writeInstruction('movq', sXMM12, sr1);
        g.writeInstruction('movq', sXMM13, sr2);
        if extension < TranslatorTreeBuilder.EXTENSION_SSSE3 then begin
            g.writeInstruction('call', FUNCTION_LONG_QMULHS);
        end else begin
            g.writeInstruction('pmulhrsw', sXMM12, sXMM13);
        end;
        g.writeInstruction('movq', sr1, sXMM12);
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_QDIV: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        g.writeInstruction('divps', sr1, sr2);
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_QADD,
    TranslatorTreeBuilder.EXPR_QSUB: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        case (node.getChild(0) as SyntaxNode).dataType.kind of
        TranslatorType.KIND_LONG: begin
            g.writeInstruction('movq', sXMM12, sr1);
            g.writeInstruction('movq', sXMM13, sr2);
            case nodeValue of
            TranslatorTreeBuilder.EXPR_QADD:
                g.writeInstruction('paddw', sXMM12, sXMM13);
            TranslatorTreeBuilder.EXPR_QSUB:
                g.writeInstruction('psubw', sXMM12, sXMM13);
            end;
            g.writeInstruction('movq', sr1, sXMM12);
        end;
        TranslatorType.KIND_ULTRA: begin
            case nodeValue of
            TranslatorTreeBuilder.EXPR_QADD:
                g.writeInstruction('paddd', sr1, sr2);
            TranslatorTreeBuilder.EXPR_QSUB:
                g.writeInstruction('psubd', sr1, sr2);
            end;
        end;
        TranslatorType.KIND_XVECTOR: begin
            case nodeValue of
            TranslatorTreeBuilder.EXPR_QADD:
                g.writeInstruction('addps', sr1, sr2);
            TranslatorTreeBuilder.EXPR_QSUB:
                g.writeInstruction('subps', sr1, sr2);
            end;
        end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_QADDS,
    TranslatorTreeBuilder.EXPR_QADDUS,
    TranslatorTreeBuilder.EXPR_QSUBS,
    TranslatorTreeBuilder.EXPR_QSUBUS: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        g.writeInstruction('movq', sXMM12, sr1);
        g.writeInstruction('movq', sXMM13, sr2);
        case nodeValue of
        TranslatorTreeBuilder.EXPR_QADDS:
            g.writeInstruction('paddsw', sXMM12, sXMM13);
        TranslatorTreeBuilder.EXPR_QADDUS:
            g.writeInstruction('paddusw', sXMM12, sXMM13);
        TranslatorTreeBuilder.EXPR_QSUBS:
            g.writeInstruction('psubsw', sXMM12, sXMM13);
        TranslatorTreeBuilder.EXPR_QSUBUS:
            g.writeInstruction('psubusw', sXMM12, sXMM13);
        end;
        g.writeInstruction('movq', sr1, sXMM12);
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_OMULL,
    TranslatorTreeBuilder.EXPR_OMULH,
    TranslatorTreeBuilder.EXPR_OMULHS,
    TranslatorTreeBuilder.EXPR_OADD,
    TranslatorTreeBuilder.EXPR_OADDS,
    TranslatorTreeBuilder.EXPR_OADDUS,
    TranslatorTreeBuilder.EXPR_OSUB,
    TranslatorTreeBuilder.EXPR_OSUBS,
    TranslatorTreeBuilder.EXPR_OSUBUS,
    TranslatorTreeBuilder.EXPR_OGT,
    TranslatorTreeBuilder.EXPR_OGE,
    TranslatorTreeBuilder.EXPR_OLT,
    TranslatorTreeBuilder.EXPR_OLE,
    TranslatorTreeBuilder.EXPR_OEQ,
    TranslatorTreeBuilder.EXPR_ONE: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        case nodeValue of
        TranslatorTreeBuilder.EXPR_OMULL: begin
            g.writeInstruction('pmullw', sr1, sr2);
        end;
        TranslatorTreeBuilder.EXPR_OMULH: begin
            g.writeInstruction('pmulhuw', sr1, sr2);
        end;
        TranslatorTreeBuilder.EXPR_OMULHS: begin
            if extension < TranslatorTreeBuilder.EXTENSION_SSSE3 then begin
                g.writeInstruction('movdqu', sXMM12, sr1);
                g.writeInstruction('movdqu', sXMM13, sr2);
                g.writeInstruction('call', FUNCTION_ULTRA_OMULHS);
                g.writeInstruction('movdqu', sr1, sXMM12);
            end else begin
                g.writeInstruction('pmulhrsw', sr1, sr2);
            end;
        end;
        TranslatorTreeBuilder.EXPR_OADD: begin
            g.writeInstruction('paddw', sr1, sr2);
        end;
        TranslatorTreeBuilder.EXPR_OADDS: begin
            g.writeInstruction('paddsw', sr1, sr2);
        end;
        TranslatorTreeBuilder.EXPR_OADDUS: begin
            g.writeInstruction('paddusw', sr1, sr2);
        end;
        TranslatorTreeBuilder.EXPR_OSUB: begin
            g.writeInstruction('psubw', sr1, sr2);
        end;
        TranslatorTreeBuilder.EXPR_OSUBS: begin
            g.writeInstruction('psubsw', sr1, sr2);
        end;
        TranslatorTreeBuilder.EXPR_OSUBUS: begin
            g.writeInstruction('psubusw', sr1, sr2);
        end;
        TranslatorTreeBuilder.EXPR_QGT: begin
            g.writeInstruction('pcmpgtw', sr1, sr2);
        end;
        TranslatorTreeBuilder.EXPR_QGE: begin
            g.writeInstruction('pcmpgtw', sr2, sr1);
            g.writeInstruction('movdqu', sr1, sr2);
            g.writeInstruction('movdqu', sr2, g.memoryToString(MNONE, LABEL_POOL_ULTRA_CONTENT,
                    programmeXUltras.indexAcquire(ultraBuild(-1, -1)) * 16));
            g.writeInstruction('pxor', sr1, sr2);
        end;
        TranslatorTreeBuilder.EXPR_QLT: begin
            g.writeInstruction('pcmpgtw', sr2, sr1);
            g.writeInstruction('movdqu', sr1, sr2);
        end;
        TranslatorTreeBuilder.EXPR_QLE: begin
            g.writeInstruction('pcmpgtw', sr1, sr2);
            g.writeInstruction('movdqu', sr2, g.memoryToString(MNONE, LABEL_POOL_ULTRA_CONTENT,
                    programmeXUltras.indexAcquire(ultraBuild(-1, -1)) * 16));
            g.writeInstruction('pxor', sr1, sr2);
        end;
        TranslatorTreeBuilder.EXPR_QEQ: begin
            g.writeInstruction('pcmpeqw', sr1, sr2);
        end;
        TranslatorTreeBuilder.EXPR_QNE: begin
            g.writeInstruction('pcmpeqw', sr1, sr2);
            g.writeInstruction('movdqu', sr2, g.memoryToString(MNONE, LABEL_POOL_ULTRA_CONTENT,
                    programmeXUltras.indexAcquire(ultraBuild(-1, -1)) * 16));
            g.writeInstruction('pxor', sr1, sr2);
        end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_SSLL,
    TranslatorTreeBuilder.EXPR_SSRA,
    TranslatorTreeBuilder.EXPR_SSRL: begin
        child := node.getChild(1) as SyntaxNode;
        if child.value <> TranslatorTreeBuilder.EXPR_VALUE_INT then begin
            reg1 := stack.getRegAt(1);
            reg2 := stack.getRegAt(0);
            sr1 := g.registerToString(reg1);
            sr2 := g.registerToString(reg2);
            stack.popRegs(1);
            g.writeInstruction('mov', sR1I, sr2);
            case nodeValue of
            TranslatorTreeBuilder.EXPR_SSLL:
                g.writeInstruction('shl', sr1, sR1B);
            TranslatorTreeBuilder.EXPR_SSRA:
                g.writeInstruction('sar', sr1, sR1B);
            TranslatorTreeBuilder.EXPR_SSRL:
                g.writeInstruction('shr', sr1, sR1B);
            end;
            stack.restoreRegs(g);
        end else begin
            reg1 := stack.getRegAt(0);
            sr1 := g.registerToString(reg1);
            buffer := (child.associate as IntegerAsObject).byteValue();
            simm := g.immediateToStringByte(buffer);
            case nodeValue of
            TranslatorTreeBuilder.EXPR_SSLL:
                g.writeInstruction('shl', sr1, simm);
            TranslatorTreeBuilder.EXPR_SSRA:
                g.writeInstruction('sar', sr1, simm);
            TranslatorTreeBuilder.EXPR_SSRL:
                g.writeInstruction('shr', sr1, simm);
            end;
        end;
    end;
    TranslatorTreeBuilder.EXPR_QSLL,
    TranslatorTreeBuilder.EXPR_QSRA,
    TranslatorTreeBuilder.EXPR_QSRL: begin
        child := node.getChild(1) as SyntaxNode;
        if child.value <> TranslatorTreeBuilder.EXPR_VALUE_INT then begin
            reg1 := stack.getRegAt(1);
            reg2 := stack.getRegAt(0);
            sr1 := g.registerToString(reg1);
            sr2 := g.registerToString(reg2);
            stack.popRegs(1);
            case (node.getChild(0) as SyntaxNode).dataType.kind of
            TranslatorType.KIND_LONG: begin
                g.writeInstruction('movq', sXMM12, sr1);
                g.writeInstruction('movd', sXMM13, sr2);
                case nodeValue of
                TranslatorTreeBuilder.EXPR_QSLL:
                    g.writeInstruction('psllw', sXMM12, sXMM13);
                TranslatorTreeBuilder.EXPR_QSRA:
                    g.writeInstruction('psraw', sXMM12, sXMM13);
                TranslatorTreeBuilder.EXPR_QSRL:
                    g.writeInstruction('psrlw', sXMM12, sXMM13);
                end;
                g.writeInstruction('movq', sr1, sXMM12);
            end;
            TranslatorType.KIND_ULTRA: begin
                g.writeInstruction('movd', sXMM12, sr2);
                case nodeValue of
                TranslatorTreeBuilder.EXPR_QSLL:
                    g.writeInstruction('pslld', sr1, sXMM12);
                TranslatorTreeBuilder.EXPR_QSRA:
                    g.writeInstruction('psrad', sr1, sXMM12);
                TranslatorTreeBuilder.EXPR_QSRL:
                    g.writeInstruction('psrld', sr1, sXMM12);
                end;
            end;
            end;
            stack.restoreRegs(g);
        end else begin
            reg1 := stack.getRegAt(0);
            sr1 := g.registerToString(reg1);
            buffer := (child.associate as IntegerAsObject).byteValue();
            simm := g.immediateToStringByte(buffer);
            case (node.getChild(0) as SyntaxNode).dataType.kind of
            TranslatorType.KIND_LONG: begin
                g.writeInstruction('movq', sXMM12, sr1);
                case nodeValue of
                TranslatorTreeBuilder.EXPR_QSLL:
                    g.writeInstruction('psllw', sXMM12, simm);
                TranslatorTreeBuilder.EXPR_QSRA:
                    g.writeInstruction('psraw', sXMM12, simm);
                TranslatorTreeBuilder.EXPR_QSRL:
                    g.writeInstruction('psrlw', sXMM12, simm);
                end;
                g.writeInstruction('movq', sr1, sXMM12);
            end;
            TranslatorType.KIND_ULTRA: begin
                case nodeValue of
                TranslatorTreeBuilder.EXPR_QSLL:
                    g.writeInstruction('pslld', sr1, simm);
                TranslatorTreeBuilder.EXPR_QSRA:
                    g.writeInstruction('psrad', sr1, simm);
                TranslatorTreeBuilder.EXPR_QSRL:
                    g.writeInstruction('psrld', sr1, simm);
                end;
            end;
            end;
        end;
    end;
    TranslatorTreeBuilder.EXPR_OSLL,
    TranslatorTreeBuilder.EXPR_OSRA,
    TranslatorTreeBuilder.EXPR_OSRL: begin
        child := node.getChild(1) as SyntaxNode;
        if child.value <> TranslatorTreeBuilder.EXPR_VALUE_INT then begin
            reg1 := stack.getRegAt(1);
            reg2 := stack.getRegAt(0);
            sr1 := g.registerToString(reg1);
            sr2 := g.registerToString(reg2);
            stack.popRegs(1);
            g.writeInstruction('movd', sXMM12, sr2);
            case nodeValue of
            TranslatorTreeBuilder.EXPR_QSLL:
                g.writeInstruction('psllw', sr1, sXMM12);
            TranslatorTreeBuilder.EXPR_QSRA:
                g.writeInstruction('psraw', sr1, sXMM12);
            TranslatorTreeBuilder.EXPR_QSRL:
                g.writeInstruction('psrlw', sr1, sXMM12);
            end;
            stack.restoreRegs(g);
        end else begin
            reg1 := stack.getRegAt(0);
            sr1 := g.registerToString(reg1);
            buffer := (child.associate as IntegerAsObject).byteValue();
            simm := g.immediateToStringByte(buffer);
            case nodeValue of
            TranslatorTreeBuilder.EXPR_QSLL:
                g.writeInstruction('psllw', sr1, simm);
            TranslatorTreeBuilder.EXPR_QSRA:
                g.writeInstruction('psraw', sr1, simm);
            TranslatorTreeBuilder.EXPR_QSRL:
                g.writeInstruction('psrlw', sr1, simm);
            end;
        end;
    end;
    TranslatorTreeBuilder.EXPR_SGT,
    TranslatorTreeBuilder.EXPR_SGE,
    TranslatorTreeBuilder.EXPR_SLT,
    TranslatorTreeBuilder.EXPR_SLE,
    TranslatorTreeBuilder.EXPR_SEQ,
    TranslatorTreeBuilder.EXPR_SNE: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(2);
        buffer := (node.getChild(0) as SyntaxNode).dataType.kind;
        case buffer of
        TranslatorType.KIND_STRUCT, TranslatorType.KIND_ARRAY, TranslatorType.KIND_FUNC,
        TranslatorType.KIND_BOOLEAN, TranslatorType.KIND_INT, TranslatorType.KIND_LONG: begin
            g.writeInstruction('cmp', sr1, sr2);
            if (goIfTrueTo <> nil) and (goIfFalseTo <> nil) then begin
                stack.restoreRegs(g); { регистр флагов – без изменений }
                if goIfTrueTo.labelNumber = nodeLN + 1 then begin
                    slbl := LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_SGT:
                        g.writeInstruction('jle', slbl);
                    TranslatorTreeBuilder.EXPR_SGE:
                        g.writeInstruction('jl', slbl);
                    TranslatorTreeBuilder.EXPR_SLT:
                        g.writeInstruction('jge', slbl);
                    TranslatorTreeBuilder.EXPR_SLE:
                        g.writeInstruction('jg', slbl);
                    TranslatorTreeBuilder.EXPR_SEQ:
                        g.writeInstruction('jne', slbl);
                    TranslatorTreeBuilder.EXPR_SNE:
                        g.writeInstruction('je', slbl);
                    end;
                end else
                if goIfFalseTo.labelNumber = nodeLN + 1 then begin
                    slbl := LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_SGT:
                        g.writeInstruction('jg', slbl);
                    TranslatorTreeBuilder.EXPR_SGE:
                        g.writeInstruction('jge', slbl);
                    TranslatorTreeBuilder.EXPR_SLT:
                        g.writeInstruction('jl', slbl);
                    TranslatorTreeBuilder.EXPR_SLE:
                        g.writeInstruction('jle', slbl);
                    TranslatorTreeBuilder.EXPR_SEQ:
                        g.writeInstruction('je', slbl);
                    TranslatorTreeBuilder.EXPR_SNE:
                        g.writeInstruction('jne', slbl);
                    end;
                end else begin
                    slbl := LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_SGT:
                        g.writeInstruction('jle', slbl);
                    TranslatorTreeBuilder.EXPR_SGE:
                        g.writeInstruction('jl', slbl);
                    TranslatorTreeBuilder.EXPR_SLT:
                        g.writeInstruction('jge', slbl);
                    TranslatorTreeBuilder.EXPR_SLE:
                        g.writeInstruction('jg', slbl);
                    TranslatorTreeBuilder.EXPR_SEQ:
                        g.writeInstruction('jne', slbl);
                    TranslatorTreeBuilder.EXPR_SNE:
                        g.writeInstruction('je', slbl);
                    end;
                    g.writeInstruction('jmp',
                            LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
                end;
            end else begin
                reg1 := R0D + (reg1 and $0f);
                srb := g.registerToString(R0B + (reg1 and $0f));
                sr1 := g.registerToString(reg1);
                stack.pushReg(reg1);
                case nodeValue of
                TranslatorTreeBuilder.EXPR_SGT:
                    g.writeInstruction('setg', srb);
                TranslatorTreeBuilder.EXPR_SGE:
                    g.writeInstruction('setge', srb);
                TranslatorTreeBuilder.EXPR_SLT:
                    g.writeInstruction('setl', srb);
                TranslatorTreeBuilder.EXPR_SLE:
                    g.writeInstruction('setle', srb);
                TranslatorTreeBuilder.EXPR_SEQ:
                    g.writeInstruction('sete', srb);
                TranslatorTreeBuilder.EXPR_SNE:
                    g.writeInstruction('setne', srb);
                end;
                g.writeInstruction('movzx', sr1, srb);
                stack.restoreRegs(g);
            end;
        end;
        TranslatorType.KIND_ULTRA, TranslatorType.KIND_XVECTOR: begin
            case buffer of
            TranslatorType.KIND_ULTRA:
                g.writeInstruction('pcmpeqw', sr1, sr2);
            TranslatorType.KIND_XVECTOR:
                g.writeInstruction('cmpps', sr1, sr2, g.immediateToStringByte(0));
            end;
            g.writeInstruction('psrlw', sr1, g.immediateToString($08));
            g.writeInstruction('packuswb', sr1, sr1);
            g.writeInstruction('movq', sR3L, sr1);
            g.writeInstruction('cmp', sR3L, g.immediateToString(-1));
            if (goIfTrueTo <> nil) and (goIfFalseTo <> nil) then begin
                stack.restoreRegs(g); { регистр флагов – без изменений }
                if goIfTrueTo.labelNumber = nodeLN + 1 then begin
                    slbl := LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_SEQ:
                        g.writeInstruction('jne', slbl);
                    TranslatorTreeBuilder.EXPR_SNE:
                        g.writeInstruction('je', slbl);
                    end;
                end else
                if goIfFalseTo.labelNumber = nodeLN + 1 then begin
                    slbl := LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_SEQ:
                        g.writeInstruction('je', slbl);
                    TranslatorTreeBuilder.EXPR_SNE:
                        g.writeInstruction('jne', slbl);
                    end;
                end else begin
                    slbl := LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_SEQ:
                        g.writeInstruction('jne', slbl);
                    TranslatorTreeBuilder.EXPR_SNE:
                        g.writeInstruction('je', slbl);
                    end;
                    g.writeInstruction('jmp',
                            LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
                end;
            end else begin
                reg1 := stack.allocateGPR32bit(g); { регистр флагов – без изменений }
                srb := g.registerToString(R0B + (reg1 and $0f));
                sr1 := g.registerToString(reg1);
                case nodeValue of
                TranslatorTreeBuilder.EXPR_SEQ:
                    g.writeInstruction('sete', srb);
                TranslatorTreeBuilder.EXPR_SNE:
                    g.writeInstruction('setne', srb);
                end;
                g.writeInstruction('movzx', sr1, srb);
                stack.restoreRegs(g);
            end;
        end;
        TranslatorType.KIND_FLOAT: begin
            case nodeValue of
            TranslatorTreeBuilder.EXPR_SGT: begin
                g.writeInstruction('cmpss', sr2, sr1, g.immediateToStringByte(1));
                g.writeInstruction('pmovmskb', sR3L, sr2);
            end;
            TranslatorTreeBuilder.EXPR_SGE: begin
                g.writeInstruction('cmpss', sr2, sr1, g.immediateToStringByte(2));
                g.writeInstruction('pmovmskb', sR3L, sr2);
            end;
            TranslatorTreeBuilder.EXPR_SLT: begin
                g.writeInstruction('cmpss', sr1, sr2, g.immediateToStringByte(1));
                g.writeInstruction('pmovmskb', sR3L, sr1);
            end;
            TranslatorTreeBuilder.EXPR_SLE: begin
                g.writeInstruction('cmpss', sr1, sr2, g.immediateToStringByte(2));
                g.writeInstruction('pmovmskb', sR3L, sr1);
            end;
            TranslatorTreeBuilder.EXPR_SEQ: begin
                g.writeInstruction('cmpss', sr1, sr2, g.immediateToStringByte(0));
                g.writeInstruction('pmovmskb', sR3L, sr1);
            end;
            TranslatorTreeBuilder.EXPR_SNE: begin
                g.writeInstruction('cmpss', sr1, sr2, g.immediateToStringByte(4));
                g.writeInstruction('pmovmskb', sR3L, sr1);
            end;
            end;
            g.writeInstruction('test', sR3I, g.immediateToStringShort($08));
            if (goIfTrueTo <> nil) and (goIfFalseTo <> nil) then begin
                stack.restoreRegs(g); { регистр флагов – без изменений }
                if goIfTrueTo.labelNumber = nodeLN + 1 then begin
                    g.writeInstruction('jz',
                            LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                end else
                if goIfFalseTo.labelNumber = nodeLN + 1 then begin
                    g.writeInstruction('jnz',
                            LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
                end else begin
                    g.writeInstruction('jz',
                            LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                    g.writeInstruction('jmp',
                            LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
                end;
            end else begin
                reg1 := stack.allocateGPR32bit(g); { регистр флагов – без изменений }
                srb := g.registerToString(R0B + (reg1 and $0f));
                sr1 := g.registerToString(reg1);
                g.writeInstruction('setnz', srb);
                g.writeInstruction('movzx', sr1, srb);
                stack.restoreRegs(g);
            end;
        end;
        TranslatorType.KIND_DOUBLE: begin
            case nodeValue of
            TranslatorTreeBuilder.EXPR_SGT: begin
                g.writeInstruction('cmpsd', sr2, sr1, g.immediateToStringByte(1));
                g.writeInstruction('pmovmskb', sR3L, sr2);
            end;
            TranslatorTreeBuilder.EXPR_SGE: begin
                g.writeInstruction('cmpsd', sr2, sr1, g.immediateToStringByte(2));
                g.writeInstruction('pmovmskb', sR3L, sr2);
            end;
            TranslatorTreeBuilder.EXPR_SLT: begin
                g.writeInstruction('cmpsd', sr1, sr2, g.immediateToStringByte(1));
                g.writeInstruction('pmovmskb', sR3L, sr1);
            end;
            TranslatorTreeBuilder.EXPR_SLE: begin
                g.writeInstruction('cmpsd', sr1, sr2, g.immediateToStringByte(2));
                g.writeInstruction('pmovmskb', sR3L, sr1);
            end;
            TranslatorTreeBuilder.EXPR_SEQ: begin
                g.writeInstruction('cmpsd', sr1, sr2, g.immediateToStringByte(0));
                g.writeInstruction('pmovmskb', sR3L, sr1);
            end;
            TranslatorTreeBuilder.EXPR_SNE: begin
                g.writeInstruction('cmpsd', sr1, sr2, g.immediateToStringByte(4));
                g.writeInstruction('pmovmskb', sR3L, sr1);
            end;
            end;
            g.writeInstruction('test', sR3I, g.immediateToStringShort($80));
            if (goIfTrueTo <> nil) and (goIfFalseTo <> nil) then begin
                stack.restoreRegs(g); { регистр флагов – без изменений }
                if goIfTrueTo.labelNumber = nodeLN + 1 then begin
                    g.writeInstruction('jz',
                            LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                end else
                if goIfFalseTo.labelNumber = nodeLN + 1 then begin
                    g.writeInstruction('jnz',
                            LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
                end else begin
                    g.writeInstruction('jz',
                            LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                    g.writeInstruction('jmp',
                            LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
                end;
            end else begin
                reg1 := stack.allocateGPR32bit(g); { регистр флагов – без изменений }
                srb := g.registerToString(R0B + (reg1 and $0f));
                sr1 := g.registerToString(reg1);
                g.writeInstruction('setnz', srb);
                g.writeInstruction('movzx', sr1, srb);
                stack.restoreRegs(g);
            end;
        end;
        TranslatorType.KIND_REAL: begin
            g.writeInstruction('fxch');
            g.writeInstruction('fcomip', sST0, sST1);
            g.writeInstruction('ffree', sST0);
            g.writeInstruction('fincstp');
            g.writeInstruction('jnp', LABEL_FOLLOWING);
            g.writeInstruction('mov', sR1B, g.immediateToStringByte($ff));
            g.writeInstruction('or', sR1I, sR1I);
            if (nodeValue <> TranslatorTreeBuilder.EXPR_SLT) and
                    (nodeValue <> TranslatorTreeBuilder.EXPR_SLE) then begin
                g.writeInstruction('stc');
            end;
            g.writeLabelShort(LABEL_ANONYMOUS);
            if (goIfTrueTo <> nil) and (goIfFalseTo <> nil) then begin
                stack.restoreRegs(g); { регистр флагов – без изменений }
                if goIfTrueTo.labelNumber = nodeLN + 1 then begin
                    slbl := LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_SGT:
                        g.writeInstruction('jbe', slbl);
                    TranslatorTreeBuilder.EXPR_SGE:
                        g.writeInstruction('jb', slbl);
                    TranslatorTreeBuilder.EXPR_SLT:
                        g.writeInstruction('jae', slbl);
                    TranslatorTreeBuilder.EXPR_SLE:
                        g.writeInstruction('ja', slbl);
                    TranslatorTreeBuilder.EXPR_SEQ:
                        g.writeInstruction('jne', slbl);
                    TranslatorTreeBuilder.EXPR_SNE:
                        g.writeInstruction('je', slbl);
                    end;
                end else
                if goIfFalseTo.labelNumber = nodeLN + 1 then begin
                    slbl := LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_SGT:
                        g.writeInstruction('ja', slbl);
                    TranslatorTreeBuilder.EXPR_SGE:
                        g.writeInstruction('jae', slbl);
                    TranslatorTreeBuilder.EXPR_SLT:
                        g.writeInstruction('jb', slbl);
                    TranslatorTreeBuilder.EXPR_SLE:
                        g.writeInstruction('jbe', slbl);
                    TranslatorTreeBuilder.EXPR_SEQ:
                        g.writeInstruction('je', slbl);
                    TranslatorTreeBuilder.EXPR_SNE:
                        g.writeInstruction('jne', slbl);
                    end;
                end else begin
                    slbl := LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber);
                    case nodeValue of
                    TranslatorTreeBuilder.EXPR_SGT:
                        g.writeInstruction('jbe', slbl);
                    TranslatorTreeBuilder.EXPR_SGE:
                        g.writeInstruction('jb', slbl);
                    TranslatorTreeBuilder.EXPR_SLT:
                        g.writeInstruction('jae', slbl);
                    TranslatorTreeBuilder.EXPR_SLE:
                        g.writeInstruction('ja', slbl);
                    TranslatorTreeBuilder.EXPR_SEQ:
                        g.writeInstruction('jne', slbl);
                    TranslatorTreeBuilder.EXPR_SNE:
                        g.writeInstruction('je', slbl);
                    end;
                    g.writeInstruction('jmp',
                            LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
                end;
            end else begin
                reg1 := stack.allocateGPR32bit(g); { регистр флагов – без изменений }
                srb := g.registerToString(R0B + (reg1 and $0f));
                sr1 := g.registerToString(reg1);
                case nodeValue of
                TranslatorTreeBuilder.EXPR_SGT:
                    g.writeInstruction('seta', srb);
                TranslatorTreeBuilder.EXPR_SGE:
                    g.writeInstruction('setae', srb);
                TranslatorTreeBuilder.EXPR_SLT:
                    g.writeInstruction('setb', srb);
                TranslatorTreeBuilder.EXPR_SLE:
                    g.writeInstruction('setbe', srb);
                TranslatorTreeBuilder.EXPR_SEQ:
                    g.writeInstruction('sete', srb);
                TranslatorTreeBuilder.EXPR_SNE:
                    g.writeInstruction('setne', srb);
                end;
                g.writeInstruction('movzx', sr1, srb);
                stack.restoreRegs(g);
            end;
        end;
        end;
    end;
    TranslatorTreeBuilder.EXPR_QGT,
    TranslatorTreeBuilder.EXPR_QGE,
    TranslatorTreeBuilder.EXPR_QLT,
    TranslatorTreeBuilder.EXPR_QLE,
    TranslatorTreeBuilder.EXPR_QEQ,
    TranslatorTreeBuilder.EXPR_QNE: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        case (node.getChild(0) as SyntaxNode).dataType.kind of
        TranslatorType.KIND_LONG: begin
            g.writeInstruction('movq', sXMM12, sr1);
            g.writeInstruction('movq', sXMM13, sr2);
            case nodeValue of
            TranslatorTreeBuilder.EXPR_QGT: begin
                g.writeInstruction('pcmpgtw', sXMM12, sXMM13);
                g.writeInstruction('movq', sr1, sXMM12);
            end;
            TranslatorTreeBuilder.EXPR_QGE: begin
                g.writeInstruction('pcmpgtw', sXMM13, sXMM12);
                g.writeInstruction('movq', sr1, sXMM13);
                g.writeInstruction('xor', sr1, g.immediateToString(-1));
            end;
            TranslatorTreeBuilder.EXPR_QLT: begin
                g.writeInstruction('pcmpgtw', sXMM13, sXMM12);
                g.writeInstruction('movq', sr1, sXMM13);
            end;
            TranslatorTreeBuilder.EXPR_QLE: begin
                g.writeInstruction('pcmpgtw', sXMM12, sXMM13);
                g.writeInstruction('movq', sr1, sXMM12);
                g.writeInstruction('xor', sr1, g.immediateToString(-1));
            end;
            TranslatorTreeBuilder.EXPR_QEQ: begin
                g.writeInstruction('pcmpeqw', sXMM12, sXMM13);
                g.writeInstruction('movq', sr1, sXMM12);
            end;
            TranslatorTreeBuilder.EXPR_QNE: begin
                g.writeInstruction('pcmpeqw', sXMM12, sXMM13);
                g.writeInstruction('movq', sr1, sXMM12);
                g.writeInstruction('xor', sr1, g.immediateToString(-1));
            end;
            end;
        end;
        TranslatorType.KIND_ULTRA: begin
            case nodeValue of
            TranslatorTreeBuilder.EXPR_QGT: begin
                g.writeInstruction('pcmpgtd', sr1, sr2);
            end;
            TranslatorTreeBuilder.EXPR_QGE: begin
                g.writeInstruction('pcmpgtd', sr2, sr1);
                g.writeInstruction('movdqu', sr1, sr2);
                g.writeInstruction('movdqu', sr2, g.memoryToString(MNONE, LABEL_POOL_ULTRA_CONTENT,
                        programmeXUltras.indexAcquire(ultraBuild(-1, -1)) * 16));
                g.writeInstruction('pxor', sr1, sr2);
            end;
            TranslatorTreeBuilder.EXPR_QLT: begin
                g.writeInstruction('pcmpgtd', sr2, sr1);
                g.writeInstruction('movdqu', sr1, sr2);
            end;
            TranslatorTreeBuilder.EXPR_QLE: begin
                g.writeInstruction('pcmpgtd', sr1, sr2);
                g.writeInstruction('movdqu', sr2, g.memoryToString(MNONE, LABEL_POOL_ULTRA_CONTENT,
                        programmeXUltras.indexAcquire(ultraBuild(-1, -1)) * 16));
                g.writeInstruction('pxor', sr1, sr2);
            end;
            TranslatorTreeBuilder.EXPR_QEQ: begin
                g.writeInstruction('pcmpeqd', sr1, sr2);
            end;
            TranslatorTreeBuilder.EXPR_QNE: begin
                g.writeInstruction('pcmpeqd', sr1, sr2);
                g.writeInstruction('movdqu', sr2, g.memoryToString(MNONE, LABEL_POOL_ULTRA_CONTENT,
                        programmeXUltras.indexAcquire(ultraBuild(-1, -1)) * 16));
                g.writeInstruction('pxor', sr1, sr2);
            end;
            end;
        end;
        TranslatorType.KIND_XVECTOR: begin
            stack.changeToXMM(0, XPINT);
            case nodeValue of
            TranslatorTreeBuilder.EXPR_SGT: begin
                g.writeInstruction('cmpps', sr2, sr1, g.immediateToStringByte(1));
                g.writeInstruction('movdqu', sr1, sr2);
            end;
            TranslatorTreeBuilder.EXPR_SGE: begin
                g.writeInstruction('cmpps', sr2, sr1, g.immediateToStringByte(2));
                g.writeInstruction('movdqu', sr1, sr2);
            end;
            TranslatorTreeBuilder.EXPR_SLT: begin
                g.writeInstruction('cmpps', sr1, sr2, g.immediateToStringByte(1));
            end;
            TranslatorTreeBuilder.EXPR_SLE: begin
                g.writeInstruction('cmpps', sr1, sr2, g.immediateToStringByte(2));
            end;
            TranslatorTreeBuilder.EXPR_SEQ: begin
                g.writeInstruction('cmpps', sr1, sr2, g.immediateToStringByte(0));
            end;
            TranslatorTreeBuilder.EXPR_SNE: begin
                g.writeInstruction('cmpps', sr1, sr2, g.immediateToStringByte(4));
            end;
            end;
        end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.EXPR_SANDB,
    TranslatorTreeBuilder.EXPR_SXORB,
    TranslatorTreeBuilder.EXPR_SORB: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        if (goIfTrueTo <> nil) and (goIfFalseTo <> nil) then begin
            stack.popRegs(1);
            case nodeValue of
            TranslatorTreeBuilder.EXPR_SANDB:
                g.writeInstruction('test', sr1, sr2);
            TranslatorTreeBuilder.EXPR_SXORB:
                g.writeInstruction('xor', sr1, sr2);
            TranslatorTreeBuilder.EXPR_SORB:
                g.writeInstruction('or', sr1, sr2);
            end;
            stack.restoreRegs(g); { регистр флагов – без изменений }
            if goIfTrueTo.labelNumber = nodeLN + 1 then begin
                g.writeInstruction('jz',
                        LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
            end else
            if goIfFalseTo.labelNumber = nodeLN + 1 then begin
                g.writeInstruction('jnz',
                        LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
            end else begin
                g.writeInstruction('jz',
                        LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                g.writeInstruction('jmp',
                        LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
            end;
        end else begin
            case (node.getChild(0) as SyntaxNode).dataType.kind of
            TranslatorType.KIND_BOOLEAN, TranslatorType.KIND_INT, TranslatorType.KIND_LONG: begin
                case nodeValue of
                TranslatorTreeBuilder.EXPR_SANDB:
                    g.writeInstruction('and', sr1, sr2);
                TranslatorTreeBuilder.EXPR_SXORB:
                    g.writeInstruction('xor', sr1, sr2);
                TranslatorTreeBuilder.EXPR_SORB:
                    g.writeInstruction('or', sr1, sr2);
                end;
            end;
            TranslatorType.KIND_ULTRA: begin
                case nodeValue of
                TranslatorTreeBuilder.EXPR_SANDB:
                    g.writeInstruction('pand', sr1, sr2);
                TranslatorTreeBuilder.EXPR_SXORB:
                    g.writeInstruction('pxor', sr1, sr2);
                TranslatorTreeBuilder.EXPR_SORB:
                    g.writeInstruction('por', sr1, sr2);
                end;
            end;
            end;
            stack.restoreRegs(g);
        end;
    end;
    TranslatorTreeBuilder.EXPR_SZR_TEST: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        g.writeInstruction('test', sr1, sr2);
        if (goIfTrueTo <> nil) and (goIfFalseTo <> nil) then begin
            stack.popRegs(1);
            stack.restoreRegs(g); { регистр флагов – без изменений }
            if goIfTrueTo.labelNumber = nodeLN + 1 then begin
                g.writeInstruction('jnz',
                        LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
            end else
            if goIfFalseTo.labelNumber = nodeLN + 1 then begin
                g.writeInstruction('jz',
                        LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
            end else begin
                g.writeInstruction('jnz',
                        LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                g.writeInstruction('jmp',
                        LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
            end;
        end else begin
            reg1 := stack.changeToGPR32bit(0);
            srb := g.registerToString(R0B + (reg1 and $0f));
            sr1 := g.registerToString(reg1);
            g.writeInstruction('setz', srb);
            g.writeInstruction('movzx', sr1, srb);
            stack.restoreRegs(g);
        end;
    end;
    TranslatorTreeBuilder.EXPR_SNZ_TEST: begin
        reg1 := stack.getRegAt(1);
        reg2 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        sr2 := g.registerToString(reg2);
        stack.popRegs(1);
        g.writeInstruction('test', sr1, sr2);
        if (goIfTrueTo <> nil) and (goIfFalseTo <> nil) then begin
            stack.popRegs(1);
            stack.restoreRegs(g); { регистр флагов – без изменений }
            if goIfTrueTo.labelNumber = nodeLN + 1 then begin
                g.writeInstruction('jz',
                        LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
            end else
            if goIfFalseTo.labelNumber = nodeLN + 1 then begin
                g.writeInstruction('jnz',
                        LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
            end else begin
                g.writeInstruction('jz',
                        LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                g.writeInstruction('jmp',
                        LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
            end;
        end else begin
            reg1 := stack.changeToGPR32bit(0);
            srb := g.registerToString(R0B + (reg1 and $0f));
            sr1 := g.registerToString(reg1);
            g.writeInstruction('setnz', srb);
            g.writeInstruction('movzx', sr1, srb);
            stack.restoreRegs(g);
        end;
    end;
    TranslatorTreeBuilder.EXPR_SEQ_NULL: begin
        reg1 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        g.writeInstruction('test', sr1, sr1);
        if (goIfTrueTo <> nil) and (goIfFalseTo <> nil) then begin
            stack.popRegs(1);
            stack.restoreRegs(g); { регистр флагов – без изменений }
            if goIfTrueTo.labelNumber = nodeLN + 1 then begin
                g.writeInstruction('jnz',
                        LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
            end else
            if goIfFalseTo.labelNumber = nodeLN + 1 then begin
                g.writeInstruction('jz',
                        LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
            end else begin
                g.writeInstruction('jnz',
                        LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                g.writeInstruction('jmp',
                        LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
            end;
        end else begin
            reg1 := stack.changeToGPR32bit(0);
            srb := g.registerToString(R0B + (reg1 and $0f));
            sr1 := g.registerToString(reg1);
            g.writeInstruction('setz', srb);
            g.writeInstruction('movzx', sr1, srb);
            stack.restoreRegs(g);
        end;
    end;
    TranslatorTreeBuilder.EXPR_SNE_NULL: begin
        reg1 := stack.getRegAt(0);
        sr1 := g.registerToString(reg1);
        g.writeInstruction('test', sr1, sr1);
        if (goIfTrueTo <> nil) and (goIfFalseTo <> nil) then begin
            stack.popRegs(1);
            stack.restoreRegs(g); { регистр флагов – без изменений }
            if goIfTrueTo.labelNumber = nodeLN + 1 then begin
                g.writeInstruction('jz',
                        LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
            end else
            if goIfFalseTo.labelNumber = nodeLN + 1 then begin
                g.writeInstruction('jnz',
                        LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
            end else begin
                g.writeInstruction('jz',
                        LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                g.writeInstruction('jmp',
                        LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
            end;
        end else begin
            reg1 := stack.changeToGPR32bit(0);
            srb := g.registerToString(R0B + (reg1 and $0f));
            sr1 := g.registerToString(reg1);
            g.writeInstruction('setnz', srb);
            g.writeInstruction('movzx', sr1, srb);
            stack.restoreRegs(g);
        end;
    end;
    TranslatorTreeBuilder.ASSIGN: begin
        child := node.getChild(0) as SyntaxNode;
        mem := getMemoryLocation(child, stack, true);
        smm := mem.memoryToString(MNONE, 0);
        smmt := mem.memoryToString(MREAL, 0);
        reg2 := mem.getRegisterSource();
        srb := g.registerToString(R0B + (reg2 and $0f));
        srw := g.registerToString(R0W + (reg2 and $0f));
        sr2 := g.registerToString(reg2);
        buffer := child.dataType.kind;
        case buffer of
        TranslatorType.KIND_BOOLEAN: begin
            g.writeInstruction('mov', smm, srb);
            if (goIfTrueTo <> nil) and (goIfFalseTo <> nil) then begin
                g.writeInstruction('test', sr2, sr2);
                stack.restoreRegs(g); { регистр флагов – без изменений }
                if goIfTrueTo.labelNumber = nodeLN + 1 then begin
                    g.writeInstruction('jz',
                            LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                end else
                if goIfFalseTo.labelNumber = nodeLN + 1 then begin
                    g.writeInstruction('jnz',
                            LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
                end else begin
                    g.writeInstruction('jz',
                            LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                    g.writeInstruction('jmp',
                            LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
                end;
            end else begin
                if nodeType <> nil then begin
                    reg1 := stack.allocateGPR32bit(g);
                    if reg1 <> reg2 then begin
                        sr1 := g.registerToString(reg1);
                        g.writeInstruction('mov', sr1, sr2);
                    end;
                end;
                stack.restoreRegs(g);
            end;
        end;
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
        TranslatorType.KIND_SHORT, TranslatorType.KIND_INT: begin
            case buffer of
            TranslatorType.KIND_CHAR, TranslatorType.KIND_SHORT:
                g.writeInstruction('mov', smm, srw);
            TranslatorType.KIND_BYTE:
                g.writeInstruction('mov', smm, srb);
            TranslatorType.KIND_INT:
                g.writeInstruction('mov', smm, sr2);
            end;
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR32bit(g);
                if reg1 <> reg2 then begin
                    sr1 := g.registerToString(reg1);
                    g.writeInstruction('mov', sr1, sr2);
                end;
            end;
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_STRUCT, TranslatorType.KIND_ARRAY,
        TranslatorType.KIND_FUNC, TranslatorType.KIND_LONG: begin
            g.writeInstruction('mov', smm, sr2);
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR64bit(g);
                if reg1 <> reg2 then begin
                    sr1 := g.registerToString(reg1);
                    g.writeInstruction('mov', sr1, sr2);
                end;
            end;
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_ULTRA: begin
            g.writeInstruction('movdqu', smm, sr2);
            if nodeType <> nil then begin
                stack.pushReg(reg2);
            end;
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_FLOAT: begin
            g.writeInstruction('movss', smm, sr2);
            if nodeType <> nil then begin
                stack.pushReg(reg2);
            end;
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_DOUBLE: begin
            g.writeInstruction('movsd', smm, sr2);
            if nodeType <> nil then begin
                stack.pushReg(reg2);
            end;
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_REAL: begin
            g.writeInstruction('fstp', smmt);
            if nodeType <> nil then begin
                stack.pushReg(ST);
                g.writeInstruction('fld', smmt);
            end;
            stack.restoreRegs(g);
        end;
        TranslatorType.KIND_XVECTOR: begin
            g.writeInstruction('movups', smm, sr2);
            if nodeType <> nil then begin
                stack.pushReg(reg2);
            end;
            stack.restoreRegs(g);
        end;
        end;
    end;
    TranslatorTreeBuilder.ASSIGN_SADD,
    TranslatorTreeBuilder.ASSIGN_SSUB,
    TranslatorTreeBuilder.ASSIGN_SMULL: begin
        child := node.getChild(0) as SyntaxNode;
        mem := getMemoryLocation(child, stack, true);
        smm := mem.memoryToString(MNONE, 0);
        smmb := mem.memoryToString(MBYTE, 0);
        smmw := mem.memoryToString(MWORD, 0);
        smmt := mem.memoryToString(MREAL, 0);
        reg2 := mem.getRegisterSource();
        sr2 := g.registerToString(reg2);
        buffer := child.dataType.kind;
        case buffer of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
        TranslatorType.KIND_SHORT, TranslatorType.KIND_INT: begin
            case buffer of
            TranslatorType.KIND_CHAR:
                g.writeInstruction('movzx', sR3I, smmw);
            TranslatorType.KIND_BYTE:
                g.writeInstruction('movsx', sR3I, smmb);
            TranslatorType.KIND_SHORT:
                g.writeInstruction('movsx', sR3I, smmw);
            TranslatorType.KIND_INT:
                g.writeInstruction('mov', sR3I, smm);
            end;
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_SADD:
                g.writeInstruction('add', sR3I, sr2);
            TranslatorTreeBuilder.ASSIGN_SSUB:
                g.writeInstruction('sub', sR3I, sr2);
            TranslatorTreeBuilder.ASSIGN_SMULL:
                g.writeInstruction('imul', sR3I, sr2);
            end;
            case buffer of
            TranslatorType.KIND_BYTE:
                g.writeInstruction('mov', smm, sR3B);
            TranslatorType.KIND_SHORT, TranslatorType.KIND_CHAR:
                g.writeInstruction('mov', smm, sR3S);
            TranslatorType.KIND_INT:
                g.writeInstruction('mov', smm, sR3I);
            end;
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('mov', sr1, sR3I);
            end;
        end;
        TranslatorType.KIND_LONG: begin
            g.writeInstruction('mov', sR3L, smm);
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_SADD:
                g.writeInstruction('add', sR3L, sr2);
            TranslatorTreeBuilder.ASSIGN_SSUB:
                g.writeInstruction('sub', sR3L, sr2);
            TranslatorTreeBuilder.ASSIGN_SMULL:
                g.writeInstruction('imul', sR3L, sr2);
            end;
            g.writeInstruction('mov', smm, sR3L);
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR64bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('mov', sr1, sR3L);
            end;
        end;
        TranslatorType.KIND_FLOAT: begin
            g.writeInstruction('movss', sXMM12, smm);
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_SADD:
                g.writeInstruction('addss', sXMM12, sr2);
            TranslatorTreeBuilder.ASSIGN_SSUB:
                g.writeInstruction('subss', sXMM12, sr2);
            TranslatorTreeBuilder.ASSIGN_SMULL:
                g.writeInstruction('mulss', sXMM12, sr2);
            end;
            g.writeInstruction('movss', smm, sXMM12);
            if nodeType <> nil then begin
                stack.pushReg(reg2);
                g.writeInstruction('movss', sr2, sXMM12);
            end;
        end;
        TranslatorType.KIND_DOUBLE: begin
            g.writeInstruction('movsd', sXMM12, smm);
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_SADD:
                g.writeInstruction('addsd', sXMM12, sr2);
            TranslatorTreeBuilder.ASSIGN_SSUB:
                g.writeInstruction('subsd', sXMM12, sr2);
            TranslatorTreeBuilder.ASSIGN_SMULL:
                g.writeInstruction('mulsd', sXMM12, sr2);
            end;
            g.writeInstruction('movsd', smm, sXMM12);
            if nodeType <> nil then begin
                stack.pushReg(reg2);
                g.writeInstruction('movsd', sr2, sXMM12);
            end;
        end;
        TranslatorType.KIND_REAL: begin
            stack.pushReg(ST);
            stack.allocateFPU(1, g);
            g.writeInstruction('fld', smmt);
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_SADD:
                g.writeInstruction('fadd', sST0, sST1);
            TranslatorTreeBuilder.ASSIGN_SSUB:
                g.writeInstruction('fsub', sST0, sST1);
            TranslatorTreeBuilder.ASSIGN_SMULL:
                g.writeInstruction('fmul', sST0, sST1);
            end;
            g.writeInstruction('fstp', sST1);
            g.writeInstruction('fstp', smmt);
            if nodeType <> nil then begin
                g.writeInstruction('fld', smmt);
                stack.popRegs(1);
            end else begin
                stack.popRegs(2);
            end;
        end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.ASSIGN_SDIVS,
    TranslatorTreeBuilder.ASSIGN_SDIVU: begin
        child := node.getChild(0) as SyntaxNode;
        mem := getMemoryLocation(child, stack, true);
        smm := mem.memoryToString(MNONE, 0);
        smmb := mem.memoryToString(MBYTE, 0);
        smmw := mem.memoryToString(MWORD, 0);
        smmt := mem.memoryToString(MREAL, 0);
        reg2 := mem.getRegisterSource();
        sr2 := g.registerToString(reg2);
        buffer := child.dataType.kind;
        case buffer of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
        TranslatorType.KIND_SHORT, TranslatorType.KIND_INT: begin
            g.writeInstruction('mov', sR3L, sR0L);
            if reg2 = R0D then begin
                reg2 := R3D;
                sr2 := g.registerToString(reg2);
            end;
            case buffer of
            TranslatorType.KIND_CHAR:
                g.writeInstruction('movzx', sR0I, smmw);
            TranslatorType.KIND_BYTE:
                g.writeInstruction('movsx', sR0I, smmb);
            TranslatorType.KIND_SHORT:
                g.writeInstruction('movsx', sR0I, smmw);
            TranslatorType.KIND_INT:
                g.writeInstruction('mov', sR0I, smm);
            end;
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_SDIVS: begin
                g.writeInstruction('cdq');
                g.writeInstruction('idiv', sr2);
            end;
            TranslatorTreeBuilder.ASSIGN_SDIVU: begin
                g.writeInstruction('xor', sR2I, sR2I);
                g.writeInstruction('div', sr2);
            end;
            end;
            case buffer of
            TranslatorType.KIND_BYTE:
                g.writeInstruction('mov', smm, sR0B);
            TranslatorType.KIND_SHORT, TranslatorType.KIND_CHAR:
                g.writeInstruction('mov', smm, sR0S);
            TranslatorType.KIND_INT:
                g.writeInstruction('mov', smm, sR0I);
            end;
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('mov', sr1, sR0I);
            end;
            g.writeInstruction('mov', sR0L, sR3L);
        end;
        TranslatorType.KIND_LONG: begin
            g.writeInstruction('mov', sR3L, sR0L);
            if reg2 = R0 then begin
                reg2 := R3;
                sr2 := g.registerToString(reg2);
            end;
            g.writeInstruction('mov', sR0L, smm);
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_SDIVS: begin
                g.writeInstruction('cqo');
                g.writeInstruction('idiv', sr2);
            end;
            TranslatorTreeBuilder.ASSIGN_SDIVU: begin
                g.writeInstruction('xor', sR2L, sR2L);
                g.writeInstruction('div', sr2);
            end;
            end;
            g.writeInstruction('mov', smm, sR0L);
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR64bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('mov', sr1, sR0L);
            end;
            g.writeInstruction('mov', sR0L, sR3L);
        end;
        TranslatorType.KIND_FLOAT: begin
            g.writeInstruction('movss', sXMM12, smm);
            g.writeInstruction('divss', sXMM12, sr2);
            g.writeInstruction('movss', smm, sXMM12);
            if nodeType <> nil then begin
                stack.pushReg(reg2);
                g.writeInstruction('movss', sr2, sXMM12);
            end;
        end;
        TranslatorType.KIND_DOUBLE: begin
            g.writeInstruction('movsd', sXMM12, smm);
            g.writeInstruction('divsd', sXMM12, sr2);
            g.writeInstruction('movsd', smm, sXMM12);
            if nodeType <> nil then begin
                stack.pushReg(reg2);
                g.writeInstruction('movsd', sr2, sXMM12);
            end;
        end;
        TranslatorType.KIND_REAL: begin
            stack.pushReg(ST);
            stack.allocateFPU(1, g);
            g.writeInstruction('fld', smmt);
            g.writeInstruction('fdiv', sST0, sST1);
            g.writeInstruction('fstp', sST1);
            g.writeInstruction('fstp', smmt);
            if nodeType <> nil then begin
                g.writeInstruction('fld', smmt);
                stack.popRegs(1);
            end else begin
                stack.popRegs(2);
            end;
        end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.ASSIGN_SREMS,
    TranslatorTreeBuilder.ASSIGN_SREMU: begin
        child := node.getChild(0) as SyntaxNode;
        mem := getMemoryLocation(child, stack, true);
        smm := mem.memoryToString(MNONE, 0);
        smmb := mem.memoryToString(MBYTE, 0);
        smmw := mem.memoryToString(MWORD, 0);
        smmt := mem.memoryToString(MREAL, 0);
        reg2 := mem.getRegisterSource();
        sr2 := g.registerToString(reg2);
        buffer := child.dataType.kind;
        case buffer of
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
        TranslatorType.KIND_SHORT, TranslatorType.KIND_INT: begin
            g.writeInstruction('mov', sR3L, sR0L);
            if reg2 = R0D then begin
                reg2 := R3D;
                sr2 := g.registerToString(reg2);
            end;
            case buffer of
            TranslatorType.KIND_CHAR:
                g.writeInstruction('movzx', sR0I, smmw);
            TranslatorType.KIND_BYTE:
                g.writeInstruction('movsx', sR0I, smmb);
            TranslatorType.KIND_SHORT:
                g.writeInstruction('movsx', sR0I, smmw);
            TranslatorType.KIND_INT:
                g.writeInstruction('mov', sR0I, smm);
            end;
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_SREMS: begin
                g.writeInstruction('cdq');
                g.writeInstruction('idiv', sr2);
            end;
            TranslatorTreeBuilder.ASSIGN_SREMU: begin
                g.writeInstruction('xor', sR2I, sR2I);
                g.writeInstruction('div', sr2);
            end;
            end;
            case buffer of
            TranslatorType.KIND_BYTE:
                g.writeInstruction('mov', smm, sR2B);
            TranslatorType.KIND_SHORT, TranslatorType.KIND_CHAR:
                g.writeInstruction('mov', smm, sR2S);
            TranslatorType.KIND_INT:
                g.writeInstruction('mov', smm, sR2I);
            end;
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('mov', sr1, sR2I);
            end;
            g.writeInstruction('mov', sR0L, sR3L);
        end;
        TranslatorType.KIND_LONG: begin
            g.writeInstruction('mov', sR3L, sR0L);
            if reg2 = R0 then begin
                reg2 := R3;
                sr2 := g.registerToString(reg2);
            end;
            g.writeInstruction('mov', sR0L, smm);
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_SREMS: begin
                g.writeInstruction('cqo');
                g.writeInstruction('idiv', sr2);
            end;
            TranslatorTreeBuilder.ASSIGN_SREMU: begin
                g.writeInstruction('xor', sR2L, sR2L);
                g.writeInstruction('div', sr2);
            end;
            end;
            g.writeInstruction('mov', smm, sR2L);
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR64bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('mov', sr1, sR2L);
            end;
            g.writeInstruction('mov', sR0L, sR3L);
        end;
        TranslatorType.KIND_FLOAT, TranslatorType.KIND_DOUBLE, TranslatorType.KIND_REAL: begin
            regInUse := stack.isUsedRegister(R0D);
            case buffer of
            TranslatorType.KIND_FLOAT:
                smmt := mem.memoryToString(MFLOAT, 0);
            TranslatorType.KIND_DOUBLE:
                smmt := mem.memoryToString(MDOUBLE, 0);
            TranslatorType.KIND_REAL:
                smmt := mem.memoryToString(MREAL, 0);
            else
                smmt := '';
            end;
            stack.pushReg(ST);
            stack.allocateFPU(1, g);
            if regInUse then begin
                g.writeInstruction('mov', sR3L, sR0L);
            end;
            g.writeInstruction('fld', smmt);
            g.writeLabelShort(LABEL_ANONYMOUS);
            g.writeInstruction('fprem');
            g.writeInstruction('fnstsw', sR0S);
            g.writeInstruction('test', sR0I, g.immediateToStringShort($0400));
            g.writeInstruction('jnz', LABEL_PRECEDING);
            g.writeInstruction('fstp', sST1);
            g.writeInstruction('fstp', smmt);
            if nodeType <> nil then begin
                g.writeInstruction('fld', smmt);
                stack.popRegs(1);
            end else begin
                stack.popRegs(2);
            end;
            if regInUse then begin
                g.writeInstruction('mov', sR0L, sR3L);
            end;
        end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.ASSIGN_QMULL,
    TranslatorTreeBuilder.ASSIGN_QADD,
    TranslatorTreeBuilder.ASSIGN_QSUB: begin
        child := node.getChild(0) as SyntaxNode;
        mem := getMemoryLocation(child, stack, true);
        smm := mem.memoryToString(MNONE, 0);
        reg2 := mem.getRegisterSource();
        sr2 := g.registerToString(reg2);
        case child.dataType.kind of
        TranslatorType.KIND_LONG: begin
            g.writeInstruction('movq', sXMM12, smm);
            g.writeInstruction('movq', sXMM13, sr2);
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_QMULL:
                g.writeInstruction('pmullw', sXMM12, sXMM13);
            TranslatorTreeBuilder.ASSIGN_QADD:
                g.writeInstruction('paddw', sXMM12, sXMM13);
            TranslatorTreeBuilder.ASSIGN_QSUB:
                g.writeInstruction('psubw', sXMM12, sXMM13);
            end;
            g.writeInstruction('movq', smm, sXMM12);
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR64bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movq', sr1, sXMM12);
            end;
        end;
        TranslatorType.KIND_ULTRA: begin
            g.writeInstruction('movdqu', sXMM12, smm);
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_QMULL:
                if extension < TranslatorTreeBuilder.EXTENSION_SSE4_1 then begin
                    g.writeInstruction('movdqu', sXMM13, sr2);
                    g.writeInstruction('call', FUNCTION_ULTRA_QMULL);
                end else begin
                    g.writeInstruction('pmulld', sXMM12, sr2);
                end;
            TranslatorTreeBuilder.ASSIGN_QADD:
                g.writeInstruction('paddd', sXMM12, sr2);
            TranslatorTreeBuilder.ASSIGN_QSUB:
                g.writeInstruction('psubd', sXMM12, sr2);
            end;
            g.writeInstruction('movdqu', smm, sXMM12);
            if nodeType <> nil then begin
                stack.pushReg(reg2);
                g.writeInstruction('movdqu', sr2, sXMM12);
            end;
        end;
        TranslatorType.KIND_XVECTOR: begin
            g.writeInstruction('movups', sXMM12, smm);
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_QMULL:
                g.writeInstruction('mulps', sXMM12, sr2);
            TranslatorTreeBuilder.ASSIGN_QADD:
                g.writeInstruction('addps', sXMM12, sr2);
            TranslatorTreeBuilder.ASSIGN_QSUB:
                g.writeInstruction('subps', sXMM12, sr2);
            end;
            g.writeInstruction('movups', smm, sXMM12);
            if nodeType <> nil then begin
                stack.pushReg(reg2);
                g.writeInstruction('movups', sr2, sXMM12);
            end;
        end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.ASSIGN_QMULH: begin
        child := node.getChild(0) as SyntaxNode;
        mem := getMemoryLocation(child, stack, true);
        smm := mem.memoryToString(MNONE, 0);
        reg2 := mem.getRegisterSource();
        sr2 := g.registerToString(reg2);
        case child.dataType.kind of
        TranslatorType.KIND_LONG: begin
            g.writeInstruction('movq', sXMM12, smm);
            g.writeInstruction('movq', sXMM13, sr2);
            g.writeInstruction('pmulhuw', sXMM12, sXMM13);
            g.writeInstruction('movq', smm, sXMM12);
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR64bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movq', sr1, sXMM12);
            end;
        end;
        TranslatorType.KIND_ULTRA: begin
            g.writeInstruction('movdqu', sXMM12, smm);
            g.writeInstruction('movdqu', sXMM13, sr2);
            g.writeInstruction('call', FUNCTION_ULTRA_QMULH);
            g.writeInstruction('movdqu', smm, sXMM12);
            if nodeType <> nil then begin
                stack.pushReg(reg2);
                g.writeInstruction('movdqu', sr2, sXMM12);
            end;
        end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.ASSIGN_QDIV: begin
        child := node.getChild(0) as SyntaxNode;
        mem := getMemoryLocation(child, stack, true);
        smm := mem.memoryToString(MNONE, 0);
        reg2 := mem.getRegisterSource();
        sr2 := g.registerToString(reg2);
        g.writeInstruction('movups', sXMM12, smm);
        g.writeInstruction('divps', sXMM12, sr2);
        g.writeInstruction('movups', smm, sXMM12);
        if nodeType <> nil then begin
            stack.pushReg(reg2);
            g.writeInstruction('movups', sr2, sXMM12);
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.ASSIGN_QMULHS,
    TranslatorTreeBuilder.ASSIGN_QADDS,
    TranslatorTreeBuilder.ASSIGN_QADDUS,
    TranslatorTreeBuilder.ASSIGN_QSUBS,
    TranslatorTreeBuilder.ASSIGN_QSUBUS: begin
        child := node.getChild(0) as SyntaxNode;
        mem := getMemoryLocation(child, stack, true);
        smm := mem.memoryToString(MNONE, 0);
        reg2 := mem.getRegisterSource();
        sr2 := g.registerToString(reg2);
        g.writeInstruction('movq', sXMM12, smm);
        g.writeInstruction('movq', sXMM13, sr2);
        case nodeValue of
        TranslatorTreeBuilder.ASSIGN_QMULHS:
            if extension < TranslatorTreeBuilder.EXTENSION_SSSE3 then begin
                g.writeInstruction('call', FUNCTION_LONG_QMULHS);
            end else begin
                g.writeInstruction('pmulhrsw', sXMM12, sXMM13);
            end;
        TranslatorTreeBuilder.EXPR_QADDS:
            g.writeInstruction('paddsw', sXMM12, sXMM13);
        TranslatorTreeBuilder.EXPR_QADDUS:
            g.writeInstruction('paddusw', sXMM12, sXMM13);
        TranslatorTreeBuilder.EXPR_QSUBS:
            g.writeInstruction('psubsw', sXMM12, sXMM13);
        TranslatorTreeBuilder.EXPR_QSUBUS:
            g.writeInstruction('psubusw', sXMM12, sXMM13);
        end;
        g.writeInstruction('movq', smm, sXMM12);
        if nodeType <> nil then begin
            reg1 := stack.allocateGPR64bit(g);
            sr1 := g.registerToString(reg1);
            g.writeInstruction('movq', sr1, sXMM12);
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.ASSIGN_OMULL,
    TranslatorTreeBuilder.ASSIGN_OMULH,
    TranslatorTreeBuilder.ASSIGN_OMULHS,
    TranslatorTreeBuilder.ASSIGN_OADD,
    TranslatorTreeBuilder.ASSIGN_OADDS,
    TranslatorTreeBuilder.ASSIGN_OADDUS,
    TranslatorTreeBuilder.ASSIGN_OSUB,
    TranslatorTreeBuilder.ASSIGN_OSUBS,
    TranslatorTreeBuilder.ASSIGN_OSUBUS,
    TranslatorTreeBuilder.ASSIGN_OGT,
    TranslatorTreeBuilder.ASSIGN_OGE,
    TranslatorTreeBuilder.ASSIGN_OLT,
    TranslatorTreeBuilder.ASSIGN_OLE,
    TranslatorTreeBuilder.ASSIGN_OEQ,
    TranslatorTreeBuilder.ASSIGN_ONE: begin
        child := node.getChild(0) as SyntaxNode;
        mem := getMemoryLocation(child, stack, true);
        smm := mem.memoryToString(MNONE, 0);
        reg2 := mem.getRegisterSource();
        sr2 := g.registerToString(reg2);
        g.writeInstruction('movdqu', sXMM12, smm);
        case nodeValue of
        TranslatorTreeBuilder.ASSIGN_OMULL: begin
            g.writeInstruction('pmullw', sXMM12, sr2);
        end;
        TranslatorTreeBuilder.ASSIGN_OMULH: begin
            g.writeInstruction('pmulhuw', sXMM12, sr2);
        end;
        TranslatorTreeBuilder.ASSIGN_OMULHS: begin
            if extension < TranslatorTreeBuilder.EXTENSION_SSSE3 then begin
                g.writeInstruction('movdqu', sXMM13, sr2);
                g.writeInstruction('call', FUNCTION_ULTRA_OMULHS);
            end else begin
                g.writeInstruction('pmulhrsw', sXMM12, sr2);
            end;
        end;
        TranslatorTreeBuilder.ASSIGN_OADD: begin
            g.writeInstruction('paddw', sXMM12, sr2);
        end;
        TranslatorTreeBuilder.ASSIGN_OADDS: begin
            g.writeInstruction('paddsw', sXMM12, sr2);
        end;
        TranslatorTreeBuilder.ASSIGN_OADDUS: begin
            g.writeInstruction('paddusw', sXMM12, sr2);
        end;
        TranslatorTreeBuilder.ASSIGN_OSUB: begin
            g.writeInstruction('psubw', sXMM12, sr2);
        end;
        TranslatorTreeBuilder.ASSIGN_OSUBS: begin
            g.writeInstruction('psubsw', sXMM12, sr2);
        end;
        TranslatorTreeBuilder.ASSIGN_OSUBUS: begin
            g.writeInstruction('psubusw', sXMM12, sr2);
        end;
        TranslatorTreeBuilder.ASSIGN_OGT: begin
            g.writeInstruction('pcmpgtw', sXMM12, sr2);
        end;
        TranslatorTreeBuilder.ASSIGN_OGE: begin
            g.writeInstruction('pcmpgtw', sr2, sXMM12);
            g.writeInstruction('movdqu', sXMM12, sr2);
            g.writeInstruction('movdqu', sr2, g.memoryToString(MNONE, LABEL_POOL_ULTRA_CONTENT,
                    programmeXUltras.indexAcquire(ultraBuild(-1, -1)) * 16));
            g.writeInstruction('pxor', sXMM12, sr2);
        end;
        TranslatorTreeBuilder.ASSIGN_OLT: begin
            g.writeInstruction('pcmpgtw', sr2, sXMM12);
            g.writeInstruction('movdqu', sXMM12, sr2);
        end;
        TranslatorTreeBuilder.ASSIGN_OLE: begin
            g.writeInstruction('pcmpgtw', sXMM12, sr2);
            g.writeInstruction('movdqu', sr2, g.memoryToString(MNONE, LABEL_POOL_ULTRA_CONTENT,
                    programmeXUltras.indexAcquire(ultraBuild(-1, -1)) * 16));
            g.writeInstruction('pxor', sXMM12, sr2);
        end;
        TranslatorTreeBuilder.ASSIGN_OEQ: begin
            g.writeInstruction('pcmpeqw', sXMM12, sr2);
        end;
        TranslatorTreeBuilder.ASSIGN_ONE: begin
            g.writeInstruction('pcmpeqw', sXMM12, sr2);
            g.writeInstruction('movdqu', sr2, g.memoryToString(MNONE, LABEL_POOL_ULTRA_CONTENT,
                    programmeXUltras.indexAcquire(ultraBuild(-1, -1)) * 16));
            g.writeInstruction('pxor', sXMM12, sr2);
        end;
        end;
        g.writeInstruction('movdqu', smm, sXMM12);
        if nodeType <> nil then begin
            stack.pushReg(reg2);
            g.writeInstruction('movdqu', sr2, sXMM12);
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.ASSIGN_SSLL,
    TranslatorTreeBuilder.ASSIGN_SSRA,
    TranslatorTreeBuilder.ASSIGN_SSRL: begin
        child := node.getChild(1) as SyntaxNode;
        if child.value <> TranslatorTreeBuilder.EXPR_VALUE_INT then begin
            child := node.getChild(0) as SyntaxNode;
            mem := getMemoryLocation(child, stack, true);
            smm := mem.memoryToString(MNONE, 0);
            smmb := mem.memoryToString(MBYTE, 0);
            smmw := mem.memoryToString(MWORD, 0);
            reg2 := mem.getRegisterSource();
            sr2 := g.registerToString(reg2);
            buffer := child.dataType.kind;
            g.writeInstruction('mov', sR1I, sr2);
            case buffer of
            TranslatorType.KIND_CHAR:
                g.writeInstruction('movzx', sR3I, smmw);
            TranslatorType.KIND_BYTE:
                g.writeInstruction('movsx', sR3I, smmb);
            TranslatorType.KIND_SHORT:
                g.writeInstruction('movsx', sR3I, smmw);
            TranslatorType.KIND_INT:
                g.writeInstruction('mov', sR3I, smm);
            TranslatorType.KIND_LONG:
                g.writeInstruction('mov', sR3L, smm);
            end;
            if buffer <> TranslatorType.KIND_LONG then begin
                case nodeValue of
                TranslatorTreeBuilder.ASSIGN_SSLL:
                    g.writeInstruction('shl', sR3I, sR1B);
                TranslatorTreeBuilder.ASSIGN_SSRA:
                    g.writeInstruction('sar', sR3I, sR1B);
                TranslatorTreeBuilder.ASSIGN_SSRL:
                    g.writeInstruction('shr', sR3I, sR1B);
                end;
            end else begin
                case nodeValue of
                TranslatorTreeBuilder.ASSIGN_SSLL:
                    g.writeInstruction('shl', sR3L, sR1B);
                TranslatorTreeBuilder.ASSIGN_SSRA:
                    g.writeInstruction('sar', sR3L, sR1B);
                TranslatorTreeBuilder.ASSIGN_SSRL:
                    g.writeInstruction('shr', sR3L, sR1B);
                end;
            end;
        end else begin
            buffer := (child.associate as IntegerAsObject).byteValue();
            child := node.getChild(0) as SyntaxNode;
            mem := getMemoryLocation(child, stack, false);
            smm := mem.memoryToString(MNONE, 0);
            smmb := mem.memoryToString(MBYTE, 0);
            smmw := mem.memoryToString(MWORD, 0);
            simm := g.immediateToStringByte(buffer);
            buffer := child.dataType.kind;
            case buffer of
            TranslatorType.KIND_CHAR:
                g.writeInstruction('movzx', sR3I, smmw);
            TranslatorType.KIND_BYTE:
                g.writeInstruction('movsx', sR3I, smmb);
            TranslatorType.KIND_SHORT:
                g.writeInstruction('movsx', sR3I, smmw);
            TranslatorType.KIND_INT:
                g.writeInstruction('mov', sR3I, smm);
            TranslatorType.KIND_LONG:
                g.writeInstruction('mov', sR3L, smm);
            end;
            if buffer <> TranslatorType.KIND_LONG then begin
                case nodeValue of
                TranslatorTreeBuilder.ASSIGN_SSLL:
                    g.writeInstruction('shl', sR3I, simm);
                TranslatorTreeBuilder.ASSIGN_SSRA:
                    g.writeInstruction('sar', sR3I, simm);
                TranslatorTreeBuilder.ASSIGN_SSRL:
                    g.writeInstruction('shr', sR3I, simm);
                end;
            end else begin
                case nodeValue of
                TranslatorTreeBuilder.ASSIGN_SSLL:
                    g.writeInstruction('shl', sR3L, simm);
                TranslatorTreeBuilder.ASSIGN_SSRA:
                    g.writeInstruction('sar', sR3L, simm);
                TranslatorTreeBuilder.ASSIGN_SSRL:
                    g.writeInstruction('shr', sR3L, simm);
                end;
            end;
        end;
        case buffer of
        TranslatorType.KIND_BYTE:
            g.writeInstruction('mov', smm, sR3B);
        TranslatorType.KIND_SHORT, TranslatorType.KIND_CHAR:
            g.writeInstruction('mov', smm, sR3S);
        TranslatorType.KIND_INT:
            g.writeInstruction('mov', smm, sR3I);
        TranslatorType.KIND_LONG:
            g.writeInstruction('mov', smm, sR3L);
        end;
        if nodeType <> nil then begin
            if buffer <> TranslatorType.KIND_LONG then begin
                reg1 := stack.allocateGPR32bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('mov', sr1, sR3I);
            end else begin
                reg1 := stack.allocateGPR64bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('mov', sr1, sR3L);
            end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.ASSIGN_QSLL,
    TranslatorTreeBuilder.ASSIGN_QSRA,
    TranslatorTreeBuilder.ASSIGN_QSRL: begin
        child := node.getChild(1) as SyntaxNode;
        if child.value <> TranslatorTreeBuilder.EXPR_VALUE_INT then begin
            child := node.getChild(0) as SyntaxNode;
            mem := getMemoryLocation(child, stack, true);
            smm := mem.memoryToString(MNONE, 0);
            reg2 := mem.getRegisterSource();
            sr2 := g.registerToString(reg2);
            buffer := child.dataType.kind;
            g.writeInstruction('movd', sXMM13, sr2);
            case buffer of
            TranslatorType.KIND_LONG: begin
                g.writeInstruction('movq', sXMM12, smm);
                case nodeValue of
                TranslatorTreeBuilder.ASSIGN_QSLL:
                    g.writeInstruction('psllw', sXMM12, sXMM13);
                TranslatorTreeBuilder.ASSIGN_QSRA:
                    g.writeInstruction('psraw', sXMM12, sXMM13);
                TranslatorTreeBuilder.ASSIGN_QSRL:
                    g.writeInstruction('psrlw', sXMM12, sXMM13);
                end;
            end;
            TranslatorType.KIND_ULTRA: begin
                g.writeInstruction('movdqu', sXMM12, smm);
                case nodeValue of
                TranslatorTreeBuilder.ASSIGN_QSLL:
                    g.writeInstruction('pslld', sXMM12, sXMM13);
                TranslatorTreeBuilder.ASSIGN_QSRA:
                    g.writeInstruction('psrad', sXMM12, sXMM13);
                TranslatorTreeBuilder.ASSIGN_QSRL:
                    g.writeInstruction('psrld', sXMM12, sXMM13);
                end;
            end;
            end;
        end else begin
            buffer := (child.associate as IntegerAsObject).byteValue();
            child := node.getChild(0) as SyntaxNode;
            mem := getMemoryLocation(child, stack, false);
            smm := mem.memoryToString(MNONE, 0);
            simm := g.immediateToStringByte(buffer);
            buffer := child.dataType.kind;
            case buffer of
            TranslatorType.KIND_LONG: begin
                g.writeInstruction('movq', sXMM12, smm);
                case nodeValue of
                TranslatorTreeBuilder.ASSIGN_QSLL:
                    g.writeInstruction('psllw', sXMM12, simm);
                TranslatorTreeBuilder.ASSIGN_QSRA:
                    g.writeInstruction('psraw', sXMM12, simm);
                TranslatorTreeBuilder.ASSIGN_QSRL:
                    g.writeInstruction('psrlw', sXMM12, simm);
                end;
            end;
            TranslatorType.KIND_ULTRA: begin
                g.writeInstruction('movdqu', sXMM12, smm);
                case nodeValue of
                TranslatorTreeBuilder.ASSIGN_QSLL:
                    g.writeInstruction('pslld', sXMM12, simm);
                TranslatorTreeBuilder.ASSIGN_QSRA:
                    g.writeInstruction('psrad', sXMM12, simm);
                TranslatorTreeBuilder.ASSIGN_QSRL:
                    g.writeInstruction('psrld', sXMM12, simm);
                end;
            end;
            end;
        end;
        case buffer of
        TranslatorType.KIND_LONG:
            g.writeInstruction('movq', smm, sXMM12);
        TranslatorType.KIND_ULTRA:
            g.writeInstruction('movdqu', smm, sXMM12);
        end;
        if nodeType <> nil then begin
            if buffer <> TranslatorType.KIND_LONG then begin
                reg1 := stack.allocateGPR64bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movq', sr1, sXMM12);
            end else begin
                reg1 := stack.allocateXMM(XPINT, g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('movdqu', sr1, sXMM12);
            end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.ASSIGN_OSLL,
    TranslatorTreeBuilder.ASSIGN_OSRA,
    TranslatorTreeBuilder.ASSIGN_OSRL: begin
        child := node.getChild(1) as SyntaxNode;
        if child.value <> TranslatorTreeBuilder.EXPR_VALUE_INT then begin
            child := node.getChild(0) as SyntaxNode;
            mem := getMemoryLocation(child, stack, true);
            smm := mem.memoryToString(MNONE, 0);
            reg2 := mem.getRegisterSource();
            sr2 := g.registerToString(reg2);
            buffer := child.dataType.kind;
            g.writeInstruction('movd', sXMM13, sr2);
            g.writeInstruction('movdqu', sXMM12, smm);
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_OSLL:
                g.writeInstruction('psllw', sXMM12, sXMM13);
            TranslatorTreeBuilder.ASSIGN_OSRA:
                g.writeInstruction('psraw', sXMM12, sXMM13);
            TranslatorTreeBuilder.ASSIGN_OSRL:
                g.writeInstruction('psrlw', sXMM12, sXMM13);
            end;
        end else begin
            buffer := (child.associate as IntegerAsObject).byteValue();
            child := node.getChild(0) as SyntaxNode;
            mem := getMemoryLocation(child, stack, false);
            smm := mem.memoryToString(MNONE, 0);
            simm := g.immediateToStringByte(buffer);
            g.writeInstruction('movdqu', sXMM12, smm);
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_OSLL:
                g.writeInstruction('psllw', sXMM12, simm);
            TranslatorTreeBuilder.ASSIGN_OSRA:
                g.writeInstruction('psraw', sXMM12, simm);
            TranslatorTreeBuilder.ASSIGN_OSRL:
                g.writeInstruction('psrlw', sXMM12, simm);
            end;
        end;
        g.writeInstruction('movdqu', smm, sXMM12);
        if nodeType <> nil then begin
            reg1 := stack.allocateXMM(XPINT, g);
            sr1 := g.registerToString(reg1);
            g.writeInstruction('movdqu', sr1, sXMM12);
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.ASSIGN_QGT,
    TranslatorTreeBuilder.ASSIGN_QGE,
    TranslatorTreeBuilder.ASSIGN_QLT,
    TranslatorTreeBuilder.ASSIGN_QLE,
    TranslatorTreeBuilder.ASSIGN_QEQ,
    TranslatorTreeBuilder.ASSIGN_QNE: begin
        child := node.getChild(0) as SyntaxNode;
        mem := getMemoryLocation(child, stack, true);
        smm := mem.memoryToString(MNONE, 0);
        reg2 := mem.getRegisterSource();
        sr2 := g.registerToString(reg2);
        case child.dataType.kind of
        TranslatorType.KIND_LONG: begin
            g.writeInstruction('movq', sXMM12, smm);
            g.writeInstruction('movq', sXMM13, sr2);
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_QGT: begin
                g.writeInstruction('pcmpgtw', sXMM12, sXMM13);
                g.writeInstruction('movq', sR3L, sXMM12);
            end;
            TranslatorTreeBuilder.ASSIGN_QGE: begin
                g.writeInstruction('pcmpgtw', sXMM13, sXMM12);
                g.writeInstruction('movq', sR3L, sXMM13);
                g.writeInstruction('xor', sR3L, g.immediateToString(-1));
            end;
            TranslatorTreeBuilder.ASSIGN_QLT: begin
                g.writeInstruction('pcmpgtw', sXMM13, sXMM12);
                g.writeInstruction('movq', sR3L, sXMM13);
            end;
            TranslatorTreeBuilder.ASSIGN_QLE: begin
                g.writeInstruction('pcmpgtw', sXMM12, sXMM13);
                g.writeInstruction('movq', sR3L, sXMM12);
                g.writeInstruction('xor', sR3L, g.immediateToString(-1));
            end;
            TranslatorTreeBuilder.ASSIGN_QEQ: begin
                g.writeInstruction('pcmpeqw', sXMM12, sXMM13);
                g.writeInstruction('movq', sR3L, sXMM12);
            end;
            TranslatorTreeBuilder.ASSIGN_QNE: begin
                g.writeInstruction('pcmpeqw', sXMM12, sXMM13);
                g.writeInstruction('movq', sR3L, sXMM12);
                g.writeInstruction('xor', sR3L, g.immediateToString(-1));
            end;
            end;
            g.writeInstruction('mov', smm, sR3L);
            if nodeType <> nil then begin
                reg1 := stack.allocateGPR64bit(g);
                sr1 := g.registerToString(reg1);
                g.writeInstruction('mov', sr1, sR3L);
            end;
        end;
        TranslatorType.KIND_ULTRA: begin
            g.writeInstruction('movdqu', sXMM12, smm);
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_QGT: begin
                g.writeInstruction('pcmpgtd', sXMM12, sr2);
            end;
            TranslatorTreeBuilder.EXPR_QGE: begin
                g.writeInstruction('pcmpgtd', sr2, sXMM12);
                g.writeInstruction('movdqu', sXMM12, sr2);
                g.writeInstruction('movdqu', sr2, g.memoryToString(MNONE, LABEL_POOL_ULTRA_CONTENT,
                        programmeXUltras.indexAcquire(ultraBuild(-1, -1)) * 16));
                g.writeInstruction('pxor', sXMM12, sr2);
            end;
            TranslatorTreeBuilder.EXPR_QLT: begin
                g.writeInstruction('pcmpgtd', sr2, sXMM12);
                g.writeInstruction('movdqu', sXMM12, sr2);
            end;
            TranslatorTreeBuilder.EXPR_QLE: begin
                g.writeInstruction('pcmpgtd', sXMM12, sr2);
                g.writeInstruction('movdqu', sr2, g.memoryToString(MNONE, LABEL_POOL_ULTRA_CONTENT,
                        programmeXUltras.indexAcquire(ultraBuild(-1, -1)) * 16));
                g.writeInstruction('pxor', sXMM12, sr2);
            end;
            TranslatorTreeBuilder.EXPR_QEQ: begin
                g.writeInstruction('pcmpeqd', sXMM12, sr2);
            end;
            TranslatorTreeBuilder.EXPR_QNE: begin
                g.writeInstruction('pcmpeqd', sXMM12, sr2);
                g.writeInstruction('movdqu', sr2, g.memoryToString(MNONE, LABEL_POOL_ULTRA_CONTENT,
                        programmeXUltras.indexAcquire(ultraBuild(-1, -1)) * 16));
                g.writeInstruction('pxor', sXMM12, sr2);
            end;
            end;
            g.writeInstruction('movdqu', smm, sXMM12);
            if nodeType <> nil then begin
                stack.pushReg(reg2);
                g.writeInstruction('movdqu', sr2, sXMM12);
            end;
        end;
        end;
        stack.restoreRegs(g);
    end;
    TranslatorTreeBuilder.ASSIGN_SANDB,
    TranslatorTreeBuilder.ASSIGN_SXORB,
    TranslatorTreeBuilder.ASSIGN_SORB: begin
        child := node.getChild(0) as SyntaxNode;
        mem := getMemoryLocation(child, stack, true);
        smm := mem.memoryToString(MNONE, 0);
        smmb := mem.memoryToString(MBYTE, 0);
        smmw := mem.memoryToString(MWORD, 0);
        reg2 := mem.getRegisterSource();
        sr2 := g.registerToString(reg2);
        buffer := child.dataType.kind;
        case buffer of
        TranslatorType.KIND_BOOLEAN:
            g.writeInstruction('movzx', sR3I, smmb);
        TranslatorType.KIND_CHAR:
            g.writeInstruction('movzx', sR3I, smmw);
        TranslatorType.KIND_BYTE:
            g.writeInstruction('movsx', sR3I, smmb);
        TranslatorType.KIND_SHORT:
            g.writeInstruction('movsx', sR3I, smmw);
        TranslatorType.KIND_INT:
            g.writeInstruction('mov', sR3I, smm);
        TranslatorType.KIND_LONG:
            g.writeInstruction('mov', sR3L, smm);
        TranslatorType.KIND_ULTRA:
            g.writeInstruction('movdqu', sXMM12, smm);
        end;
        case buffer of
        TranslatorType.KIND_BOOLEAN,
        TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
        TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_SANDB:
                g.writeInstruction('and', sR3I, sr2);
            TranslatorTreeBuilder.ASSIGN_SXORB:
                g.writeInstruction('xor', sR3I, sr2);
            TranslatorTreeBuilder.ASSIGN_SORB:
                g.writeInstruction('or', sR3I, sr2);
            end;
        TranslatorType.KIND_LONG:
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_SANDB:
                g.writeInstruction('and', sR3L, sr2);
            TranslatorTreeBuilder.ASSIGN_SXORB:
                g.writeInstruction('xor', sR3L, sr2);
            TranslatorTreeBuilder.ASSIGN_SORB:
                g.writeInstruction('or', sR3L, sr2);
            end;
        TranslatorType.KIND_ULTRA:
            case nodeValue of
            TranslatorTreeBuilder.ASSIGN_SANDB:
                g.writeInstruction('pand', sXMM12, sr2);
            TranslatorTreeBuilder.ASSIGN_SXORB:
                g.writeInstruction('pxor', sXMM12, sr2);
            TranslatorTreeBuilder.ASSIGN_SORB:
                g.writeInstruction('por', sXMM12, sr2);
            end;
        end;
        case buffer of
        TranslatorType.KIND_BYTE, TranslatorType.KIND_BOOLEAN:
            g.writeInstruction('mov', smm, sR3B);
        TranslatorType.KIND_SHORT, TranslatorType.KIND_CHAR:
            g.writeInstruction('mov', smm, sR3S);
        TranslatorType.KIND_INT:
            g.writeInstruction('mov', smm, sR3I);
        TranslatorType.KIND_LONG:
            g.writeInstruction('mov', smm, sR3L);
        TranslatorType.KIND_ULTRA:
            g.writeInstruction('movdqu', smm, sXMM12);
        end;
        if (goIfTrueTo <> nil) and (goIfFalseTo <> nil) then begin
            stack.restoreRegs(g); { регистр флагов – без изменений }
            if goIfTrueTo.labelNumber = nodeLN + 1 then begin
                g.writeInstruction('jz',
                        LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
            end else
            if goIfFalseTo.labelNumber = nodeLN + 1 then begin
                g.writeInstruction('jnz',
                        LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
            end else begin
                g.writeInstruction('jz',
                        LABEL_LOCAL + intToString(goIfFalseTo.assignedLabelNumber));
                g.writeInstruction('jmp',
                        LABEL_LOCAL + intToString(goIfTrueTo.assignedLabelNumber));
            end;
        end else begin
            if nodeType <> nil then begin
                case buffer of
                TranslatorType.KIND_BOOLEAN,
                TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
                TranslatorType.KIND_SHORT, TranslatorType.KIND_INT: begin
                    reg1 := stack.allocateGPR32bit(g);
                    sr1 := g.registerToString(reg1);
                    g.writeInstruction('mov', sr1, sR3I);
                end;
                TranslatorType.KIND_LONG: begin
                    reg1 := stack.allocateGPR64bit(g);
                    sr1 := g.registerToString(reg1);
                    g.writeInstruction('mov', sr1, sR3L);
                end;
                TranslatorType.KIND_ULTRA: begin
                    stack.pushReg(reg2);
                    g.writeInstruction('movdqu', sr2, sXMM12);
                end;
                end;
            end;
            stack.restoreRegs(g);
        end;
    end;
    TranslatorTreeBuilder.JUMP: begin
        if (node.parent as SyntaxNode).value = TranslatorTreeBuilder.EXPR_QUESTION then begin
            stack.deallocateRegWithoutCodeGeneration();
        end;
        g.writeInstruction('jmp', LABEL_LOCAL + intToString(goAlwaysTo.assignedLabelNumber));
    end;
    TranslatorTreeBuilder.TF_JUMP: begin
        child := TranslatorTreeBuilder.getCommonParent(node, goAlwaysTo) as SyntaxNode;
        current := node.parent as SyntaxNode;
        repeat
            if current.value = TranslatorTreeBuilder.OPERATOR_TRY_FINALLY then begin
                gotoNode := (current.getChild(current.getChildrensCount() - 1) as SyntaxNode).
                        goAlwaysToNode as BuilderNode;
                if gotoNode <> nil then begin
                    g.writeInstruction('call',
                            LABEL_LOCAL + intToString(gotoNode.assignedLabelNumber));
                end;
            end;
            current := current.parent as SyntaxNode;
        until (current = nil) or (current = child);
        g.writeInstruction('jmp', LABEL_LOCAL + intToString(goAlwaysTo.assignedLabelNumber));
    end;
    end;
end;

procedure TranslatorBuilderOf64bitCode.translateSwitch(node: SyntaxNode; stack: RegisterStack);
var
    i: int;
    j: int;
    k: int;
    reg1: int;
    caseC: int;
    caseF: int;
    caseS: int;
    delta: int;
    count: int;
    default: int;
    current: long;
    labels: long_Array1d;
    child: BuilderNode;
    g: TextGenerator;
    slabels: String_Array1d;
    sdef: String;
    sr1d: String;
    sR1L: String;
    sR2L: String;
    sR3L: String;

    procedure addLabel(caseValue, nodeLabel: int); inline;
    var
        newlabels: long_Array1d;
    begin
        if length(labels) = count then begin
            newlabels := long_Array1d_create((count shl 1) + 1);
            arraycopyPrimitives(labels, 0, newlabels, 0, count);
            labels := newlabels;
        end;
        labels[count] := longBuild(nodeLabel, caseValue);
        inc(count);
    end;

    procedure sortLabels(); inline;
    var
        i: int;
        j: int;
        valueAtI: int;
        valueAtJ: int;
        labelAtI: long;
        labelAtJ: long;
    begin
        for i := count - 1 downto 1 do begin
            labelAtI := labels[i];
            valueAtI := int(labelAtI);
            j := i - 1;
            while j >= 0 do begin
                labelAtJ := labels[j];
                valueAtJ := int(labelAtJ);
                if valueAtJ > valueAtI then begin
                    labels[i] := labelAtJ;
                    labels[j] := labelAtI;
                    labelAtI := labelAtJ;
                    valueAtI := valueAtJ;
                    j := i;
                end;
                dec(j);
            end;
        end;
    end;

    procedure setLabelsLength(newLength: int); inline;
    var
        newlabels: String_Array1d;
    begin
        if newLength < length(slabels) then begin
            newlabels := String_Array1d_create(newLength);
            arraycopyStrings(slabels, 0, newlabels, 0, newLength);
            slabels := newlabels;
        end;
    end;

begin
    g := self.generator;
    count := 0;
    default := -1;
    labels := nil;
    reg1 := R0 + (stack.getRegAt(0) and $0f);
    sr1d := g.registerToString(R0D + (reg1 and $0f));
    stack.popRegs(1);
    for i := node.getChildrensCount() - 1 downto 0 do begin
        child := node.getChild(i) as BuilderNode;
        case child.value of
        TranslatorTreeBuilder.BLOCK_CASE:
            addLabel((child.associate as IntegerAsObject).intValue(),
                    (child.goAlwaysToNode as BuilderNode).assignedLabelNumber);
        TranslatorTreeBuilder.BLOCK_DEFAULT:
            default := (child.goAlwaysToNode as BuilderNode).assignedLabelNumber;
        end;
    end;
    sortLabels();
    sdef := LABEL_LOCAL + intToString(default);
    if count > 0 then begin
        caseS := int(labels[0]);
        caseF := int(labels[count - 1]);
    end else begin
        caseS := 0;
        caseF := -1;
    end;
    caseC := caseF - caseS + 1;
    if (caseC > 0) and (caseC < count shl 1) then begin
        { tableswitch }
        sR1L := g.registerToString(R1);
        sR2L := g.registerToString(R2);
        sR3L := g.registerToString(R3);
        g.writeInstruction('sub', sr1d, g.immediateToStringInt(caseS));
        g.writeInstruction('jl', sdef);
        g.writeInstruction('cmp', sr1d, g.immediateToStringInt(caseF - caseS));
        g.writeInstruction('ja', sdef);
        g.writeInstruction('lea', sR1L, g.memoryToString(MNONE, LABEL_FOLLOWING, 0));
        g.writeInstruction('movsxd', sR2L, sr1d);
        g.writeInstruction('movsxd', sR3L, g.memoryToString(MNONE, R1, R2, 4, 0));
        g.writeInstruction('lea', sR3L, g.memoryToString(MNONE, R1, R3, 0));
        g.writeInstruction('jmp', sR3L);
        g.writeAlignLocal(4);
        g.writeLabelShort(LABEL_ANONYMOUS);
        i := 0;
        k := 0;
        slabels := String_Array1d_create(8);
        for j := caseS to caseF do begin
            current := labels[i];
            if int(current) = j then begin
                slabels[k] := g.labelRelativeAnotherToString(
                        LABEL_LOCAL + intToString(current.ints[1]), LABEL_PRECEDING, 0);
                inc(i);
            end else begin
                slabels[k] := g.labelRelativeAnotherToString(sdef, LABEL_PRECEDING, 0);
            end;
            inc(k);
            if k = 8 then begin
                g.writeInstruction('dd', slabels);
                k := 0;
            end;
        end;
        if k > 0 then begin
            setLabelsLength(k);
            g.writeInstruction('dd', slabels);
        end;
    end else begin
        { lookupswitch }
        dec(count);
        for i := 0 to count do begin
            current := labels[i];
            delta := int(current);
            if i > 0 then begin
                dec(delta, int(labels[i - 1]));
            end;
            g.writeInstruction('sub', sr1d, g.immediateToStringInt(delta));
            g.writeInstruction('jz', LABEL_LOCAL + intToString(current.ints[1]));
        end;
        g.writeInstruction('jmp', sdef);
    end;
end;

procedure TranslatorBuilderOf64bitCode.translateExceptionHandler(root: SyntaxNode;
        argums, locals: int);
var
    intr: boolean;
    i: int;
    j: int;
    esize: int;
    limit: int;
    node: SyntaxNode;
    last: SyntaxNode;
    ftyp: TypeFunction;
    func: GlobalFunction;
    enum: NodeEnumerator;
    exhn: Vector;
    g: TextGenerator;
    sR0I: String;
    sR1L: String;
    sR2L: String;
    sR3L: String;
    sRSP: String;
    sR15L: String;
begin
    g := self.generator;
    sR0I := g.registerToString(R0D);
    sR1L := g.registerToString(R1);
    sR2L := g.registerToString(R2);
    sR3L := g.registerToString(R3);
    sRSP := g.registerToString(RSP);
    sR15L := g.registerToString(R15);
    func := root.associate as GlobalFunction;
    enum := root.enumerateChildrens();
    exhn := Vector.create();
    try
        intr := func.isInterrupt();
        g.writeLabelShort(LABEL_EXCEPTION_HANDLER);
        if intr = false then begin
            g.writeInstruction('emms');
        end;
        node := root;
        repeat
            case node.value of
            TranslatorTreeBuilder.OPERATOR_TRY_CATCH,
            TranslatorTreeBuilder.OPERATOR_TRY_FINALLY: begin
                exhn.addElement(node);
            end;
            end;
            node := enum.nextChild() as SyntaxNode;
        until node = nil;
        esize := exhn.size();
        if esize > 0 then begin
            g.writeInstruction('lea', sRSP, g.memoryToString(MNONE, RBP, -locals));
        end;
        for i := esize downto 1 do begin
            if i < esize then begin
                g.writeLabelShort(LABEL_ANONYMOUS);
            end;
            node := exhn.elementAt(i - 1) as SyntaxNode;
            g.writeInstruction('lea', sR3L, g.memoryToString(MNONE, LABEL_LOCAL + intToString(
                    (node.goIfTrueToNode as BuilderNode).assignedLabelNumber), 0));
            g.writeInstruction('cmp', sR2L, sR3L);
            g.writeInstruction('jl', LABEL_FOLLOWING);
            g.writeInstruction('lea', sR3L, g.memoryToString(MNONE, LABEL_LOCAL + intToString(
                    (node.goIfFalseToNode as BuilderNode).assignedLabelNumber), 0));
            g.writeInstruction('cmp', sR2L, sR3L);
            g.writeInstruction('jge', LABEL_FOLLOWING);
            case node.value of
            TranslatorTreeBuilder.OPERATOR_TRY_CATCH: begin
                limit := node.getChildrensCount() - 1;
                for j := 0 to limit do begin
                    last := node.getChild(j) as SyntaxNode;
                    if last.value <> TranslatorTreeBuilder.BLOCK_CATCH then begin
                        continue;
                    end;
                    g.writeInstruction('lea', sR3L, g.memoryToString(MNONE,
                            getEntryFullName(last.associate as NamespaceEntry), 0));
                    g.writeInstruction('call', FUNCTION_EXCEPTION_INHERITED_FROM);
                    g.writeInstruction('test', sR0I, sR0I);
                    g.writeInstruction('jnz', LABEL_LOCAL + intToString(
                            (last.goAlwaysToNode as BuilderNode).assignedLabelNumber));
                end;
            end;
            TranslatorTreeBuilder.OPERATOR_TRY_FINALLY: begin
                last := node.getChild(node.getChildrensCount() - 1) as SyntaxNode;
                g.writeInstruction('push', sR1L);
                g.writeInstruction('push', sR2L);
                g.writeInstruction('call', LABEL_LOCAL + intToString(
                        (last.goAlwaysToNode as BuilderNode).assignedLabelNumber));
                g.writeInstruction('pop', sR2L);
                g.writeInstruction('pop', sR1L);
            end;
            end;
        end;
        if esize > 0 then begin
            g.writeLabelShort(LABEL_ANONYMOUS);
        end;
        if intr then begin
            g.writeInstruction('leave');
            g.writeInstruction('pop', g.registerToString(R15));
            g.writeInstruction('pop', g.registerToString(R14));
            g.writeInstruction('pop', g.registerToString(R13));
            g.writeInstruction('pop', g.registerToString(R12));
            g.writeInstruction('pop', g.registerToString(R11));
            g.writeInstruction('pop', g.registerToString(R10));
            g.writeInstruction('pop', g.registerToString(R9));
            g.writeInstruction('pop', g.registerToString(R8));
            g.writeInstruction('pop', g.registerToString(R7));
            g.writeInstruction('pop', g.registerToString(R6));
            g.writeInstruction('pop', g.registerToString(R3));
            g.writeInstruction('pop', g.registerToString(R2));
            g.writeInstruction('pop', g.registerToString(R1));
            g.writeInstruction('pop', g.registerToString(R0));
            ftyp := func.functionType;
            if (ftyp.getArgumentsCount() > 5) and
                    stringStartsWith(UnicodeString('error'), ftyp.getArgument(5).name) then begin
                g.writeInstruction('lea', g.registerToString(RSP),
                        g.memoryToString(MNONE, RSP, $10));
            end else begin
                g.writeInstruction('lea', g.registerToString(RSP),
                        g.memoryToString(MNONE, RSP, $08));
            end;
            g.writeInstruction('iretq');
        end else begin
            g.writeInstruction('leave');
            g.writeInstruction('pop', sR15L);
            if length(func.owner.name) > 0 then begin
                g.writeInstruction('pop', sR2L);
                g.writeInstruction('dec', sR2L);
                g.writeInstruction('jmp', sR15L);
            end else begin
                case g.exitMethod of
                TextGenerator.EXIT_RETF: begin
                    if argums > 0 then begin
                        g.writeInstruction('retf', g.immediateToString(argums));
                    end else begin
                        g.writeInstruction('retf');
                    end;
                end;
                TextGenerator.EXIT_CALL: begin
                    g.writeInstruction('push', sR1L);
                    g.writeInstruction('call', FUNCTION_EXIT);
                end;
                else
                    if argums > 0 then begin
                        g.writeInstruction('ret', g.immediateToString(argums));
                    end else begin
                        g.writeInstruction('ret');
                    end;
                end;
            end;
        end;
    finally
        exhn.free();
    end;
end;

procedure TranslatorBuilderOf64bitCode.writePools();
var
    i: int;
    j: int;
    k: int;
    l: int;
    len: int;
    limit: int;
    exponent: int;
    significand: long;
    longValue: long;
    ultraValue: ultra;
    floatValue: float;
    doubleValue: double;
    realValue: real;
    xvectorValue: xvector;
    funcValue: GlobalFunction;
    poolOfLong: PoolLong;
    poolOfUltra: PoolUltra;
    poolOfReal: PoolReal;
    poolOfXVector: PoolXVector;
    poolOfString: PoolString;
    poolOfFunctions: Vector;
    representer: RealValueRepresenter;
    g: TextGenerator;
    schars: String_Array1d;
    stringValue: UnicodeString;
    funcOwner: UnicodeString;
    shex: String;
    sdec: String;
begin
    g := self.generator;

    {%region открытые функции, имеющиеся в программе}
    poolOfFunctions := programmeFunctions;
    poolOfString := programmeStrings;
    limit := poolOfFunctions.size() - 1;
    g.writeEmptyLine();
    g.writeCommentToLineEnd('pool of functions');
    g.writeAlignGlobal(4);
    g.writeLabelLong(LABEL_POOL_FUNCS_LENGTH);
    g.writeInstruction('dd', g.immediateToStringInt(limit + 1));
    g.writeLabelLong(LABEL_POOL_FUNCS_CONTENT);
    for i := 0 to limit do begin
        funcValue := poolOfFunctions.elementAt(i) as GlobalFunction;
        stringValue := funcValue.name;
        funcOwner := funcValue.owner.name;
        if length(funcOwner) > 0 then begin
            stringValue := funcOwner + '.' + stringValue;
        end;
        g.writeInstruction('dd', g.immediateToStringInt(poolOfString.indexAcquire(stringValue)),
                g.labelRelativeToString(getEntryFullName(funcValue), 4));
    end;
    g.writeEmptyLine();
    {%endregion}

    {%region числа типа long, используемые программой }
    poolOfLong := programmeLongs;
    limit := poolOfLong.getLength() - 1;
    g.writeEmptyLine();
    g.writeCommentToLineEnd('pool of long');
    g.writeAlignGlobal(8);
    g.writeLabelLong(LABEL_POOL_LONG_LENGTH);
    g.writeInstruction('dq', g.immediateToStringInt(limit + 1), g.immediateToStringLong(0));
    g.writeLabelLong(LABEL_POOL_LONG_CONTENT);
    for i := 0 to limit do begin
        longValue := poolOfLong.getValue(i);
        shex := g.immediateToStringLong(longValue);
        sdec := longToString(longValue);
        g.writeInstruction('dq', shex);
        g.writeCommentToLineEnd(sdec);
    end;
    g.writeEmptyLine();
    {%endregion}

    {%region векторы типа ultra, используемые программой }
    poolOfUltra := programmeXUltras;
    limit := poolOfUltra.getLength() - 1;
    g.writeEmptyLine();
    g.writeCommentToLineEnd('pool of ultra');
    g.writeLabelLong(LABEL_POOL_ULTRA_LENGTH);
    g.writeInstruction('dq', g.immediateToStringInt(limit + 1), g.immediateToStringLong(0));
    g.writeLabelLong(LABEL_POOL_ULTRA_CONTENT);
    for i := 0 to limit do begin
        ultraValue := poolOfUltra.getValue(i);
        g.writeInstruction('dd',
                g.immediateToStringInt(ultraValue.ints[0]),
                g.immediateToStringInt(ultraValue.ints[1]),
                g.immediateToStringInt(ultraValue.ints[2]),
                g.immediateToStringInt(ultraValue.ints[3]));
        g.writeCommentToLineEnd('new ultra { ' +
                intToString(ultraValue.ints[0]) + ', ' +
                intToString(ultraValue.ints[1]) + ', ' +
                intToString(ultraValue.ints[2]) + ', ' +
                intToString(ultraValue.ints[3]) + ' }');
    end;
    g.writeEmptyLine();
    {%endregion}

    {%region числа типа float, используемые программой }
    poolOfReal := programmeFloats;
    limit := poolOfReal.getLength() - 1;
    g.writeEmptyLine();
    g.writeCommentToLineEnd('pool of float');
    g.writeLabelLong(LABEL_POOL_FLOAT_LENGTH);
    g.writeInstruction('dq', g.immediateToStringInt(limit + 1), g.immediateToStringLong(0));
    g.writeLabelLong(LABEL_POOL_FLOAT_CONTENT);
    representer := RealValueRepresenter.create(RealValueRepresenter.FLOAT_SIGNIFICAND_DIGITS,
            RealValueRepresenter.FLOAT_ORDER_DIGITS);
    try
        for i := 0 to limit do begin
            floatValue := realToFloat(poolOfReal.getValue(i));
            shex := g.immediateToStringInt(floatToIntBits(floatValue));
            sdec := representer.toString(floatValue);
            g.writeInstruction('dd', shex);
            g.writeCommentToLineEnd(sdec);
        end;
    finally
        representer.free();
    end;
    g.writeEmptyLine();
    {%endregion}

    {%region числа типа double, используемые программой }
    poolOfReal := programmeDoubles;
    limit := poolOfReal.getLength() - 1;
    g.writeEmptyLine();
    g.writeCommentToLineEnd('pool of double');
    g.writeAlignGlobal(8);
    g.writeLabelLong(LABEL_POOL_DOUBLE_LENGTH);
    g.writeInstruction('dq', g.immediateToStringInt(limit + 1), g.immediateToStringLong(0));
    g.writeLabelLong(LABEL_POOL_DOUBLE_CONTENT);
    representer := RealValueRepresenter.create(RealValueRepresenter.DOUBLE_SIGNIFICAND_DIGITS,
            RealValueRepresenter.DOUBLE_ORDER_DIGITS);
    try
        for i := 0 to limit do begin
            doubleValue := realToDouble(poolOfReal.getValue(i));
            shex := g.immediateToStringLong(doubleToLongBits(doubleValue));
            sdec := representer.toString(doubleValue);
            g.writeInstruction('dq', shex);
            g.writeCommentToLineEnd(sdec);
        end;
    finally
        representer.free();
    end;
    g.writeEmptyLine();
    {%endregion}

    {%region числа типа real, используемые программой }
    poolOfReal := programmeReals;
    limit := poolOfReal.getLength() - 1;
    g.writeEmptyLine();
    g.writeCommentToLineEnd('pool of real');
    g.writeLabelLong(LABEL_POOL_REAL_LENGTH);
    g.writeInstruction('dq', g.immediateToStringInt(limit + 1), g.immediateToStringLong(0));
    g.writeLabelLong(LABEL_POOL_REAL_CONTENT);
    representer := RealValueRepresenter.create(RealValueRepresenter.REAL_SIGNIFICAND_DIGITS,
            RealValueRepresenter.REAL_ORDER_DIGITS);
    try
        for i := 0 to limit do begin
            realValue := poolOfReal.getValue(i);
            exponent := realExtractExponent(realValue);
            significand := realExtractSignificand(realValue);
            sdec := representer.toString(realValue);
            g.writeInstruction('dw', String_Array1d_create([
                g.immediateToStringShort(significand.shorts[0]),
                g.immediateToStringShort(significand.shorts[1]),
                g.immediateToStringShort(significand.shorts[2]),
                g.immediateToStringShort(significand.shorts[3]),
                g.immediateToStringShort(exponent)
            ]));
            g.writeCommentToLineEnd(sdec);
        end;
    finally
        representer.free();
    end;
    g.writeEmptyLine();
    {%endregion}

    {%region векторы типа xvector, используемые программой }
    poolOfXVector := programmeXVectors;
    limit := poolOfXVector.getLength() - 1;
    g.writeEmptyLine();
    g.writeCommentToLineEnd('pool of xvector');
    g.writeAlignGlobal(8);
    g.writeLabelLong(LABEL_POOL_XVECTOR_LENGTH);
    g.writeInstruction('dq', g.immediateToStringInt(limit + 1), g.immediateToStringLong(0));
    g.writeLabelLong(LABEL_POOL_XVECTOR_CONTENT);
    representer := RealValueRepresenter.create(RealValueRepresenter.FLOAT_SIGNIFICAND_DIGITS,
            RealValueRepresenter.FLOAT_ORDER_DIGITS);
    try
        for i := 0 to limit do begin
            xvectorValue := poolOfXVector.getValue(i);
            g.writeInstruction('dd',
                    g.immediateToStringInt(floatToIntBits(xvectorValue.floats[0])),
                    g.immediateToStringInt(floatToIntBits(xvectorValue.floats[1])),
                    g.immediateToStringInt(floatToIntBits(xvectorValue.floats[2])),
                    g.immediateToStringInt(floatToIntBits(xvectorValue.floats[3])));
            g.writeCommentToLineEnd('new xvector { ' +
                    representer.toString(xvectorValue.floats[0]) + ', ' +
                    representer.toString(xvectorValue.floats[1]) + ', ' +
                    representer.toString(xvectorValue.floats[2]) + ', ' +
                    representer.toString(xvectorValue.floats[3]) + ' }');
        end;
    finally
        representer.free();
    end;
    g.writeEmptyLine();
    {%endregion}

    {%region строки типа char[], используемые программой }
    limit := poolOfString.getLength() - 1;
    g.writeEmptyLine();
    g.writeCommentToLineEnd('pool of string');
    g.writeLabelLong(LABEL_POOL_STRING_LENGTH);
    g.writeInstruction('dd', g.immediateToStringInt(limit + 1), g.immediateToStringInt(0));
    g.writeLabelLong(LABEL_POOL_STRING_CONTENT);
    for i := 0 to limit do begin
        g.writeInstruction('dq', g.immediateToStringInt(length(poolOfString.getValue(i))),
                g.labelRelativeToString(LABEL_POOL_STRING_ENTRY + intToString(i), -8))
    end;
    for i := 0 to limit do begin
        g.writeLabelLong(LABEL_POOL_STRING_ENTRY + intToString(i));
        stringValue := poolOfString.getValue(i);
        len := length(stringValue);
        j := 0;
        while j < len do begin
            k := len - j;
            if k >= 8 then begin
                schars := String_Array1d_create([
                    g.immediateToStringShort(int(stringValue[j + 1])),
                    g.immediateToStringShort(int(stringValue[j + 2])),
                    g.immediateToStringShort(int(stringValue[j + 3])),
                    g.immediateToStringShort(int(stringValue[j + 4])),
                    g.immediateToStringShort(int(stringValue[j + 5])),
                    g.immediateToStringShort(int(stringValue[j + 6])),
                    g.immediateToStringShort(int(stringValue[j + 7])),
                    g.immediateToStringShort(int(stringValue[j + 8]))
                ]);
            end else begin
                schars := String_Array1d_create(k);
                for l := 1 to k do begin
                    schars[l - 1] := g.immediateToStringShort(int(stringValue[j + l]));
                end;
            end;
            g.writeInstruction('dw', schars);
            inc(j, 8);
        end;
    end;
    g.writeEmptyLine();
    {%endregion}
end;

function TranslatorBuilderOf64bitCode.insertArguments(args: TypeFunction; offset: int): int;
var
    i: int;
    delta: int;
    g: TextGenerator;
begin
    result := 0;
    g := self.generator;
    for i := args.getArgumentsCount() - 1 downto 0 do with args.getArgument(i) do begin
        g.writeLabelRelative('.' + encode(name), RBP, offset);
        delta := dataType.getAlignedSize(TranslatorType.SIZE_64_BIT);
        inc(offset, delta);
        inc(result, delta);
    end;
end;

function TranslatorBuilderOf64bitCode.insertLocalVars(tree: SyntaxTree; offset: int): int;
var
    csize: int;
    lsize: int;
    locals: Hashtable;
    root: SyntaxNode;
    node: SyntaxNode;
    enum: NodeEnumerator;
    vars: Enumeration;
    g: TextGenerator;
    ltype: TypeDescriptor;
    lname: UnicodeString;
begin
    result := 0;
    if tree = nil then begin
        exit;
    end;
    locals := Hashtable.create();
    try
        root := tree.root as SyntaxNode;
        { определяем размер каждой локальной переменной }
        node := root;
        enum := root.enumerateChildrens();
        repeat
            case node.value of
            TranslatorTreeBuilder.OPERATOR_VARIABLE, TranslatorTreeBuilder.BLOCK_WITH: begin
                with node.associate as LocalVariable do begin
                    ltype := dataType;
                    lname := name;
                end;
                csize := ltype.getAlignedSize(TranslatorType.SIZE_64_BIT);
                if locals.containsKey(lname) then begin
                    lsize := (locals.get(lname) as IntegerAsObject).intValue();
                    if csize > lsize then begin
                        locals.put(lname, csize);
                    end;
                end else begin
                    locals.put(lname, csize);
                end;
            end;
            end;
            node := enum.nextChild() as SyntaxNode;
        until node = nil;
        { определяем смещение каждой локальной переменной }
        g := self.generator;
        vars := locals.keys();
        while vars.hasMoreElements() do begin
            lname := (vars.nextElement() as UnicodeStringAsObject).unicodeStringValue();
            lsize := (locals.get(lname) as IntegerAsObject).intValue();
            dec(offset, lsize);
            inc(result, lsize);
            g.writeLabelRelative('.' + encode(lname), RBP, offset);
        end;
    finally
        locals.free();
    end;
end;

function TranslatorBuilderOf64bitCode.getMemoryLocation(node: SyntaxNode; stack: RegisterStack;
        hasValueForWrite: boolean): MemoryLocation;
var
    regPtr: int;
    regIdx: int;
    regSrc: int;
    scale: int;
    size: int;
    nodeValue: int;
    g: TextGenerator;
    srIdx: String;
begin
    g := self.generator;
    nodeValue := node.value;
    if hasValueForWrite then begin
        case nodeValue of
        TranslatorTreeBuilder.EXPR_LOCAL_VARIABLE,
        TranslatorTreeBuilder.EXPR_GLOBAL_VARIABLE: begin
            regPtr := -1;
            regIdx := -1;
            regSrc := stack.getRegAt(0);
            stack.popRegs(1);
        end;
        TranslatorTreeBuilder.EXPR_ARRAY: begin
            regPtr := stack.getRegAt(2);
            regIdx := stack.getRegAt(1);
            regSrc := stack.getRegAt(0);
            stack.popRegs(3);
        end;
        TranslatorTreeBuilder.EXPR_FIELD: begin
            regPtr := stack.getRegAt(1);
            regIdx := -1;
            regSrc := stack.getRegAt(0);
            stack.popRegs(2);
        end;
        else
            exit;
        end;
    end else begin
        case nodeValue of
        TranslatorTreeBuilder.EXPR_LOCAL_VARIABLE,
        TranslatorTreeBuilder.EXPR_GLOBAL_VARIABLE: begin
            regPtr := -1;
            regIdx := -1;
            regSrc := -1;
        end;
        TranslatorTreeBuilder.EXPR_ARRAY: begin
            regPtr := stack.getRegAt(1);
            regIdx := stack.getRegAt(0);
            regSrc := -1;
            stack.popRegs(2);
        end;
        TranslatorTreeBuilder.EXPR_FIELD: begin
            regPtr := stack.getRegAt(0);
            regIdx := -1;
            regSrc := -1;
            stack.popRegs(1);
        end;
        else
            exit;
        end;
    end;
    case nodeValue of
    TranslatorTreeBuilder.EXPR_LOCAL_VARIABLE: begin
        result := MemoryLocationTfasm.create(g, regSrc,
                '.' + encode((node.associate as LocalVariable).name));
    end;
    TranslatorTreeBuilder.EXPR_GLOBAL_VARIABLE: begin
        result := MemoryLocationTfasm.create(g, regSrc,
                getEntryFullName(node.associate as GlobalVariable));
    end;
    TranslatorTreeBuilder.EXPR_FIELD: begin
        result := MemoryLocationTfasm.create(g, regSrc, regPtr,
                getFieldFullName(node.associate as StructureField));
    end;
    TranslatorTreeBuilder.EXPR_ARRAY: begin
        g.writeInstruction('mov', g.registerToString(R1), g.registerToString(regPtr));
        g.writeInstruction('mov', g.registerToString(R2D), g.registerToString(regIdx));
        g.writeInstruction('call', FUNCTION_CHECK_ARRAY_INDEX);
        regIdx := R0 + (regIdx and $0f);
        srIdx := g.registerToString(regIdx);
        size := node.dataType.size;
        case size of
        1, 2, 4, 8: begin
            scale := size;
            g.writeInstruction('lea', srIdx, g.memoryToString(MNONE, '', R2, 1, 0));
        end;
        16: begin
            scale := 8;
            g.writeInstruction('lea', srIdx, g.memoryToString(MNONE, '', R2, 2, 0));
        end;
        32: begin
            scale := 8;
            g.writeInstruction('lea', srIdx, g.memoryToString(MNONE, '', R2, 4, 0));
        end;
        64: begin
            scale := 8;
            g.writeInstruction('lea', srIdx, g.memoryToString(MNONE, '', R2, 8, 0));
        end;
        else
            scale := 1;
            g.writeInstruction('imul', srIdx, g.registerToString(R2), g.immediateToString(size));
        end;
        result := MemoryLocationTfasm.create(g, regSrc, R1, regIdx, scale, '');
    end;
    else
        result := nil;
    end;
end;

end.