diff options
| author | jiang <30155751@qq.com> | 2014-05-04 13:18:31 +0800 |
|---|---|---|
| committer | jiang <30155751@qq.com> | 2014-05-04 13:18:31 +0800 |
| commit | 5e56fb635a23484d8fda8b54a40900d0a54b0ba1 (patch) | |
| tree | 6f7491150cfe01700c9863946906203adad0de13 /i386-gen.c | |
| parent | 089dea355a28da44376ce4f5195baa4b4e0b217d (diff) | |
| download | tinycc-5e56fb635a23484d8fda8b54a40900d0a54b0ba1.tar.gz tinycc-5e56fb635a23484d8fda8b54a40900d0a54b0ba1.tar.bz2 | |
Return to: e20c1eb99e1003c1e59522c136dbb15c52d7cc7c
1: The new patch for the other machines still have the problem.
2: libcrt Rename (what if gcc had libcrt as well)
3: parse_number exact problem
4: VT_VLS is to allow tcc
Compile the following
int b = 9;
struct st {
int a;
int b [b]
};
struct st st1;
st1.b [8] = 9;
printf ("% d \ n", st1.b [8]);
tcc a problem. Due to problems in front, and now can not be improved
5: they commit much, bug difficult to lock, you can not let other people help develop.
6: ('\ t') too
Thanks to Michael and Ray
Their criticism I have benefited!
Diffstat (limited to 'i386-gen.c')
| -rw-r--r-- | i386-gen.c | 190 |
1 files changed, 57 insertions, 133 deletions
@@ -21,7 +21,7 @@ #ifdef TARGET_DEFS_ONLY /* number of available registers */ -#define NB_REGS 8 +#define NB_REGS 4 #define NB_ASM_REGS 8 /* a register can belong to several classes. The classes must be @@ -33,24 +33,17 @@ #define RC_ST0 0x0008 #define RC_ECX 0x0010 #define RC_EDX 0x0020 -#define RC_EBX 0x0040 -#define RC_ESI 0x0080 -#define RC_EDI 0x0100 -#define RC_INT2 0x0200 #define RC_IRET RC_EAX /* function return: integer register */ #define RC_LRET RC_EDX /* function return: second integer register */ #define RC_FRET RC_ST0 /* function return: float register */ -#define RC_MASK (RC_INT|RC_INT2|RC_FLOAT) + /* pretty names for the registers */ enum { TREG_EAX = 0, TREG_ECX, TREG_EDX, - TREG_EBX, - TREG_ESP, TREG_ST0, - TREG_ESI, - TREG_EDI, + TREG_ESP = 4 }; /* return registers for function */ @@ -97,14 +90,10 @@ enum { #include "tcc.h" ST_DATA const int reg_classes[NB_REGS] = { - /* eax */ RC_INT | RC_EAX | RC_INT2, - /* ecx */ RC_INT | RC_ECX | RC_INT2, + /* eax */ RC_INT | RC_EAX, + /* ecx */ RC_INT | RC_ECX, /* edx */ RC_INT | RC_EDX, - RC_INT|RC_INT2|RC_EBX, - 0, /* st0 */ RC_FLOAT | RC_ST0, - RC_ESI|RC_INT2, - RC_EDI|RC_INT2, }; static unsigned long func_sub_sp_offset; @@ -237,14 +226,6 @@ ST_FUNC void load(int r, SValue *sv) v = fr & VT_VALMASK; if (fr & VT_LVAL) { - if(fr & VT_TMP){ - int size, align; - if((ft & VT_BTYPE) == VT_FUNC) - size = PTR_SIZE; - else - size = type_size(&sv->type, &align); - loc_stack(size, 0); - } if (v == VT_LLOCAL) { v1.type.t = VT_INT; v1.r = VT_LOCAL | VT_LVAL; @@ -253,7 +234,6 @@ ST_FUNC void load(int r, SValue *sv) if (!(reg_classes[fr] & RC_INT)) fr = get_reg(RC_INT); load(fr, &v1); - fc = 0; } if ((ft & VT_BTYPE) == VT_FLOAT) { o(0xd9); /* flds */ @@ -697,7 +677,7 @@ ST_FUNC int gtst(int inv, int t) /* fast case : can jump directly since flags are set */ g(0x0f); t = psym((vtop->c.i - 16) ^ inv, t); - } else if (v == VT_JMP || v == VT_JMPI) { + } else { /* VT_JMP || VT_JMPI */ /* && or || optimization */ if ((v & 1) == inv) { /* insert vtop->c jump list in t */ @@ -710,23 +690,6 @@ ST_FUNC int gtst(int inv, int t) t = gjmp(t); gsym(vtop->c.i); } - } else { - if (is_float(vtop->type.t) || - (vtop->type.t & VT_BTYPE) == VT_LLONG) { - vpushi(0); - gen_op(TOK_NE); - } - if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { - /* constant jmp optimization */ - if ((vtop->c.i != 0) != inv) - t = gjmp(t); - } else { - v = gv(RC_INT); - o(0x85); - o(0xc0 + v * 9); - g(0x0f); - t = psym(0x85 ^ inv, t); - } } vtop--; return t; @@ -735,48 +698,40 @@ ST_FUNC int gtst(int inv, int t) /* generate an integer binary operation */ ST_FUNC void gen_opi(int op) { - int r, fr, opc, fc, c; - int cc, uu, tt2; - - fr = vtop[0].r; - fc = vtop->c.ul; - cc = (fr & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST; - tt2 = (fr & (VT_LVAL | VT_LVAL_TYPE)) == VT_LVAL; + int r, fr, opc, c; switch(op) { case '+': case TOK_ADDC1: /* add with carry generation */ opc = 0; gen_op8: - vswap(); - r = gv(RC_INT); - vswap(); - if (cc) { + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { /* constant case */ + vswap(); + r = gv(RC_INT); + vswap(); c = vtop->c.i; if (c == (char)c) { /* generate inc and dec for smaller code */ - if (c == 1 && opc == 0) { + if (c==1 && opc==0) { o (0x40 | r); // inc - } else if (c == 1 && opc == 5) { + } else if (c==1 && opc==5) { o (0x48 | r); // dec } else { o(0x83); - o(0xc0 + r + opc*8); + o(0xc0 | (opc << 3) | r); g(c); } } else { o(0x81); - oad(0xc0 + r+ opc*8, c); + oad(0xc0 | (opc << 3) | r, c); } } else { - if(!tt2) - fr = gv(RC_INT); - o(0x03 + opc*8); - if(fr >= VT_CONST) - gen_modrm(r, fr, vtop->sym, fc); - else - o(0xc0 + fr + r*8); + gv2(RC_INT, RC_INT); + r = vtop[-1].r; + fr = vtop[0].r; + o((opc << 3) | 0x01); + o(0xc0 + r + fr * 8); } vtop--; if (op >= TOK_ULT && op <= TOK_GT) { @@ -804,28 +759,12 @@ ST_FUNC void gen_opi(int op) opc = 1; goto gen_op8; case '*': - opc = 5; - vswap(); - r = gv(RC_INT); - vswap(); - if(!tt2) - fr = gv(RC_INT); - if(r == TREG_EAX){ - if(fr != TREG_EDX) - save_reg(TREG_EDX); - o(0xf7); - if(fr >= VT_CONST) - gen_modrm(opc, fr, vtop->sym, fc); - else - o(0xc0 + fr + opc*8); - }else{ - o(0xaf0f); /* imul fr, r */ - if(fr >= VT_CONST) - gen_modrm(r, fr, vtop->sym, fc); - else - o(0xc0 + fr + r*8); - } + gv2(RC_INT, RC_INT); + r = vtop[-1].r; + fr = vtop[0].r; vtop--; + o(0xaf0f); /* imul fr, r */ + o(0xc0 + fr + r * 8); break; case TOK_SHL: opc = 4; @@ -836,71 +775,56 @@ ST_FUNC void gen_opi(int op) case TOK_SAR: opc = 7; gen_shift: - if (cc) { + opc = 0xc0 | (opc << 3); + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { /* constant case */ vswap(); r = gv(RC_INT); vswap(); - c = vtop->c.i; - if(c == 1){ - o(0xd1); - o(0xc0 + r + opc*8); - }else{ - o(0xc1); /* shl/shr/sar $xxx, r */ - o(0xc0 + r + opc*8); - g(c & 0x1f); - } + c = vtop->c.i & 0x1f; + o(0xc1); /* shl/shr/sar $xxx, r */ + o(opc | r); + g(c); } else { /* we generate the shift in ecx */ gv2(RC_INT, RC_ECX); r = vtop[-1].r; o(0xd3); /* shl/shr/sar %cl, r */ - o(0xc0 + r + opc*8); + o(opc | r); } vtop--; break; - case TOK_UMOD: - opc = 4; - uu = 1; - goto divmod; - case TOK_UDIV: - case TOK_UMULL: - opc = 6; - uu = 1; - goto divmod; case '/': - case '%': + case TOK_UDIV: case TOK_PDIV: - opc = 7; - uu = 0; - divmod: + case '%': + case TOK_UMOD: + case TOK_UMULL: /* first operand must be in eax */ /* XXX: need better constraint for second operand */ - if(!tt2){ - gv2(RC_EAX, RC_INT2); - fr = vtop[0].r; - }else{ - vswap(); - gv(RC_EAX); - vswap(); - } - save_reg(TREG_EDX); - if (op == TOK_UMULL) { + gv2(RC_EAX, RC_ECX); + r = vtop[-1].r; + fr = vtop[0].r; + vtop--; + save_reg(TREG_EDX); + if (op == TOK_UMULL) { o(0xf7); /* mul fr */ - vtop->r2 = TREG_EDX; - }else{ - o(uu ? 0xd231 : 0x99); /* xor %edx,%edx : cdq RDX:RAX <- sign-extend of RAX. */ - o(0xf7); /* div fr, %eax */ - } - if(fr >= VT_CONST) - gen_modrm(opc, fr, vtop->sym, fc); - else - o(0xc0 + fr + opc*8); - if (op == '%' || op == TOK_UMOD) - r = TREG_EDX; - else + o(0xe0 + fr); + vtop->r2 = TREG_EDX; r = TREG_EAX; - vtop--; + } else { + if (op == TOK_UDIV || op == TOK_UMOD) { + o(0xf7d231); /* xor %edx, %edx, div fr, %eax */ + o(0xf0 + fr); + } else { + o(0xf799); /* cltd, idiv fr, %eax */ + o(0xf8 + fr); + } + if (op == '%' || op == TOK_UMOD) + r = TREG_EDX; + else + r = TREG_EAX; + } vtop->r = r; break; default: |
