void gfunc_call(int nb_args) Обнуляется args_size Начинается цикл от нуля до переданного значения Если последняя SValue кдирует кодирует VT_STRUCT, происходит следующая обработка: С помощью type_size() вычисляется размре типа. Размер выравнивается по кранице 3-х байтных значений. Вызывается oad(), переменная r обновлянеся вызовом get_reg() Дважды вызывается o() Вызываются vset() vswap() vstore(); Переменная args_size увеличивается на величину размера Если кодируется другой тип и он проходит проверку is_float(), происходит следующая обработка: Вызывается gv(RC_FLOAT) Если кодируется VT_FLOAT, размер будет 4 байта Если кодируется VT_DOUBLE, размер будет 8 байта Если кодируется другой тип, размер будет 12 байта Если размер равен 12 байтам, вызывается o(), иначе тоже вызывается o(), но с другим параметром. Дважды вызывается g(); Переменная args_size увеличивается на величину размера Если провека is_float() не проходит, происходит следующая обработка: Переменная r обновляется вызовом gv() Если кодируется VT_DOUBLE, размер будет 8 байта и вызовется o(), иначе размер будет 4 бйта Вызовется o() Переменная args_size увеличивается на величину размера Уменьшается цепочка vtop Вызывается save_regs(); /* save used temporary registers */ Переменная func_sym обновляется значением поля ref структуры CType, связанной с последней SValue Переменная func_call обновляется значением поля r симола, адрес которого мы поместили в func_sym. Значение поля преобразовывается к нужному типу с помощью макроса FUNC_CALL() Если полученное значение равно FUNC_FASTCALLW или больше или равно FUNC_FASTCALL1 но при этом меньше или равно FUNC_FASTCALL3, происходит следующая обработка: Если значение равно FUNC_FASTCALLW, будут обрабатыватся регистры fastcallw_regs, их количество рано 2 Для других значений будут обрабатываться регистры fastcall_regs их количестово высчитвается как разность значения и FUNC_FASTCALL1 увеличенная на 1 Обрабатывается каждый регсистр. Обработка прекратится если args_size меньше нуля. Вызывается o(). Переменная args_size уменьшается на 4 на каждом шаге Вызывается gcall_or_jmp() Если args_size не достигла нулевого или отрицательного значения и при этом значение не достигло FUNC_STDCALL, вызывается gadd_sp() Уменьшается цепочка vtop static void gadd_sp(int val) Если переданное значение при отбрасывании старших бит равно само себе, вызывается o() и g() иначе вызывается oad() static void gcall_or_jmp(int is_jmp) Если поле r последней SValue кодирует VT_CONST, происходит следующая обработка: Если поле r содержит биты VT_SYM, вызывается greloc(), иначе put_elf_reloc() Вызывается oad() Если проверка на VT_CONST не проходит, перемення r обновялется вызовом gv() Дважды вызывается o() void vrott(int n) Сохраняется последняя SValue для того чтобы в конце функции сделать ее первой. Остальные элементы сдвигаются вперед. static void vpush_global_sym(CType *type, int v) Получаем ссылку на символ с помощью external_global_sym() Во временном CValue обнуляется поле ul Вызывается vsetc() В последнем SValue обноляется поле sym адресом полученного символа. static Sym *external_global_sym(int v, CType *type, int r) Вызывается sym_find(), чтобы найти символ. Если получен ненулевой адрес , Адрес обновляется вызывом global_identifier_push(). В CType связном с обновленным символом обновляется поле ref значением поля ref переданного CType В поле r обновленного символа устанавливаются биты | VT_CONST | VT_SYM; Возвращается адрес символа void gen_opif(int op) Сохраняем последнюю и предпоследнюю SValue. Для обоих SValue сохряняется в c1 и c2 сохраняется результат проверки кодирует, поле r символа VT_CONST Если одна из проверок истинна, происходит следующая обработка: Если CType связанный с последней SValue кодирует VT_FLOAT, то в f1 и в f2 записывается значения полей f связанных СValue Если CType связанный с последней SValue кодирует VT_DOUBLE, то в f1 и в f2 записывается значения полей d связанных СValue Если CType связанный с последней SValue кодирует другой тип, то в f1 и в f2 записывается значения полей ld связанных СValue Если проверка ieee_finite() для одного из двух полученных значений возвращает нулевой результат, упраление передается на метку general_case Далее происходит обработка в соостветствии с переданной операщии Для '+' к f1 прибавляется f2 Для '-' от f1 отнимается f2 Для '*' f1 умножается на f2 Для '/' если f2 равна 0.0, то управление передается на метку general_case. Предварительно проверяется флаг const_wanted. Если он установлен, компилятор завершается с ошибкой. Если проверка на 0 не проходит f1 делится на f2 Для остальных операций, управление передается на метку general_case Значение f1 записывается в одно из полей Сvalue Если CType связанный с последней SValue кодирует VT_FLOAT, обновляется поле f Если CType связанный с последней SValue кодирует VT_DOUBLE, обновляется поле d Если CType связанный с последней SValue кодирует другой тип, обновляется поле ld Уменьшается цепочка vtop Если провека на VT_CONST не проходит, начинается обработка, начинающаяся с метки general_case: Если флаг nocode_wanted сброшен, вызывается gen_opf() иначе уменьшается цепочка vtop |