Mercurial > hg > tinycc
changeset 574:1f1a692f7563
Rename o() to gen_multibyte().
author | Rob Landley <rob@landley.net> |
---|---|
date | Tue, 18 Mar 2008 18:52:00 -0500 |
parents | 09b424940c88 |
children | 6912ed120df3 |
files | arm/gen.c i386/gen.c tcc.c |
diffstat | 3 files changed, 214 insertions(+), 231 deletions(-) [+] |
line wrap: on
line diff
--- a/arm/gen.c Tue Mar 18 18:50:19 2008 -0500 +++ b/arm/gen.c Tue Mar 18 18:52:00 2008 -0500 @@ -149,7 +149,7 @@ static unsigned long func_sub_sp_offset,last_itod_magic; static int leaffunc; -void o(unsigned long i) +void gen_multibyte(unsigned long i) { /* this is a good place to start adding big-endian support*/ int ind1; @@ -226,8 +226,7 @@ void stuff_const_harder(unsigned long op,unsigned long v) { unsigned long x; x=stuff_const(op,v); - if(x) - o(x); + if(x) gen_multibyte(x); else { unsigned long a[16],nv,no,o2,n2; int i,j,k; @@ -238,8 +237,8 @@ for(i=0;i<12;i++) for(j=i+4;i<13+i;i++) if((v&(a[i]|a[j]))==v) { - o(stuff_const(op,v&a[i])); - o(stuff_const(o2,v&a[j])); + gen_multibyte(stuff_const(op,v&a[i])); + gen_multibyte(stuff_const(o2,v&a[j])); return; } no=op^0xC00000; @@ -248,17 +247,17 @@ for(i=0;i<12;i++) for(j=i+4;i<13+i;i++) if((nv&(a[i]|a[j]))==nv) { - o(stuff_const(no,nv&a[i])); - o(stuff_const(n2,nv&a[j])); + gen_multibyte(stuff_const(no,nv&a[i])); + gen_multibyte(stuff_const(n2,nv&a[j])); return; } for(i=0;i<8;i++) for(j=i+4;i<12;i++) for(k=j+4;k<13+i;i++) if((v&(a[i]|a[j]|a[k]))==v) { - o(stuff_const(op,v&a[i])); - o(stuff_const(o2,v&a[j])); - o(stuff_const(o2,v&a[k])); + gen_multibyte(stuff_const(op,v&a[i])); + gen_multibyte(stuff_const(o2,v&a[j])); + gen_multibyte(stuff_const(o2,v&a[k])); return; } no=op^0xC00000; @@ -267,15 +266,15 @@ for(j=i+4;i<12;i++) for(k=j+4;k<13+i;i++) if((nv&(a[i]|a[j]|a[k]))==nv) { - o(stuff_const(no,nv&a[i])); - o(stuff_const(n2,nv&a[j])); - o(stuff_const(n2,nv&a[k])); + gen_multibyte(stuff_const(no,nv&a[i])); + gen_multibyte(stuff_const(n2,nv&a[j])); + gen_multibyte(stuff_const(n2,nv&a[k])); return; } - o(stuff_const(op,v&a[0])); - o(stuff_const(o2,v&a[4])); - o(stuff_const(o2,v&a[8])); - o(stuff_const(o2,v&a[12])); + gen_multibyte(stuff_const(op,v&a[0])); + gen_multibyte(stuff_const(o2,v&a[4])); + gen_multibyte(stuff_const(o2,v&a[8])); + gen_multibyte(stuff_const(o2,v&a[12])); } } @@ -359,13 +358,13 @@ *base=14; // lr y=stuff_const(x,*off&~maxoff); if(y) { - o(y); + gen_multibyte(y); *off&=maxoff; return; } y=stuff_const(x,(*off+maxoff)&~maxoff); if(y) { - o(y); + gen_multibyte(y); *sgn=!*sgn; *off=((*off+maxoff)&~maxoff)-*off; return; @@ -491,7 +490,7 @@ op|=0x800000; if ((ft & VT_BTYPE) != VT_FLOAT) op|=0x100; /* flds -> fldd */ - o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16)); + gen_multibyte(op|(vfpr(r)<<12)|(fc>>2)|(base<<16)); #else op=0xED100100; if(!sign) @@ -505,7 +504,7 @@ else if ((ft & VT_BTYPE) == VT_LDOUBLE) op|=0x400000; #endif - o(op|(fpr(r)<<12)|(fc>>2)|(base<<16)); + gen_multibyte(op|(fpr(r)<<12)|(fc>>2)|(base<<16)); #endif } else if((ft & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE || (ft & VT_BTYPE) == VT_SHORT) { @@ -517,7 +516,7 @@ op|=0x40; if(!sign) op|=0x800000; - o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf)); + gen_multibyte(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf)); } else { calcaddr(&base,&fc,&sign,4095,0); op=0xE5100000; @@ -525,7 +524,7 @@ op|=0x800000; if ((ft & VT_BTYPE) == VT_BYTE) op|=0x400000; - o(op|(intr(r)<<12)|fc|(base<<16)); + gen_multibyte(op|(intr(r)<<12)|fc|(base<<16)); } return; } @@ -533,47 +532,47 @@ if (v == VT_CONST) { op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.ul); if (fr & VT_SYM || !op) { - o(0xE59F0000|(intr(r)<<12)); - o(0xEA000000); + gen_multibyte(0xE59F0000|(intr(r)<<12)); + gen_multibyte(0xEA000000); if(fr & VT_SYM) greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32); - o(sv->c.ul); + gen_multibyte(sv->c.ul); } else - o(op); + gen_multibyte(op); return; } else if (v == VT_LOCAL) { op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.ul); if (fr & VT_SYM || !op) { - o(0xE59F0000|(intr(r)<<12)); - o(0xEA000000); + gen_multibyte(0xE59F0000|(intr(r)<<12)); + gen_multibyte(0xEA000000); if(fr & VT_SYM) // needed ? greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32); - o(sv->c.ul); - o(0xE08B0000|(intr(r)<<12)|intr(r)); + gen_multibyte(sv->c.ul); + gen_multibyte(0xE08B0000|(intr(r)<<12)|intr(r)); } else - o(op); + gen_multibyte(op); return; } else if(v == VT_CMP) { - o(mapcc(sv->c.ul)|0x3A00001|(intr(r)<<12)); - o(mapcc(negcc(sv->c.ul))|0x3A00000|(intr(r)<<12)); + gen_multibyte(mapcc(sv->c.ul)|0x3A00001|(intr(r)<<12)); + gen_multibyte(mapcc(negcc(sv->c.ul))|0x3A00000|(intr(r)<<12)); return; } else if (v == VT_JMP || v == VT_JMPI) { int t; t = v & 1; - o(0xE3A00000|(intr(r)<<12)|t); - o(0xEA000000); + gen_multibyte(0xE3A00000|(intr(r)<<12)|t); + gen_multibyte(0xEA000000); gsym(sv->c.ul); - o(0xE3A00000|(intr(r)<<12)|(t^1)); + gen_multibyte(0xE3A00000|(intr(r)<<12)|(t^1)); return; } else if (v < VT_CONST) { if(is_float(ft)) #ifdef TCC_ARM_VFP - o(0xEEB00A40|(vfpr(r)<<12)|vfpr(v)|T2CPR(ft)); /* fcpyX */ + gen_multibyte(0xEEB00A40|(vfpr(r)<<12)|vfpr(v)|T2CPR(ft)); /* fcpyX */ #else - o(0xEE008180|(fpr(r)<<12)|fpr(v)); + gen_multibyte(0xEE008180|(fpr(r)<<12)|fpr(v)); #endif else - o(0xE1A00000|(intr(r)<<12)|intr(v)); + gen_multibyte(0xE1A00000|(intr(r)<<12)|intr(v)); return; } } @@ -623,7 +622,7 @@ op|=0x800000; if ((ft & VT_BTYPE) != VT_FLOAT) op|=0x100; /* fsts -> fstd */ - o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16)); + gen_multibyte(op|(vfpr(r)<<12)|(fc>>2)|(base<<16)); #else op=0xED000100; if(!sign) @@ -637,7 +636,7 @@ if ((ft & VT_BTYPE) == VT_LDOUBLE) op|=0x400000; #endif - o(op|(fpr(r)<<12)|(fc>>2)|(base<<16)); + gen_multibyte(op|(fpr(r)<<12)|(fc>>2)|(base<<16)); #endif return; } else if((ft & VT_BTYPE) == VT_SHORT) { @@ -645,7 +644,7 @@ op=0xE14000B0; if(!sign) op|=0x800000; - o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf)); + gen_multibyte(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf)); } else { calcaddr(&base,&fc,&sign,4095,0); op=0xE5000000; @@ -653,7 +652,7 @@ op|=0x800000; if ((ft & VT_BTYPE) == VT_BYTE) op|=0x400000; - o(op|(intr(r)<<12)|fc|(base<<16)); + gen_multibyte(op|(intr(r)<<12)|fc|(base<<16)); } return; } @@ -680,21 +679,21 @@ greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24); } else put_elf_reloc(symtab_section, cur_text_section, ind, R_ARM_PC24, 0); - o(x|(is_jmp?0xE0000000:0xE1000000)); + gen_multibyte(x|(is_jmp?0xE0000000:0xE1000000)); } else { if(!is_jmp) - o(0xE28FE004); // add lr,pc,#4 - o(0xE51FF004); // ldr pc,[pc,#-4] + gen_multibyte(0xE28FE004); // add lr,pc,#4 + gen_multibyte(0xE51FF004); // ldr pc,[pc,#-4] if (vtop->r & VT_SYM) greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32); - o(vtop->c.ul); + gen_multibyte(vtop->c.ul); } } else { /* otherwise, indirect call */ r = gv(RC_INT); if(!is_jmp) - o(0xE1A0E00F); // mov lr,pc - o(0xE1A0F000|intr(r)); // mov pc,r + gen_multibyte(0xE1A0E00F); // mov lr,pc + gen_multibyte(0xE1A0F000|intr(r)); // mov pc,r } } @@ -768,7 +767,7 @@ gadd_sp(-size); /* generate structure store */ r = get_reg(RC_INT); - o(0xE1A0000D|(intr(r)<<12)); + gen_multibyte(0xE1A0000D|(intr(r)<<12)); vset(&vtop->type, r | VT_LVAL, 0); vswap(); vstore(); @@ -783,7 +782,7 @@ size=8; r|=0x101; /* fstms -> fstmd */ } - o(0xED2D0A01+r); + gen_multibyte(0xED2D0A01+r); #else r=fpr(gv(RC_FLOAT))<<12; if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) @@ -798,7 +797,7 @@ else if(size == 8) r|=0x8000; - o(0xED2D0100|r|(size>>2)); + gen_multibyte(0xED2D0100|r|(size>>2)); #endif vtop--; args_size += size; @@ -816,7 +815,7 @@ } if(s==RC_INT) { r = gv(s); - o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */ + gen_multibyte(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */ vtop--; } else { plan2[keep]=s; @@ -833,13 +832,13 @@ #ifdef TCC_ARM_EABI if(vtop->type.t == VT_VOID) { if(s == RC_INT) - o(0xE24DD004); /* sub sp,sp,#4 */ + gen_multibyte(0xE24DD004); /* sub sp,sp,#4 */ vtop--; } else #endif if(s == RC_INT) { r = gv(s); - o(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */ + gen_multibyte(0xE52D0004|(intr(r)<<12)); /* str r,[sp,#-4]! */ vtop--; } else { plan2[keep]=s; @@ -862,7 +861,7 @@ todo&=((1<<n)-1); if(todo) { int i; - o(0xE8BD0000|todo); + gen_multibyte(0xE8BD0000|todo); for(i=0;i<4;i++) if(todo&(1<<i)) { vpushi(0); @@ -887,10 +886,10 @@ #ifdef TCC_ARM_VFP else if(is_float(vtop->type.ref->type.t)) { if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) { - o(0xEE000A10); /* fmsr s0,r0 */ + gen_multibyte(0xEE000A10); /* fmsr s0,r0 */ } else { - o(0xEE000B10); /* fmdlr d0,r0 */ - o(0xEE201B10); /* fmdhr d0,r1 */ + gen_multibyte(0xEE000B10); /* fmdlr d0,r0 */ + gen_multibyte(0xEE201B10); /* fmdhr d0,r1 */ } } #endif @@ -921,7 +920,7 @@ size = type_size(&sym2->type, &align); n += (size + 3) / 4; } - o(0xE1A0C00D); /* mov ip,sp */ + gen_multibyte(0xE1A0C00D); /* mov ip,sp */ if(func_type->ref->c == FUNC_ELLIPSIS) n=4; if(n) { @@ -930,12 +929,12 @@ #ifdef TCC_ARM_EABI n=(n+1)&-2; #endif - o(0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */ + gen_multibyte(0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */ } - o(0xE92D5800); /* save fp, ip, lr */ - o(0xE28DB00C); /* add fp, sp, #12 */ + gen_multibyte(0xE92D5800); /* save fp, ip, lr */ + gen_multibyte(0xE28DB00C); /* add fp, sp, #12 */ func_sub_sp_offset = ind; - o(0xE1A00000); /* nop, leave space for stack adjustment */ + gen_multibyte(0xE1A00000); /* nop, leave space for stack adjustment */ while ((sym = sym->next)) { CType *type; type = &sym->type; @@ -960,14 +959,14 @@ #ifdef TCC_ARM_EABI if(is_float(func_vt.t)) { if((func_vt.t & VT_BTYPE) == VT_FLOAT) - o(0xEE100A10); /* fmrs r0, s0 */ + gen_multibyte(0xEE100A10); /* fmrs r0, s0 */ else { - o(0xEE100B10); /* fmrdl r0, d0 */ - o(0xEE301B10); /* fmrdh r1, d0 */ + gen_multibyte(0xEE100B10); /* fmrdl r0, d0 */ + gen_multibyte(0xEE301B10); /* fmrdh r1, d0 */ } } #endif - o(0xE91BA800); /* restore fp, sp, pc */ + gen_multibyte(0xE91BA800); /* restore fp, sp, pc */ diff = (-loc + 3) & -4; #ifdef TCC_ARM_EABI if(!leaffunc) @@ -980,10 +979,10 @@ else { unsigned long addr; addr=ind; - o(0xE59FC004); /* ldr ip,[pc+4] */ - o(0xE04BD00C); /* sub sp,fp,ip */ - o(0xE1A0F00E); /* mov pc,lr */ - o(diff); + gen_multibyte(0xE59FC004); /* ldr ip,[pc+4] */ + gen_multibyte(0xE04BD00C); /* sub sp,fp,ip */ + gen_multibyte(0xE1A0F00E); /* mov pc,lr */ + gen_multibyte(diff); *(unsigned long *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(func_sub_sp_offset,addr,1); } } @@ -994,7 +993,7 @@ { int r; r=ind; - o(0xE0000000|encbranch(r,t,1)); + gen_multibyte(0xE0000000|encbranch(r,t,1)); return r; } @@ -1014,7 +1013,7 @@ if (v == VT_CMP) { op=mapcc(inv?negcc(vtop->c.i):vtop->c.i); op|=encbranch(r,t,1); - o(op); + gen_multibyte(op); t=r; } else if (v == VT_JMP || v == VT_JMPI) { if ((v & 1) == inv) { @@ -1042,10 +1041,10 @@ if (is_float(vtop->type.t)) { r=gv(RC_FLOAT); #ifdef TCC_ARM_VFP - o(0xEEB50A40|(vfpr(r)<<12)|T2CPR(vtop->type.t)); /* fcmpzX */ - o(0xEEF1FA10); /* fmstat */ + gen_multibyte(0xEEB50A40|(vfpr(r)<<12)|T2CPR(vtop->type.t)); /* fcmpzX */ + gen_multibyte(0xEEF1FA10); /* fmstat */ #else - o(0xEE90F118|(fpr(r)<<16)); + gen_multibyte(0xEE90F118|(fpr(r)<<16)); #endif vtop->r = VT_CMP; vtop->c.i = TOK_NE; @@ -1056,7 +1055,7 @@ t = gjmp(t); } else { v = gv(RC_INT); - o(0xE3300000|(intr(v)<<16)); + gen_multibyte(0xE3300000|(intr(v)<<16)); vtop->r = VT_CMP; vtop->c.i = TOK_NE; return gtst(inv, t); @@ -1115,7 +1114,7 @@ r = vtop[-1].r; fr = vtop[0].r; vtop--; - o(0xE0000090|(intr(r)<<16)|(intr(r)<<8)|intr(fr)); + gen_multibyte(0xE0000090|(intr(r)<<16)|(intr(r)<<8)|intr(fr)); return; case TOK_SHL: opc = 0; @@ -1152,7 +1151,7 @@ c=vtop[-1].r; vtop[-1].r=get_reg_ex(RC_INT,regmask(c)); vtop--; - o(0xE0800090|(r<<16)|(intr(vtop->r)<<12)|(intr(c)<<8)|intr(vtop[1].r)); + gen_multibyte(0xE0800090|(r<<16)|(intr(vtop->r)<<12)|(intr(c)<<8)|intr(vtop[1].r)); return; default: opc = 0x15; @@ -1179,13 +1178,13 @@ x=stuff_const(opc|0x2000000,vtop->c.i); if(x) { r=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r))); - o(x|(r<<12)); + gen_multibyte(x|(r<<12)); goto done; } } fr=intr(gv(RC_INT)); r=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r))); - o(opc|(r<<12)|fr); + gen_multibyte(opc|(r<<12)|fr); done: vtop--; if (op >= TOK_ULT && op <= TOK_GT) { @@ -1205,11 +1204,11 @@ if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { fr=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r))); c = vtop->c.i & 0x1f; - o(opc|(c<<7)|(fr<<12)); + gen_multibyte(opc|(c<<7)|(fr<<12)); } else { fr=intr(gv(RC_INT)); c=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r))); - o(opc|(c<<12)|(fr<<8)|0x10); + gen_multibyte(opc|(c<<12)|(fr<<8)|0x10); } vtop--; break; @@ -1292,14 +1291,14 @@ x|=0x80; /* fcmpX -> fcmpeX */ if(is_zero(0)) { vtop--; - o(x|0x10000|(vfpr(gv(RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */ + gen_multibyte(x|0x10000|(vfpr(gv(RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */ } else { x|=vfpr(gv(RC_FLOAT)); vswap(); - o(x|(vfpr(gv(RC_FLOAT))<<12)); + gen_multibyte(x|(vfpr(gv(RC_FLOAT))<<12)); vtop--; } - o(0xEEF1FA10); /* fmstat */ + gen_multibyte(0xEEF1FA10); /* fmstat */ switch(op) { case TOK_LE: op=TOK_ULE; break; @@ -1325,7 +1324,7 @@ vtop->r=get_reg_ex(RC_FLOAT,r); if(!fneg) vtop--; - o(x|(vfpr(vtop->r)<<12)); + gen_multibyte(x|(vfpr(vtop->r)<<12)); } #else @@ -1529,7 +1528,7 @@ c1=fpr(vtop[-1].r); } vtop--; - o(x|(r<<16)|(c1<<12)|r2); + gen_multibyte(x|(r<<16)|(c1<<12)|r2); } #endif @@ -1543,17 +1542,17 @@ r=intr(gv(RC_INT)); #ifdef TCC_ARM_VFP r2=vfpr(vtop->r=get_reg(RC_FLOAT)); - o(0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */ + gen_multibyte(0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */ r2<<=12; if(!(vtop->type.t & VT_UNSIGNED)) r2|=0x80; /* fuitoX -> fsituX */ - o(0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/ + gen_multibyte(0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/ #else r2=fpr(vtop->r=get_reg(RC_FLOAT)); - o(0xEE000190|(r2<<16)|(r<<12)); + gen_multibyte(0xEE000190|(r2<<16)|(r<<12)); if((vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) { unsigned int off=0; - o(0xE3500000|(r<<12)); + gen_multibyte(0xE3500000|(r<<12)); r=fpr(get_reg(RC_FLOAT)); if(last_itod_magic) { off=ind+8-last_itod_magic; @@ -1561,14 +1560,14 @@ if(off>255) off=0; } - o(0xBD1F8100|(r<<12)|off); + gen_multibyte(0xBD1F8100|(r<<12)|off); if(!off) { - o(0xEA000001); + gen_multibyte(0xEA000001); last_itod_magic=ind; - o(0x41F00000); - o(0); + gen_multibyte(0x41F00000); + gen_multibyte(0); } - o(0xBE000180|(r2<<16)|(r2<<12)|r); + gen_multibyte(0xBE000180|(r2<<16)|(r2<<12)|r); } #endif return; @@ -1614,9 +1613,9 @@ #ifdef TCC_ARM_VFP r=vfpr(gv(RC_FLOAT)); u=u?0:0x10000; - o(0xEEBC0A40|(r<<12)|r|T2CPR(r2)); /* ftoXiY */ + gen_multibyte(0xEEBC0A40|(r<<12)|r|T2CPR(r2)); /* ftoXiY */ r2=intr(vtop->r=get_reg(RC_INT)); - o(0xEE100A10|(r<<16)|(r2<<12)); + gen_multibyte(0xEE100A10|(r<<16)|(r2<<12)); return; #else if(u) { @@ -1633,7 +1632,7 @@ } else { r=fpr(gv(RC_FLOAT)); r2=intr(vtop->r=get_reg(RC_INT)); - o(0xEE100170|(r2<<12)|r); + gen_multibyte(0xEE100170|(r2<<12)|r); return; } #endif @@ -1668,7 +1667,7 @@ #ifdef TCC_ARM_VFP if(((vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) { int r=vfpr(gv(RC_FLOAT)); - o(0xEEB70AC0|(r<<12)|r|T2CPR(vtop->type.t)); + gen_multibyte(0xEEB70AC0|(r<<12)|r|T2CPR(vtop->type.t)); } #else /* all we have to do on i386 and FPA ARM is to put the float in a register */
--- a/i386/gen.c Tue Mar 18 18:50:19 2008 -0500 +++ b/i386/gen.c Tue Mar 18 18:52:00 2008 -0500 @@ -90,7 +90,8 @@ ind = ind1; } -void o(unsigned int c) +// Output a variable number of bytes, little endian, ignoring high zero bytes. +void gen_multibyte(unsigned int c) { while (c) { gen_byte(c); @@ -98,6 +99,7 @@ } } +// Output 4 bytes little endian void gen_le32(int c) { gen_byte(c); @@ -134,7 +136,7 @@ int ind1; if (!cur_text_section) return 0; - o(c); + gen_multibyte(c); ind1 = ind + 4; if (ind1 > cur_text_section->data_allocated) section_realloc(cur_text_section, ind1); @@ -152,20 +154,20 @@ gen_le32(c); } -/* generate a modrm reference. 'op_reg' contains the addtionnal 3 +/* generate a modrm reference. 'op_reg' contains the addtional 3 opcode bits */ static void gen_modrm(int op_reg, int r, Sym *sym, int c) { - op_reg = op_reg << 3; + op_reg <<= 3; if ((r & VT_VALMASK) == VT_CONST) { /* constant memory reference */ - o(0x05 | op_reg); + gen_multibyte(0x05 | op_reg); // XXX possibly gen_byte? gen_addr32(r, sym, c); } else if ((r & VT_VALMASK) == VT_LOCAL) { /* currently, we use only ebp as base */ if (c == (char)c) { /* short reference */ - o(0x45 | op_reg); + gen_multibyte(0x45 | op_reg); // XXX possibly gen_byte? gen_byte(c); } else { oad(0x85 | op_reg, c); @@ -196,47 +198,47 @@ fr = r; } if ((ft & VT_BTYPE) == VT_FLOAT) { - o(0xd9); /* flds */ + gen_byte(0xd9); /* flds */ r = 0; } else if ((ft & VT_BTYPE) == VT_DOUBLE) { - o(0xdd); /* fldl */ + gen_byte(0xdd); /* fldl */ r = 0; } else if ((ft & VT_BTYPE) == VT_LDOUBLE) { - o(0xdb); /* fldt */ + gen_byte(0xdb); /* fldt */ r = 5; } else if ((ft & VT_TYPE) == VT_BYTE) { - o(0xbe0f); /* movsbl */ + gen_multibyte(0xbe0f); /* movsbl */ } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) { - o(0xb60f); /* movzbl */ + gen_multibyte(0xb60f); /* movzbl */ } else if ((ft & VT_TYPE) == VT_SHORT) { - o(0xbf0f); /* movswl */ + gen_multibyte(0xbf0f); /* movswl */ } else if ((ft & VT_TYPE) == (VT_SHORT | VT_UNSIGNED)) { - o(0xb70f); /* movzwl */ + gen_multibyte(0xb70f); /* movzwl */ } else { - o(0x8b); /* movl */ + gen_byte(0x8b); /* movl */ } gen_modrm(r, fr, sv->sym, fc); } else { if (v == VT_CONST) { - o(0xb8 + r); /* mov $xx, r */ + gen_multibyte(0xb8 + r); /* mov $xx, r */ // XXX possibly gen_byte? gen_addr32(fr, sv->sym, fc); } else if (v == VT_LOCAL) { - o(0x8d); /* lea xxx(%ebp), r */ + gen_byte(0x8d); /* lea xxx(%ebp), r */ gen_modrm(r, VT_LOCAL, sv->sym, fc); } else if (v == VT_CMP) { oad(0xb8 + r, 0); /* mov $0, r */ - o(0x0f); /* setxx %br */ - o(fc); - o(0xc0 + r); + gen_byte(0x0f); /* setxx %br */ + gen_multibyte(fc); // XXX possibly gen_byte? + gen_multibyte(0xc0 + r); // XXX possibly gen_byte? } else if (v == VT_JMP || v == VT_JMPI) { t = v & 1; oad(0xb8 + r, t); /* mov $1, r */ - o(0x05eb); /* jmp after */ + gen_multibyte(0x05eb); /* jmp after */ gsym(fc); oad(0xb8 + r, t ^ 1); /* mov $0, r */ } else if (v != r) { - o(0x89); - o(0xc0 + r + v * 8); /* mov v, r */ + gen_byte(0x89); + gen_multibyte(0xc0 + r + v * 8); /* mov v, r */ // XXX possibly gen_byte? } } } @@ -252,36 +254,33 @@ bt = ft & VT_BTYPE; /* XXX: incorrect if float reg to reg */ if (bt == VT_FLOAT) { - o(0xd9); /* fsts */ + gen_byte(0xd9); /* fsts */ r = 2; } else if (bt == VT_DOUBLE) { - o(0xdd); /* fstpl */ + gen_byte(0xdd); /* fstpl */ r = 2; } else if (bt == VT_LDOUBLE) { - o(0xc0d9); /* fld %st(0) */ - o(0xdb); /* fstpt */ + gen_multibyte(0xc0d9); /* fld %st(0) */ // XXX combine? + gen_byte(0xdb); /* fstpt */ r = 7; } else { - if (bt == VT_SHORT) - o(0x66); - if (bt == VT_BYTE || bt == VT_BOOL) - o(0x88); - else - o(0x89); + if (bt == VT_SHORT) gen_byte(0x66); + else if (bt == VT_BYTE || bt == VT_BOOL) gen_byte(0x88); + else gen_byte(0x89); } if (fr == VT_CONST || fr == VT_LOCAL || (v->r & VT_LVAL)) { gen_modrm(r, v->r, v->sym, fc); } else if (fr != r) { - o(0xc0 + fr + r * 8); /* mov r, fr */ + gen_multibyte(0xc0 + fr + r * 8); /* mov r, fr */ // XXX maybe gen_byte? } } static void gadd_sp(int val) { if (val == (char)val) { - o(0xc483); + gen_multibyte(0xc483); gen_byte(val); } else { oad(0xc481, val); /* add $xxx, %esp */ @@ -307,8 +306,8 @@ } else { /* otherwise, indirect call */ r = gv(RC_INT); - o(0xff); /* call/jmp *r */ - o(0xd0 + r + (is_jmp << 4)); + gen_byte(0xff); /* call/jmp *r */ + gen_multibyte(0xd0 + r + (is_jmp << 4)); // XXX maybe gen_byte? } } @@ -333,26 +332,21 @@ oad(0xec81, size); /* sub $xxx, %esp */ /* generate structure store */ r = get_reg(RC_INT); - o(0x89); /* mov %esp, r */ - o(0xe0 + r); + gen_byte(0x89); /* mov %esp, r */ + gen_multibyte(0xe0 + r); // XXX maybe gen_byte? Combine? vset(&vtop->type, r | VT_LVAL, 0); vswap(); vstore(); args_size += size; } else if (is_float(vtop->type.t)) { gv(RC_FLOAT); /* only one float register */ - if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) - size = 4; - else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) - size = 8; - else - size = 12; + if ((vtop->type.t & VT_BTYPE) == VT_FLOAT) size = 4; + else if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) size = 8; + else size = 12; oad(0xec81, size); /* sub $xxx, %esp */ - if (size == 12) - o(0x7cdb); - else - o(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */ - gen_byte(0x24); + if (size == 12) gen_multibyte(0x7cdb); + else gen_multibyte(0x5cd9 + size - 4); /* fstp[s|l] 0(%esp) */ + gen_byte(0x24); // XXX maybe combine? gen_byte(0x00); args_size += size; } else { @@ -361,11 +355,9 @@ r = gv(RC_INT); if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { size = 8; - o(0x50 + vtop->r2); /* push r */ - } else { - size = 4; - } - o(0x50 + r); /* push r */ + gen_multibyte(0x50 + vtop->r2); /* push r */ // XXX maybe gen_byte? + } else size = 4; + gen_multibyte(0x50 + r); /* push r */ // XXX maybe gen_byte? args_size += size; } vtop--; @@ -388,7 +380,7 @@ for(i = 0;i < fastcall_nb_regs; i++) { if (args_size <= 0) break; - o(0x58 + fastcall_regs_ptr[i]); /* pop r */ + gen_multibyte(0x58 + fastcall_regs_ptr[i]); /* pop r */ // XXX maybe gen_byte? /* XXX: incorrect for struct/floats */ args_size -= 4; } @@ -451,7 +443,7 @@ if (param_index < fastcall_nb_regs) { /* save FASTCALL register */ loc -= 4; - o(0x89); /* movl */ + gen_byte(0x89); /* movl */ gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc); param_addr = loc; } else { @@ -502,7 +494,7 @@ oad(0xe8, -4); ind = saved_ind; /* generate bound check local freeing */ - o(0x5250); /* save returned value, if any */ + gen_multibyte(0x5250); /* save returned value, if any */ greloc(cur_text_section, sym_data, ind + 1, R_386_32); oad(0xb8, 0); /* mov %eax, xxx */ @@ -510,14 +502,14 @@ greloc(cur_text_section, sym, ind + 1, R_386_PC32); oad(0xe8, -4); - o(0x585a); /* restore returned value, if any */ + gen_multibyte(0x585a); /* restore returned value, if any */ } #endif - o(0xc9); /* leave */ + gen_byte(0xc9); /* leave */ if (func_ret_sub == 0) { - o(0xc3); /* ret */ + gen_byte(0xc3); /* ret */ } else { - o(0xc2); /* ret n */ + gen_byte(0xc2); /* ret n */ gen_byte(func_ret_sub); gen_byte(func_ret_sub >> 8); } @@ -534,8 +526,8 @@ } else #endif { - o(0xe58955); /* push %ebp, mov %esp, %ebp */ - o(0xec81); /* sub esp, stacksize */ + gen_multibyte(0xe58955); /* push %ebp, mov %esp, %ebp */ + gen_multibyte(0xec81); /* sub esp, stacksize */ } gen_le32(v); ind = saved_ind; @@ -595,8 +587,8 @@ t = gjmp(t); } else { v = gv(RC_INT); - o(0x85); - o(0xc0 + v * 9); + gen_byte(0x85); + gen_multibyte(0xc0 + v * 9); // XXX maybe gen_byte? gen_byte(0x0f); t = psym(0x85 ^ inv, t); } @@ -623,19 +615,19 @@ c = vtop->c.i; if (c == (char)c) { /* XXX: generate inc and dec for smaller code ? */ - o(0x83); - o(0xc0 | (opc << 3) | r); + gen_byte(0x83); + gen_multibyte(0xc0 | (opc << 3) | r); // XXX maybe gen_byte? gen_byte(c); } else { - o(0x81); + gen_byte(0x81); oad(0xc0 | (opc << 3) | r, c); } } else { gv2(RC_INT, RC_INT); r = vtop[-1].r; fr = vtop[0].r; - o((opc << 3) | 0x01); - o(0xc0 + r + fr * 8); + gen_multibyte((opc << 3) | 0x01); // XXX maybe gen_byte? + gen_multibyte(0xc0 + r + fr * 8); // XXX maybe gen_byte? } vtop--; if (op >= TOK_ULT && op <= TOK_GT) { @@ -667,8 +659,8 @@ r = vtop[-1].r; fr = vtop[0].r; vtop--; - o(0xaf0f); /* imul fr, r */ - o(0xc0 + fr + r * 8); + gen_multibyte(0xaf0f); /* imul fr, r */ + gen_multibyte(0xc0 + fr + r * 8); // XXX maybe gen_byte? break; case TOK_SHL: opc = 4; @@ -686,15 +678,15 @@ r = gv(RC_INT); vswap(); c = vtop->c.i & 0x1f; - o(0xc1); /* shl/shr/sar $xxx, r */ - o(opc | r); + gen_byte(0xc1); /* shl/shr/sar $xxx, r */ + gen_multibyte(opc | r); // XXX maybe gen_byte? gen_byte(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(opc | r); + gen_byte(0xd3); /* shl/shr/sar %cl, r */ + gen_multibyte(opc | r); // XXX maybe gen_byte? } vtop--; break; @@ -712,17 +704,17 @@ vtop--; save_reg(TREG_EDX); if (op == TOK_UMULL) { - o(0xf7); /* mul fr */ - o(0xe0 + fr); + gen_byte(0xf7); /* mul fr */ + gen_multibyte(0xe0 + fr); // XXX maybe gen_byte, or combine? vtop->r2 = TREG_EDX; r = TREG_EAX; } else { if (op == TOK_UDIV || op == TOK_UMOD) { - o(0xf7d231); /* xor %edx, %edx, div fr, %eax */ - o(0xf0 + fr); + gen_multibyte(0xf7d231); /* xor %edx, %edx, div fr, %eax */ + gen_multibyte(0xf0 + fr); // XXX maybe gen_byte/combine? } else { - o(0xf799); /* cltd, idiv fr, %eax */ - o(0xf8 + fr); + gen_multibyte(0xf799); /* cltd, idiv fr, %eax */ + gen_multibyte(0xf8 + fr); // XXX maybe gen_byte/combine? } if (op == '%' || op == TOK_UMOD) r = TREG_EDX; @@ -776,21 +768,21 @@ else if (op == TOK_EQ || op == TOK_NE) swapped = 0; if (swapped) - o(0xc9d9); /* fxch %st(1) */ - o(0xe9da); /* fucompp */ - o(0xe0df); /* fnstsw %ax */ + gen_multibyte(0xc9d9); /* fxch %st(1) */ + gen_multibyte(0xe9da); /* fucompp */ + gen_multibyte(0xe0df); /* fnstsw %ax */ // XXX maybe combine? if (op == TOK_EQ) { - o(0x45e480); /* and $0x45, %ah */ - o(0x40fC80); /* cmp $0x40, %ah */ + gen_multibyte(0x45e480); /* and $0x45, %ah */ + gen_multibyte(0x40fC80); /* cmp $0x40, %ah */ } else if (op == TOK_NE) { - o(0x45e480); /* and $0x45, %ah */ - o(0x40f480); /* xor $0x40, %ah */ - op = TOK_NE; + gen_multibyte(0x45e480); /* and $0x45, %ah */ + gen_multibyte(0x40f480); /* xor $0x40, %ah */ + op = TOK_NE; // XXX redundant? } else if (op == TOK_GE || op == TOK_LE) { - o(0x05c4f6); /* test $0x05, %ah */ + gen_multibyte(0x05c4f6); /* test $0x05, %ah */ op = TOK_EQ; } else { - o(0x45c4f6); /* test $0x45, %ah */ + gen_multibyte(0x45c4f6); /* test $0x45, %ah */ op = TOK_EQ; } vtop--; @@ -825,8 +817,8 @@ ft = vtop->type.t; fc = vtop->c.ul; if ((ft & VT_BTYPE) == VT_LDOUBLE) { - o(0xde); /* fxxxp %st, %st(1) */ - o(0xc1 + (a << 3)); + gen_byte(0xde); /* fxxxp %st, %st(1) */ + gen_multibyte(0xc1 + (a << 3)); // XXX maybe gen_byte/combine? } else { /* if saved lvalue, then we must reload it */ r = vtop->r; @@ -840,10 +832,8 @@ fc = 0; } - if ((ft & VT_BTYPE) == VT_DOUBLE) - o(0xdc); - else - o(0xd8); + if ((ft & VT_BTYPE) == VT_DOUBLE) gen_byte(0xdc); + else gen_byte(0xd8); gen_modrm(a, r, vtop->sym, fc); } vtop--; @@ -859,23 +849,23 @@ if ((vtop->type.t & VT_BTYPE) == VT_LLONG) { /* signed long long to float/double/long double (unsigned case is handled generically) */ - o(0x50 + vtop->r2); /* push r2 */ - o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ - o(0x242cdf); /* fildll (%esp) */ - o(0x08c483); /* add $8, %esp */ + gen_multibyte(0x50 + vtop->r2); /* push r2 */ // XXX maybe gen_byte? + gen_multibyte(0x50 + (vtop->r & VT_VALMASK)); /* push r */ /// XXX maybe gen_byte? + gen_multibyte(0x242cdf); /* fildll (%esp) */ + gen_multibyte(0x08c483); /* add $8, %esp */ } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED)) { /* unsigned int to float/double/long double */ - o(0x6a); /* push $0 */ + gen_byte(0x6a); /* push $0 */ gen_byte(0x00); - o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ - o(0x242cdf); /* fildll (%esp) */ - o(0x08c483); /* add $8, %esp */ + gen_multibyte(0x50 + (vtop->r & VT_VALMASK)); /* push r */ // XXX maybe gen_byte? + gen_multibyte(0x242cdf); /* fildll (%esp) */ + gen_multibyte(0x08c483); /* add $8, %esp */ } else { /* int to float/double/long double */ - o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ - o(0x2404db); /* fildl (%esp) */ - o(0x04c483); /* add $4, %esp */ + gen_multibyte(0x50 + (vtop->r & VT_VALMASK)); /* push r */ // XXX maybe gen_byte? + gen_multibyte(0x2404db); /* fildl (%esp) */ + gen_multibyte(0x04c483); /* add $4, %esp */ } vtop->r = TREG_ST0; } @@ -891,12 +881,10 @@ ushort_type.t = VT_SHORT | VT_UNSIGNED; gv(RC_FLOAT); - if (t != VT_INT) - size = 8; - else - size = 4; + if (t != VT_INT) size = 8; + else size = 4; - o(0x2dd9); /* ldcw xxx */ + gen_multibyte(0x2dd9); /* ldcw xxx */ sym = external_global_sym(TOK___tcc_int_fpu_control, &ushort_type, VT_LVAL); greloc(cur_text_section, sym, @@ -904,12 +892,10 @@ gen_le32(0); oad(0xec81, size); /* sub $xxx, %esp */ - if (size == 4) - o(0x1cdb); /* fistpl */ - else - o(0x3cdf); /* fistpll */ - o(0x24); - o(0x2dd9); /* ldcw xxx */ + if (size == 4) gen_multibyte(0x1cdb); /* fistpl */ + else gen_multibyte(0x3cdf); /* fistpll */ + gen_byte(0x24); // XXX maybe combine? + gen_multibyte(0x2dd9); /* ldcw xxx */ sym = external_global_sym(TOK___tcc_fpu_control, &ushort_type, VT_LVAL); greloc(cur_text_section, sym, @@ -917,16 +903,14 @@ gen_le32(0); r = get_reg(RC_INT); - o(0x58 + r); /* pop r */ + gen_multibyte(0x58 + r); /* pop r */ // XXX maybe gen_byte? if (size == 8) { if (t == VT_LLONG) { vtop->r = r; /* mark reg as used */ r2 = get_reg(RC_INT); - o(0x58 + r2); /* pop r2 */ + gen_multibyte(0x58 + r2); /* pop r2 */ // XXX maybe gen_byte? vtop->r2 = r2; - } else { - o(0x04c483); /* add $4, %esp */ - } + } else gen_multibyte(0x04c483); /* add $4, %esp */ } vtop->r = r; }
--- a/tcc.c Tue Mar 18 18:50:19 2008 -0500 +++ b/tcc.c Tue Mar 18 18:52:00 2008 -0500 @@ -3694,7 +3694,7 @@ #ifdef TINYCC_TARGET_I386 /* x86 specific: need to pop fp register ST0 if saved */ if (r == TREG_ST0) { - o(0xd9dd); /* fstp %st(1) */ + gen_multibyte(0xd9dd); /* fstp %st(1) */ } #endif /* special long long case */ @@ -4135,7 +4135,7 @@ #ifdef TINYCC_TARGET_I386 /* for x86, we need to pop the FP stack */ if (v == TREG_ST0) { - o(0xd8dd); /* fstp %st(1) */ + gen_multibyte(0xd8dd); /* fstp %st(1) */ } else #endif if (v == VT_JMP || v == VT_JMPI) { @@ -4388,7 +4388,7 @@ b = psym(0x850f, 0); #elif defined(TINYCC_TARGET_ARM) b = ind; - o(0x1A000000 | encbranch(ind, 0, 1)); + gen_multibyte(0x1A000000 | encbranch(ind, 0, 1)); #elif defined(TINYCC_TARGET_C67) error("not implemented"); #else