Ignore:
Timestamp:
Jan 21, 2018, 12:10:09 AM (6 years ago)
Author:
coas-nagasima
Message:

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

Location:
EcnlProtoTool/trunk/tcc-0.9.27
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/tcc-0.9.27/i386-gen.c

    r321 r331  
    2222
    2323/* number of available registers */
    24 #define NB_REGS         4
     24#define NB_REGS         5
    2525#define NB_ASM_REGS     8
     26#define CONFIG_TCC_ASM
    2627
    2728/* a register can belong to several classes. The classes must be
     
    3435#define RC_ECX     0x0010
    3536#define RC_EDX     0x0020
     37#define RC_EBX     0x0040
     38
    3639#define RC_IRET    RC_EAX /* function return: integer register */
    3740#define RC_LRET    RC_EDX /* function return: second integer register */
     
    4346    TREG_ECX,
    4447    TREG_EDX,
     48    TREG_EBX,
    4549    TREG_ST0,
     50    TREG_ESP = 4
    4651};
    4752
     
    5661/* defined if structures are passed as pointers. Otherwise structures
    5762   are directly pushed on stack. */
    58 //#define FUNC_STRUCT_PARAM_AS_PTR
     63/* #define FUNC_STRUCT_PARAM_AS_PTR */
    5964
    6065/* pointer size, in bytes */
     
    6772#define MAX_ALIGN     8
    6873
    69 
    70 #define psym oad
    71 
    72 /******************************************************/
    73 /* ELF defines */
    74 
    75 #define EM_TCC_TARGET EM_386
    76 
    77 /* relocation type for 32 bit data relocation */
    78 #define R_DATA_32   R_386_32
    79 #define R_DATA_PTR  R_386_32
    80 #define R_JMP_SLOT  R_386_JMP_SLOT
    81 #define R_COPY      R_386_COPY
    82 
    83 #define ELF_START_ADDR 0x08048000
    84 #define ELF_PAGE_SIZE  0x1000
    85 
    8674/******************************************************/
    8775#else /* ! TARGET_DEFS_ONLY */
     
    8977#include "tcc.h"
    9078
     79/* define to 1/0 to [not] have EBX as 4th register */
     80#define USE_EBX 0
     81
    9182ST_DATA const int reg_classes[NB_REGS] = {
    9283    /* eax */ RC_INT | RC_EAX,
    9384    /* ecx */ RC_INT | RC_ECX,
    9485    /* edx */ RC_INT | RC_EDX,
     86    /* ebx */ (RC_INT | RC_EBX) * USE_EBX,
    9587    /* st0 */ RC_FLOAT | RC_ST0,
    9688};
     
    9991static int func_ret_sub;
    10092#ifdef CONFIG_TCC_BCHECK
    101 static unsigned long func_bound_offset;
     93static addr_t func_bound_offset;
     94static unsigned long func_bound_ind;
    10295#endif
    10396
     
    10699{
    107100    int ind1;
     101    if (nocode_wanted)
     102        return;
    108103    ind1 = ind + 1;
    109104    if (ind1 > cur_text_section->data_allocated)
     
    138133ST_FUNC void gsym_addr(int t, int a)
    139134{
    140     int n, *ptr;
    141135    while (t) {
    142         ptr = (int *)(cur_text_section->data + t);
    143         n = *ptr; /* next value */
    144         *ptr = a - t - 4;
     136        unsigned char *ptr = cur_text_section->data + t;
     137        uint32_t n = read32le(ptr); /* next value */
     138        write32le(ptr, a - t - 4);
    145139        t = n;
    146140    }
     
    152146}
    153147
    154 /* psym is used to put an instruction with a data field which is a
    155    reference to a symbol. It is in fact the same as oad ! */
    156 #define psym oad
    157 
    158148/* instruction + 4 bytes data. Return the address of the data */
    159 ST_FUNC int oad(int c, int s)
    160 {
    161     int ind1;
    162 
     149static int oad(int c, int s)
     150{
     151    int t;
     152    if (nocode_wanted)
     153        return s;
    163154    o(c);
    164     ind1 = ind + 4;
    165     if (ind1 > cur_text_section->data_allocated)
    166         section_realloc(cur_text_section, ind1);
    167     *(int *)(cur_text_section->data + ind) = s;
    168     s = ind;
    169     ind = ind1;
    170     return s;
    171 }
     155    t = ind;
     156    gen_le32(s);
     157    return t;
     158}
     159
     160/* generate jmp to a label */
     161#define gjmp2(instr,lbl) oad(instr,lbl)
    172162
    173163/* output constant with relocation if 'r & VT_SYM' is true */
     
    186176}
    187177
    188 /* generate a modrm reference. 'op_reg' contains the addtionnal 3
     178/* generate a modrm reference. 'op_reg' contains the additional 3
    189179   opcode bits */
    190180static void gen_modrm(int op_reg, int r, Sym *sym, int c)
     
    221211
    222212    fr = sv->r;
    223     ft = sv->type.t;
    224     fc = sv->c.ul;
     213    ft = sv->type.t & ~VT_DEFSIGN;
     214    fc = sv->c.i;
     215
     216    ft &= ~(VT_VOLATILE | VT_CONSTANT);
    225217
    226218    v = fr & VT_VALMASK;
     
    229221            v1.type.t = VT_INT;
    230222            v1.r = VT_LOCAL | VT_LVAL;
    231             v1.c.ul = fc;
     223            v1.c.i = fc;
    232224            fr = r;
    233225            if (!(reg_classes[fr] & RC_INT))
     
    244236            o(0xdb); /* fldt */
    245237            r = 5;
    246         } else if ((ft & VT_TYPE) == VT_BYTE) {
     238        } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
    247239            o(0xbe0f);   /* movsbl */
    248240        } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
     
    297289
    298290    ft = v->type.t;
    299     fc = v->c.ul;
     291    fc = v->c.i;
    300292    fr = v->r & VT_VALMASK;
     293    ft &= ~(VT_VOLATILE | VT_CONSTANT);
    301294    bt = ft & VT_BTYPE;
    302295    /* XXX: incorrect if float reg to reg */
     
    338331}
    339332
     333#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE
     334static void gen_static_call(int v)
     335{
     336    Sym *sym;
     337
     338    sym = external_global_sym(v, &func_old_type, 0);
     339    oad(0xe8, -4);
     340    greloc(cur_text_section, sym, ind-4, R_386_PC32);
     341}
     342#endif
     343
    340344/* 'is_jmp' is '1' if it is a jump */
    341345static void gcall_or_jmp(int is_jmp)
    342346{
    343347    int r;
    344     if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
    345         /* constant case */
    346         if (vtop->r & VT_SYM) {
    347             /* relocation case */
    348             greloc(cur_text_section, vtop->sym,
    349                    ind + 1, R_386_PC32);
    350         } else {
    351             /* put an empty PC32 relocation */
    352             put_elf_reloc(symtab_section, cur_text_section,
    353                           ind + 1, R_386_PC32, 0);
    354         }
    355         oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
     348    if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {
     349        /* constant and relocation case */
     350        greloc(cur_text_section, vtop->sym, ind + 1, R_386_PC32);
     351        oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */
    356352    } else {
    357353        /* otherwise, indirect call */
     
    360356        o(0xd0 + r + (is_jmp << 4));
    361357    }
     358    if (!is_jmp) {
     359        int rt;
     360        /* extend the return value to the whole register if necessary
     361           visual studio and gcc do not always set the whole eax register
     362           when assigning the return value of a function  */
     363        rt = vtop->type.ref->type.t;
     364        switch (rt & VT_BTYPE) {
     365            case VT_BYTE:
     366                if (rt & VT_UNSIGNED) {
     367                    o(0xc0b60f); /* movzx %al, %eax */
     368                }
     369                else {
     370                    o(0xc0be0f); /* movsx %al, %eax */
     371                }
     372                break;
     373            case VT_SHORT:
     374                if (rt & VT_UNSIGNED) {
     375                    o(0xc0b70f); /* movzx %ax, %eax */
     376                }
     377                else {
     378                    o(0xc0bf0f); /* movsx %ax, %eax */
     379                }
     380                break;
     381            default:
     382                break;
     383        }
     384    }
    362385}
    363386
    364387static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX };
    365388static uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX };
     389
     390/* Return the number of registers needed to return the struct, or 0 if
     391   returning via struct pointer. */
     392ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
     393{
     394#ifdef TCC_TARGET_PE
     395    int size, align;
     396    *ret_align = 1; // Never have to re-align return values for x86
     397    *regsize = 4;
     398    size = type_size(vt, &align);
     399    if (size > 8 || (size & (size - 1)))
     400        return 0;
     401    if (size == 8)
     402        ret->t = VT_LLONG;
     403    else if (size == 4)
     404        ret->t = VT_INT;
     405    else if (size == 2)
     406        ret->t = VT_SHORT;
     407    else
     408        ret->t = VT_BYTE;
     409    ret->ref = NULL;
     410    return 1;
     411#else
     412    *ret_align = 1; // Never have to re-align return values for x86
     413    return 0;
     414#endif
     415}
    366416
    367417/* Generate function call. The function address is pushed first, then
     
    422472    save_regs(0); /* save used temporary registers */
    423473    func_sym = vtop->type.ref;
    424     func_call = FUNC_CALL(func_sym->r);
     474    func_call = func_sym->f.func_call;
    425475    /* fast call case */
    426476    if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
     
    443493        }
    444494    }
     495#ifndef TCC_TARGET_PE
     496    else if ((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT)
     497        args_size -= 4;
     498#endif
    445499    gcall_or_jmp(0);
    446500
    447 #ifdef TCC_TARGET_PE
    448     if ((func_sym->type.t & VT_BTYPE) == VT_STRUCT)
    449         args_size -= 4;
    450 #endif
    451     if (args_size && func_call != FUNC_STDCALL)
     501    if (args_size && func_call != FUNC_STDCALL && func_call != FUNC_FASTCALLW)
    452502        gadd_sp(args_size);
    453503    vtop--;
     
    455505
    456506#ifdef TCC_TARGET_PE
    457 #define FUNC_PROLOG_SIZE 10
     507#define FUNC_PROLOG_SIZE (10 + USE_EBX)
    458508#else
    459 #define FUNC_PROLOG_SIZE 9
     509#define FUNC_PROLOG_SIZE (9 + USE_EBX)
    460510#endif
    461511
     
    470520
    471521    sym = func_type->ref;
    472     func_call = FUNC_CALL(sym->r);
     522    func_call = sym->f.func_call;
    473523    addr = 8;
    474524    loc = 0;
     
    492542       implicit pointer parameter */
    493543    func_vt = sym->type;
     544    func_var = (sym->f.func_type == FUNC_ELLIPSIS);
     545#ifdef TCC_TARGET_PE
     546    size = type_size(&func_vt,&align);
     547    if (((func_vt.t & VT_BTYPE) == VT_STRUCT)
     548        && (size > 8 || (size & (size - 1)))) {
     549#else
    494550    if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
     551#endif
    495552        /* XXX: fastcall case ? */
    496553        func_vc = addr;
     
    524581    }
    525582    func_ret_sub = 0;
    526     /* pascal type call ? */
    527     if (func_call == FUNC_STDCALL)
     583    /* pascal type call or fastcall ? */
     584    if (func_call == FUNC_STDCALL || func_call == FUNC_FASTCALLW)
    528585        func_ret_sub = addr - 8;
    529 #ifdef TCC_TARGET_PE
     586#ifndef TCC_TARGET_PE
    530587    else if (func_vc)
    531588        func_ret_sub = 4;
     
    535592    /* leave some room for bound checking code */
    536593    if (tcc_state->do_bounds_check) {
     594        func_bound_offset = lbounds_section->data_offset;
     595        func_bound_ind = ind;
    537596        oad(0xb8, 0); /* lbound section pointer */
    538597        oad(0xb8, 0); /* call to function */
    539         func_bound_offset = lbounds_section->data_offset;
    540598    }
    541599#endif
     
    545603ST_FUNC void gfunc_epilog(void)
    546604{
    547     int v, saved_ind;
     605    addr_t v, saved_ind;
    548606
    549607#ifdef CONFIG_TCC_BCHECK
    550608    if (tcc_state->do_bounds_check
    551609     && func_bound_offset != lbounds_section->data_offset) {
    552         int saved_ind;
    553         int *bounds_ptr;
    554         Sym *sym, *sym_data;
     610        addr_t saved_ind;
     611        addr_t *bounds_ptr;
     612        Sym *sym_data;
     613
    555614        /* add end of table info */
    556         bounds_ptr = section_ptr_add(lbounds_section, sizeof(int));
     615        bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
    557616        *bounds_ptr = 0;
     617
    558618        /* generate bound local allocation */
    559619        saved_ind = ind;
    560         ind = func_sub_sp_offset;
     620        ind = func_bound_ind;
    561621        sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
    562622                               func_bound_offset, lbounds_section->data_offset);
     
    564624               ind + 1, R_386_32);
    565625        oad(0xb8, 0); /* mov %eax, xxx */
    566         sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0);
    567         greloc(cur_text_section, sym,
    568                ind + 1, R_386_PC32);
    569         oad(0xe8, -4);
     626        gen_static_call(TOK___bound_local_new);
    570627        ind = saved_ind;
     628
    571629        /* generate bound check local freeing */
    572630        o(0x5250); /* save returned value, if any */
    573         greloc(cur_text_section, sym_data,
    574                ind + 1, R_386_32);
     631        greloc(cur_text_section, sym_data, ind + 1, R_386_32);
    575632        oad(0xb8, 0); /* mov %eax, xxx */
    576         sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0);
    577         greloc(cur_text_section, sym,
    578                ind + 1, R_386_PC32);
    579         oad(0xe8, -4);
     633        gen_static_call(TOK___bound_local_delete);
    580634        o(0x585a); /* restore returned value, if any */
    581635    }
    582636#endif
     637
     638    /* align local size to word & save local variables */
     639    v = (-loc + 3) & -4;
     640
     641#if USE_EBX
     642    o(0x8b);
     643    gen_modrm(TREG_EBX, VT_LOCAL, NULL, -(v+4));
     644#endif
     645
    583646    o(0xc9); /* leave */
    584647    if (func_ret_sub == 0) {
     
    589652        g(func_ret_sub >> 8);
    590653    }
    591     /* align local size to word & save local variables */
    592    
    593     v = (-loc + 3) & -4;
    594654    saved_ind = ind;
    595655    ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
    596656#ifdef TCC_TARGET_PE
    597657    if (v >= 4096) {
    598         Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
    599658        oad(0xb8, v); /* mov stacksize, %eax */
    600         oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
    601         greloc(cur_text_section, sym, ind-4, R_386_PC32);
     659        gen_static_call(TOK___chkstk); /* call __chkstk, (does the stackframe too) */
    602660    } else
    603661#endif
     
    606664        o(0xec81);  /* sub esp, stacksize */
    607665        gen_le32(v);
    608 #if FUNC_PROLOG_SIZE == 10
     666#ifdef TCC_TARGET_PE
    609667        o(0x90);  /* adjust to FUNC_PROLOG_SIZE */
    610668#endif
    611669    }
     670    o(0x53 * USE_EBX); /* push ebx */
    612671    ind = saved_ind;
    613672}
     
    616675ST_FUNC int gjmp(int t)
    617676{
    618     return psym(0xe9, t);
     677    return gjmp2(0xe9, t);
    619678}
    620679
     
    632691}
    633692
     693ST_FUNC void gtst_addr(int inv, int a)
     694{
     695    int v = vtop->r & VT_VALMASK;
     696    if (v == VT_CMP) {
     697        inv ^= (vtop--)->c.i;
     698        a -= ind + 2;
     699        if (a == (char)a) {
     700            g(inv - 32);
     701            g(a);
     702        } else {
     703            g(0x0f);
     704            oad(inv - 16, a - 4);
     705        }
     706    } else if ((v & ~1) == VT_JMP) {
     707        if ((v & 1) != inv) {
     708            gjmp_addr(a);
     709            gsym(vtop->c.i);
     710        } else {
     711            gsym(vtop->c.i);
     712            o(0x05eb);
     713            gjmp_addr(a);
     714        }
     715        vtop--;
     716    }
     717}
     718
    634719/* generate a test. set 'inv' to invert test. Stack entry is popped */
    635720ST_FUNC int gtst(int inv, int t)
    636721{
    637     int v, *p;
    638 
    639     v = vtop->r & VT_VALMASK;
    640     if (v == VT_CMP) {
     722    int v = vtop->r & VT_VALMASK;
     723    if (nocode_wanted) {
     724        ;
     725    } else if (v == VT_CMP) {
    641726        /* fast case : can jump directly since flags are set */
    642727        g(0x0f);
    643         t = psym((vtop->c.i - 16) ^ inv, t);
     728        t = gjmp2((vtop->c.i - 16) ^ inv, t);
    644729    } else if (v == VT_JMP || v == VT_JMPI) {
    645730        /* && or || optimization */
    646731        if ((v & 1) == inv) {
    647732            /* insert vtop->c jump list in t */
    648             p = &vtop->c.i;
    649             while (*p != 0)
    650                 p = (int *)(cur_text_section->data + *p);
    651             *p = t;
    652             t = vtop->c.i;
     733            uint32_t n1, n = vtop->c.i;
     734            if (n) {
     735                while ((n1 = read32le(cur_text_section->data + n)))
     736                    n = n1;
     737                write32le(cur_text_section->data + n, t);
     738                t = vtop->c.i;
     739            }
    653740        } else {
    654741            t = gjmp(t);
    655742            gsym(vtop->c.i);
    656         }
    657     } else {
    658         if (is_float(vtop->type.t) ||
    659             (vtop->type.t & VT_BTYPE) == VT_LLONG) {
    660             vpushi(0);
    661             gen_op(TOK_NE);
    662         }
    663         if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
    664             /* constant jmp optimization */
    665             if ((vtop->c.i != 0) != inv)
    666                 t = gjmp(t);
    667         } else {
    668             v = gv(RC_INT);
    669             o(0x85);
    670             o(0xc0 + v * 9);
    671             g(0x0f);
    672             t = psym(0x85 ^ inv, t);
    673743        }
    674744    }
     
    695765            if (c == (char)c) {
    696766                /* generate inc and dec for smaller code */
    697                 if (c==1 && opc==0) {
     767                if (c==1 && opc==0 && op != TOK_ADDC1) {
    698768                    o (0x40 | r); // inc
    699                 } else if (c==1 && opc==5) {
     769                } else if (c==1 && opc==5 && op != TOK_SUBC1) {
    700770                    o (0x48 | r); // dec
    701771                } else {
     
    789859        vtop--;
    790860        save_reg(TREG_EDX);
     861        /* save EAX too if used otherwise */
     862        save_reg_upstack(TREG_EAX, 1);
    791863        if (op == TOK_UMULL) {
    792864            o(0xf7); /* mul fr */
     
    816888
    817889/* generate a floating point operation 'v = t1 op t2' instruction. The
    818    two operands are guaranted to have the same floating point type */
     890   two operands are guaranteed to have the same floating point type */
    819891/* XXX: need to use ST1 too */
    820892ST_FUNC void gen_opf(int op)
     
    855927        if (swapped)
    856928            o(0xc9d9); /* fxch %st(1) */
    857         o(0xe9da); /* fucompp */
     929        if (op == TOK_EQ || op == TOK_NE)
     930            o(0xe9da); /* fucompp */
     931        else
     932            o(0xd9de); /* fcompp */
    858933        o(0xe0df); /* fnstsw %ax */
    859934        if (op == TOK_EQ) {
     
    901976        }
    902977        ft = vtop->type.t;
    903         fc = vtop->c.ul;
     978        fc = vtop->c.i;
    904979        if ((ft & VT_BTYPE) == VT_LDOUBLE) {
    905980            o(0xde); /* fxxxp %st, %st(1) */
     
    913988                v1.type.t = VT_INT;
    914989                v1.r = VT_LOCAL | VT_LVAL;
    915                 v1.c.ul = fc;
     990                v1.c.i = fc;
    916991                load(r, &v1);
    917992                fc = 0;
     
    9591034
    9601035/* convert fp to int 't' type */
    961 /* XXX: handle long long case */
    9621036ST_FUNC void gen_cvt_ftoi(int t)
    9631037{
    964     int r, r2, size;
    965     Sym *sym;
    966     CType ushort_type;
    967 
    968     ushort_type.t = VT_SHORT | VT_UNSIGNED;
    969     ushort_type.ref = 0;
    970 
    971     gv(RC_FLOAT);
    972     if (t != VT_INT)
    973         size = 8;
    974     else
    975         size = 4;
    976    
    977     o(0x2dd9); /* ldcw xxx */
    978     sym = external_global_sym(TOK___tcc_int_fpu_control,
    979                               &ushort_type, VT_LVAL);
    980     greloc(cur_text_section, sym,
    981            ind, R_386_32);
    982     gen_le32(0);
    983    
    984     oad(0xec81, size); /* sub $xxx, %esp */
    985     if (size == 4)
    986         o(0x1cdb); /* fistpl */
     1038    int bt = vtop->type.t & VT_BTYPE;
     1039    if (bt == VT_FLOAT)
     1040        vpush_global_sym(&func_old_type, TOK___fixsfdi);
     1041    else if (bt == VT_LDOUBLE)
     1042        vpush_global_sym(&func_old_type, TOK___fixxfdi);
    9871043    else
    988         o(0x3cdf); /* fistpll */
    989     o(0x24);
    990     o(0x2dd9); /* ldcw xxx */
    991     sym = external_global_sym(TOK___tcc_fpu_control,
    992                               &ushort_type, VT_LVAL);
    993     greloc(cur_text_section, sym,
    994            ind, R_386_32);
    995     gen_le32(0);
    996 
    997     r = get_reg(RC_INT);
    998     o(0x58 + r); /* pop r */
    999     if (size == 8) {
    1000         if (t == VT_LLONG) {
    1001             vtop->r = r; /* mark reg as used */
    1002             r2 = get_reg(RC_INT);
    1003             o(0x58 + r2); /* pop r2 */
    1004             vtop->r2 = r2;
    1005         } else {
    1006             o(0x04c483); /* add $4, %esp */
    1007         }
    1008     }
    1009     vtop->r = r;
     1044        vpush_global_sym(&func_old_type, TOK___fixdfdi);
     1045    vswap();
     1046    gfunc_call(1);
     1047    vpushi(0);
     1048    vtop->r = REG_IRET;
     1049    vtop->r2 = REG_LRET;
    10101050}
    10111051
     
    10301070ST_FUNC void gen_bounded_ptr_add(void)
    10311071{
    1032     Sym *sym;
    1033 
    10341072    /* prepare fast i386 function call (args in eax and edx) */
    10351073    gv2(RC_EAX, RC_EDX);
     
    10381076    save_regs(0);
    10391077    /* do a fast function call */
    1040     sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0);
    1041     greloc(cur_text_section, sym,
    1042            ind + 1, R_386_PC32);
    1043     oad(0xe8, -4);
     1078    gen_static_call(TOK___bound_ptr_add);
    10441079    /* returned pointer is in eax */
    10451080    vtop++;
    10461081    vtop->r = TREG_EAX | VT_BOUNDED;
    10471082    /* address of bounding function call point */
    1048     vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
     1083    vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
    10491084}
    10501085
     
    10531088ST_FUNC void gen_bounded_ptr_deref(void)
    10541089{
    1055     int func;
    1056     int size, align;
     1090    addr_t func;
     1091    int  size, align;
    10571092    Elf32_Rel *rel;
    10581093    Sym *sym;
     
    10831118    /* patch relocation */
    10841119    /* XXX: find a better solution ? */
    1085     rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul);
     1120    rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.i);
    10861121    sym = external_global_sym(func, &func_old_type, 0);
    10871122    if (!sym->c)
     
    10911126#endif
    10921127
     1128/* Save the stack pointer onto the stack */
     1129ST_FUNC void gen_vla_sp_save(int addr) {
     1130    /* mov %esp,addr(%ebp)*/
     1131    o(0x89);
     1132    gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
     1133}
     1134
     1135/* Restore the SP from a location on the stack */
     1136ST_FUNC void gen_vla_sp_restore(int addr) {
     1137    o(0x8b);
     1138    gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
     1139}
     1140
     1141/* Subtract from the stack pointer, and push the resulting value onto the stack */
     1142ST_FUNC void gen_vla_alloc(CType *type, int align) {
     1143#ifdef TCC_TARGET_PE
     1144    /* alloca does more than just adjust %rsp on Windows */
     1145    vpush_global_sym(&func_old_type, TOK_alloca);
     1146    vswap(); /* Move alloca ref past allocation size */
     1147    gfunc_call(1);
     1148#else
     1149    int r;
     1150    r = gv(RC_INT); /* allocation size */
     1151    /* sub r,%rsp */
     1152    o(0x2b);
     1153    o(0xe0 | r);
     1154    /* We align to 16 bytes rather than align */
     1155    /* and ~15, %esp */
     1156    o(0xf0e483);
     1157    vpop();
     1158#endif
     1159}
     1160
    10931161/* end of X86 code generator */
    10941162/*************************************************************/
Note: See TracChangeset for help on using the changeset viewer.