summaryrefslogtreecommitdiff
path: root/arm-gen.c
diff options
context:
space:
mode:
Diffstat (limited to 'arm-gen.c')
-rw-r--r--arm-gen.c1133
1 files changed, 570 insertions, 563 deletions
diff --git a/arm-gen.c b/arm-gen.c
index 4a1b775..2b2e626 100644
--- a/arm-gen.c
+++ b/arm-gen.c
@@ -179,17 +179,24 @@ ST_DATA const int reg_classes[NB_REGS] = {
static int func_sub_sp_offset, last_itod_magic;
static int leaffunc;
+#if defined(CONFIG_TCC_BCHECK)
+static addr_t func_bound_offset;
+static unsigned long func_bound_ind;
+ST_DATA int func_bound_add_epilog;
+#endif
+
#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
-ST_FUNC void arm_init(TCCState *S)
+static CType float_type, double_type, func_float_type, func_double_type;
+ST_FUNC void arm_init(struct TCCState *s)
{
- S->armgen_float_type.t = VT_FLOAT;
- S->armgen_double_type.t = VT_DOUBLE;
- S->armgen_func_float_type.t = VT_FUNC;
- S->armgen_func_float_type.ref = sym_push(S, SYM_FIELD, &S->armgen_float_type, FUNC_CDECL, FUNC_OLD);
- S->armgen_func_double_type.t = VT_FUNC;
- S->armgen_func_double_type.ref = sym_push(S, SYM_FIELD, &S->armgen_double_type, FUNC_CDECL, FUNC_OLD);
-
- float_abi = S->float_abi;
+ float_type.t = VT_FLOAT;
+ double_type.t = VT_DOUBLE;
+ func_float_type.t = VT_FUNC;
+ func_float_type.ref = sym_push(SYM_FIELD, &float_type, FUNC_CDECL, FUNC_OLD);
+ func_double_type.t = VT_FUNC;
+ func_double_type.ref = sym_push(SYM_FIELD, &double_type, FUNC_CDECL, FUNC_OLD);
+
+ float_abi = s->float_abi;
#ifndef TCC_ARM_HARDFLOAT
// XXX: Works on OpenBSD
// # warning "soft float ABI currently not supported: default to softfp"
@@ -216,15 +223,15 @@ ST_FUNC void arm_init(struct TCCState *s)
#define CHECK_R(r) ((r) >= TREG_R0 && (r) <= TREG_LR)
-static int two2mask(TCCState* S, int a,int b) {
+static int two2mask(int a,int b) {
if (!CHECK_R(a) || !CHECK_R(b))
- tcc_error(S, "compiler error! registers %i,%i is not valid",a,b);
+ tcc_error("compiler error! registers %i,%i is not valid",a,b);
return (reg_classes[a]|reg_classes[b])&~(RC_INT|RC_FLOAT);
}
-static int regmask(TCCState* S, int r) {
+static int regmask(int r) {
if (!CHECK_R(r))
- tcc_error(S, "compiler error! register %i is not valid",r);
+ tcc_error("compiler error! register %i is not valid",r);
return reg_classes[r]&~(RC_INT|RC_FLOAT);
}
@@ -240,25 +247,25 @@ const char *default_elfinterp(struct TCCState *s)
}
#endif
-void o(TCCState* S, uint32_t i)
+void o(uint32_t i)
{
/* this is a good place to start adding big-endian support*/
int ind1;
- if (S->tccgen_nocode_wanted)
+ if (nocode_wanted)
return;
- ind1 = S->tccgen_ind + 4;
+ ind1 = ind + 4;
if (!cur_text_section)
- tcc_error(S, "compiler error! This happens f.ex. if the compiler\n"
+ tcc_error("compiler error! This happens f.ex. if the compiler\n"
"can't evaluate constant expressions outside of a function.");
if (ind1 > cur_text_section->data_allocated)
- section_realloc(S, cur_text_section, ind1);
- cur_text_section->data[S->tccgen_ind++] = i&255;
+ section_realloc(cur_text_section, ind1);
+ cur_text_section->data[ind++] = i&255;
i>>=8;
- cur_text_section->data[S->tccgen_ind++] = i&255;
+ cur_text_section->data[ind++] = i&255;
i>>=8;
- cur_text_section->data[S->tccgen_ind++] = i&255;
+ cur_text_section->data[ind++] = i&255;
i>>=8;
- cur_text_section->data[S->tccgen_ind++] = i;
+ cur_text_section->data[ind++] = i;
}
static uint32_t stuff_const(uint32_t op, uint32_t c)
@@ -315,11 +322,11 @@ static uint32_t stuff_const(uint32_t op, uint32_t c)
//only add,sub
-void stuff_const_harder(TCCState* S, uint32_t op, uint32_t v) {
+void stuff_const_harder(uint32_t op, uint32_t v) {
uint32_t x;
x=stuff_const(op,v);
if(x)
- o(S, x);
+ o(x);
else {
uint32_t a[16], nv, no, o2, n2;
int i,j,k;
@@ -330,8 +337,8 @@ void stuff_const_harder(TCCState* S, uint32_t op, uint32_t v) {
for(i=0;i<12;i++)
for(j=i<4?i+12:15;j>=i+4;j--)
if((v&(a[i]|a[j]))==v) {
- o(S, stuff_const(op,v&a[i]));
- o(S, stuff_const(o2,v&a[j]));
+ o(stuff_const(op,v&a[i]));
+ o(stuff_const(o2,v&a[j]));
return;
}
no=op^0xC00000;
@@ -340,17 +347,17 @@ void stuff_const_harder(TCCState* S, uint32_t op, uint32_t v) {
for(i=0;i<12;i++)
for(j=i<4?i+12:15;j>=i+4;j--)
if((nv&(a[i]|a[j]))==nv) {
- o(S, stuff_const(no,nv&a[i]));
- o(S, stuff_const(n2,nv&a[j]));
+ o(stuff_const(no,nv&a[i]));
+ o(stuff_const(n2,nv&a[j]));
return;
}
for(i=0;i<8;i++)
for(j=i+4;j<12;j++)
for(k=i<4?i+12:15;k>=j+4;k--)
if((v&(a[i]|a[j]|a[k]))==v) {
- o(S, stuff_const(op,v&a[i]));
- o(S, stuff_const(o2,v&a[j]));
- o(S, stuff_const(o2,v&a[k]));
+ o(stuff_const(op,v&a[i]));
+ o(stuff_const(o2,v&a[j]));
+ o(stuff_const(o2,v&a[k]));
return;
}
no=op^0xC00000;
@@ -359,31 +366,31 @@ void stuff_const_harder(TCCState* S, uint32_t op, uint32_t v) {
for(j=i+4;j<12;j++)
for(k=i<4?i+12:15;k>=j+4;k--)
if((nv&(a[i]|a[j]|a[k]))==nv) {
- o(S, stuff_const(no,nv&a[i]));
- o(S, stuff_const(n2,nv&a[j]));
- o(S, stuff_const(n2,nv&a[k]));
+ o(stuff_const(no,nv&a[i]));
+ o(stuff_const(n2,nv&a[j]));
+ o(stuff_const(n2,nv&a[k]));
return;
}
- o(S, stuff_const(op,v&a[0]));
- o(S, stuff_const(o2,v&a[4]));
- o(S, stuff_const(o2,v&a[8]));
- o(S, stuff_const(o2,v&a[12]));
+ 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]));
}
}
-uint32_t encbranch(TCCState* S, int pos, int addr, int fail)
+uint32_t encbranch(int pos, int addr, int fail)
{
addr-=pos+8;
addr/=4;
if(addr>=0x1000000 || addr<-0x1000000) {
if(fail)
- tcc_error(S, "FIXME: function bigger than 32MB");
+ tcc_error("FIXME: function bigger than 32MB");
return 0;
}
return 0x0A000000|(addr&0xffffff);
}
-int decbranch(TCCState* S, int pos)
+int decbranch(int pos)
{
int x;
x=*(uint32_t *)(cur_text_section->data + pos);
@@ -394,50 +401,50 @@ int decbranch(TCCState* S, int pos)
}
/* output a symbol and patch all calls to it */
-void gsym_addr(TCCState* S, int t, int a)
+void gsym_addr(int t, int a)
{
uint32_t *x;
int lt;
while(t) {
x=(uint32_t *)(cur_text_section->data + t);
- t=decbranch(S, lt=t);
+ t=decbranch(lt=t);
if(a==lt+4)
*x=0xE1A00000; // nop
else {
*x &= 0xff000000;
- *x |= encbranch(S, lt,a,1);
+ *x |= encbranch(lt,a,1);
}
}
}
#ifdef TCC_ARM_VFP
-static uint32_t vfpr(TCCState* S, int r)
+static uint32_t vfpr(int r)
{
if(r<TREG_F0 || r>TREG_F7)
- tcc_error(S, "compiler error! register %i is no vfp register",r);
+ tcc_error("compiler error! register %i is no vfp register",r);
return r - TREG_F0;
}
#else
-static uint32_t fpr(TCCState* S, int r)
+static uint32_t fpr(int r)
{
if(r<TREG_F0 || r>TREG_F3)
- tcc_error(S, "compiler error! register %i is no fpa register",r);
+ tcc_error("compiler error! register %i is no fpa register",r);
return r - TREG_F0;
}
#endif
-static uint32_t intr(TCCState* S, int r)
+static uint32_t intr(int r)
{
if(r == TREG_R12)
return 12;
if(r >= TREG_R0 && r <= TREG_R3)
return r - TREG_R0;
if (!(r >= TREG_SP && r <= TREG_LR))
- tcc_error(S, "compiler error! register %i is no int register",r);
+ tcc_error("compiler error! register %i is no int register",r);
return r + (13 - TREG_SP);
}
-static void calcaddr(TCCState* S, uint32_t *base, int *off, int *sgn, int maxoff, unsigned shift)
+static void calcaddr(uint32_t *base, int *off, int *sgn, int maxoff, unsigned shift)
{
if(*off>maxoff || *off&((1<<shift)-1)) {
uint32_t x, y;
@@ -448,23 +455,23 @@ static void calcaddr(TCCState* S, uint32_t *base, int *off, int *sgn, int maxoff
*base=14; // lr
y=stuff_const(x,*off&~maxoff);
if(y) {
- o(S, y);
+ o(y);
*off&=maxoff;
return;
}
y=stuff_const(x,(*off+maxoff)&~maxoff);
if(y) {
- o(S, y);
+ o(y);
*sgn=!*sgn;
*off=((*off+maxoff)&~maxoff)-*off;
return;
}
- stuff_const_harder(S, x,*off&~maxoff);
+ stuff_const_harder(x,*off&~maxoff);
*off&=maxoff;
}
}
-static uint32_t mapcc(TCCState* S, int cc)
+static uint32_t mapcc(int cc)
{
switch(cc)
{
@@ -493,11 +500,11 @@ static uint32_t mapcc(TCCState* S, int cc)
case TOK_GT:
return 0xC0000000; /* GT */
}
- tcc_error(S, "unexpected condition code");
+ tcc_error("unexpected condition code");
return 0xE0000000; /* AL */
}
-static int negcc(TCCState* S, int cc)
+static int negcc(int cc)
{
switch(cc)
{
@@ -526,44 +533,44 @@ static int negcc(TCCState* S, int cc)
case TOK_GT:
return TOK_LE;
}
- tcc_error(S, "unexpected condition code");
+ tcc_error("unexpected condition code");
return TOK_NE;
}
/* Load value into register r.
Use relative/got addressing to avoid setting DT_TEXTREL */
-static void load_value(TCCState* S, SValue *sv, int r)
+static void load_value(SValue *sv, int r)
{
- o(S, 0xE59F0000|(intr(S, r)<<12)); /* ldr r, [pc] */
- o(S, 0xEA000000); /* b $+4 */
+ o(0xE59F0000|(intr(r)<<12)); /* ldr r, [pc] */
+ o(0xEA000000); /* b $+4 */
#ifndef CONFIG_TCC_PIE
if(sv->r & VT_SYM)
- greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_ARM_ABS32);
- o(S, sv->c.i);
+ greloc(cur_text_section, sv->sym, ind, R_ARM_ABS32);
+ o(sv->c.i);
#else
if(sv->r & VT_SYM) {
if (sv->sym->type.t & VT_STATIC) {
greloc(cur_text_section, sv->sym, ind, R_ARM_REL32);
- o(S, sv->c.i - 12);
- o(S, 0xe080000f | (intr(S, r)<<12) | (intr(S, r)<<16)); // add rx,rx,pc
+ o(sv->c.i - 12);
+ o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc
}
else {
greloc(cur_text_section, sv->sym, ind, R_ARM_GOT_PREL);
- o(S, -12);
- o(S, 0xe080000f | (intr(S, r)<<12) | (intr(S, r)<<16)); // add rx,rx,pc
- o(S, 0xe5900000 | (intr(S, r)<<12) | (intr(S, r)<<16)); // ldr rx,[rx]
+ o(-12);
+ o(0xe080000f | (intr(r)<<12) | (intr(r)<<16)); // add rx,rx,pc
+ o(0xe5900000 | (intr(r)<<12) | (intr(r)<<16)); // ldr rx,[rx]
if (sv->c.i)
- stuff_const_harder(S, 0xe2800000 | (intr(S, r)<<12) | (intr(S, r)<<16),
+ stuff_const_harder(0xe2800000 | (intr(r)<<12) | (intr(r)<<16),
sv->c.i);
}
}
else
- o(S, sv->c.i);
+ o(sv->c.i);
#endif
}
/* load 'r' from value 'sv' */
-void load(TCCState* S, int r, SValue *sv)
+void load(int r, SValue *sv)
{
int v, ft, fc, fr, sign;
uint32_t op;
@@ -587,7 +594,7 @@ void load(TCCState* S, int r, SValue *sv)
v1.type.t = VT_PTR;
v1.r = VT_LOCAL | VT_LVAL;
v1.c.i = sv->c.i;
- load(S, TREG_LR, &v1);
+ load(TREG_LR, &v1);
base = 14; /* lr */
fc=sign=0;
v=VT_LOCAL;
@@ -596,25 +603,25 @@ void load(TCCState* S, int r, SValue *sv)
v1.r = fr&~VT_LVAL;
v1.c.i = sv->c.i;
v1.sym=sv->sym;
- load(S, TREG_LR, &v1);
+ load(TREG_LR, &v1);
base = 14; /* lr */
fc=sign=0;
v=VT_LOCAL;
} else if(v < VT_CONST) {
- base=intr(S, v);
+ base=intr(v);
fc=sign=0;
v=VT_LOCAL;
}
if(v == VT_LOCAL) {
if(is_float(ft)) {
- calcaddr(S, &base,&fc,&sign,1020,2);
+ calcaddr(&base,&fc,&sign,1020,2);
#ifdef TCC_ARM_VFP
op=0xED100A00; /* flds */
if(!sign)
op|=0x800000;
if ((ft & VT_BTYPE) != VT_FLOAT)
op|=0x100; /* flds -> fldd */
- o(S, op|(vfpr(S, r)<<12)|(fc>>2)|(base<<16));
+ o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
#else
op=0xED100100;
if(!sign)
@@ -628,11 +635,11 @@ void load(TCCState* S, int r, SValue *sv)
else if ((ft & VT_BTYPE) == VT_LDOUBLE)
op|=0x400000;
#endif
- o(S, op|(fpr(S, r)<<12)|(fc>>2)|(base<<16));
+ o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));
#endif
} else if((ft & (VT_BTYPE|VT_UNSIGNED)) == VT_BYTE
|| (ft & VT_BTYPE) == VT_SHORT) {
- calcaddr(S, &base,&fc,&sign,255,0);
+ calcaddr(&base,&fc,&sign,255,0);
op=0xE1500090;
if ((ft & VT_BTYPE) == VT_SHORT)
op|=0x20;
@@ -640,63 +647,63 @@ void load(TCCState* S, int r, SValue *sv)
op|=0x40;
if(!sign)
op|=0x800000;
- o(S, op|(intr(S, r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
+ o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
} else {
- calcaddr(S, &base,&fc,&sign,4095,0);
+ calcaddr(&base,&fc,&sign,4095,0);
op=0xE5100000;
if(!sign)
op|=0x800000;
if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
op|=0x400000;
- o(S, op|(intr(S, r)<<12)|fc|(base<<16));
+ o(op|(intr(r)<<12)|fc|(base<<16));
}
return;
}
} else {
if (v == VT_CONST) {
- op=stuff_const(0xE3A00000|(intr(S, r)<<12),sv->c.i);
+ op=stuff_const(0xE3A00000|(intr(r)<<12),sv->c.i);
if (fr & VT_SYM || !op)
- load_value(S, sv, r);
+ load_value(sv, r);
else
- o(S, op);
+ o(op);
return;
} else if (v == VT_LOCAL) {
- op=stuff_const(0xE28B0000|(intr(S, r)<<12),sv->c.i);
+ op=stuff_const(0xE28B0000|(intr(r)<<12),sv->c.i);
if (fr & VT_SYM || !op) {
- load_value(S, sv, r);
- o(S, 0xE08B0000|(intr(S, r)<<12)|intr(S, r));
+ load_value(sv, r);
+ o(0xE08B0000|(intr(r)<<12)|intr(r));
} else
- o(S, op);
+ o(op);
return;
} else if(v == VT_CMP) {
- o(S, mapcc(S, sv->c.i)|0x3A00001|(intr(S, r)<<12));
- o(S, mapcc(S, negcc(S, sv->c.i))|0x3A00000|(intr(S, r)<<12));
+ o(mapcc(sv->c.i)|0x3A00001|(intr(r)<<12));
+ o(mapcc(negcc(sv->c.i))|0x3A00000|(intr(r)<<12));
return;
} else if (v == VT_JMP || v == VT_JMPI) {
int t;
t = v & 1;
- o(S, 0xE3A00000|(intr(S, r)<<12)|t);
- o(S, 0xEA000000);
- gsym(S, sv->c.i);
- o(S, 0xE3A00000|(intr(S, r)<<12)|(t^1));
+ o(0xE3A00000|(intr(r)<<12)|t);
+ o(0xEA000000);
+ gsym(sv->c.i);
+ o(0xE3A00000|(intr(r)<<12)|(t^1));
return;
} else if (v < VT_CONST) {
if(is_float(ft))
#ifdef TCC_ARM_VFP
- o(S, 0xEEB00A40|(vfpr(S, r)<<12)|vfpr(S, v)|T2CPR(ft)); /* fcpyX */
+ o(0xEEB00A40|(vfpr(r)<<12)|vfpr(v)|T2CPR(ft)); /* fcpyX */
#else
- o(S, 0xEE008180|(fpr(S, r)<<12)|fpr(S, v));
+ o(0xEE008180|(fpr(r)<<12)|fpr(v));
#endif
else
- o(S, 0xE1A00000|(intr(S, r)<<12)|intr(S, v));
+ o(0xE1A00000|(intr(r)<<12)|intr(v));
return;
}
}
- tcc_error(S, "load unimplemented!");
+ tcc_error("load unimplemented!");
}
/* store register 'r' in lvalue 'v' */
-void store(TCCState* S, int r, SValue *sv)
+void store(int r, SValue *sv)
{
SValue v1;
int v, ft, fc, fr, sign;
@@ -717,7 +724,7 @@ void store(TCCState* S, int r, SValue *sv)
if (fr & VT_LVAL || fr == VT_LOCAL) {
uint32_t base = 0xb; /* fp */
if(v < VT_CONST) {
- base=intr(S, v);
+ base=intr(v);
v=VT_LOCAL;
fc=sign=0;
} else if(v == VT_CONST) {
@@ -725,21 +732,21 @@ void store(TCCState* S, int r, SValue *sv)
v1.r = fr&~VT_LVAL;
v1.c.i = sv->c.i;
v1.sym=sv->sym;
- load(S, TREG_LR, &v1);
+ load(TREG_LR, &v1);
base = 14; /* lr */
fc=sign=0;
v=VT_LOCAL;
}
if(v == VT_LOCAL) {
if(is_float(ft)) {
- calcaddr(S, &base,&fc,&sign,1020,2);
+ calcaddr(&base,&fc,&sign,1020,2);
#ifdef TCC_ARM_VFP
op=0xED000A00; /* fsts */
if(!sign)
op|=0x800000;
if ((ft & VT_BTYPE) != VT_FLOAT)
op|=0x100; /* fsts -> fstd */
- o(S, op|(vfpr(S, r)<<12)|(fc>>2)|(base<<16));
+ o(op|(vfpr(r)<<12)|(fc>>2)|(base<<16));
#else
op=0xED000100;
if(!sign)
@@ -753,138 +760,138 @@ void store(TCCState* S, int r, SValue *sv)
if ((ft & VT_BTYPE) == VT_LDOUBLE)
op|=0x400000;
#endif
- o(S, op|(fpr(S, r)<<12)|(fc>>2)|(base<<16));
+ o(op|(fpr(r)<<12)|(fc>>2)|(base<<16));
#endif
return;
} else if((ft & VT_BTYPE) == VT_SHORT) {
- calcaddr(S, &base,&fc,&sign,255,0);
+ calcaddr(&base,&fc,&sign,255,0);
op=0xE14000B0;
if(!sign)
op|=0x800000;
- o(S, op|(intr(S, r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
+ o(op|(intr(r)<<12)|(base<<16)|((fc&0xf0)<<4)|(fc&0xf));
} else {
- calcaddr(S, &base,&fc,&sign,4095,0);
+ calcaddr(&base,&fc,&sign,4095,0);
op=0xE5000000;
if(!sign)
op|=0x800000;
if ((ft & VT_BTYPE) == VT_BYTE || (ft & VT_BTYPE) == VT_BOOL)
op|=0x400000;
- o(S, op|(intr(S, r)<<12)|fc|(base<<16));
+ o(op|(intr(r)<<12)|fc|(base<<16));
}
return;
}
}
- tcc_error(S, "store unimplemented");
+ tcc_error("store unimplemented");
}
-static void gadd_sp(TCCState* S, int val)
+static void gadd_sp(int val)
{
- stuff_const_harder(S, 0xE28DD000,val);
+ stuff_const_harder(0xE28DD000,val);
}
/* 'is_jmp' is '1' if it is a jump */
-static void gcall_or_jmp(TCCState* S, int is_jmp)
+static void gcall_or_jmp(int is_jmp)
{
int r;
uint32_t x;
- if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
+ if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
/* constant case */
- if(S->tccgen_vtop->r & VT_SYM){
- x=encbranch(S, S->tccgen_ind, S->tccgen_ind+S->tccgen_vtop->c.i,0);
+ if(vtop->r & VT_SYM){
+ x=encbranch(ind,ind+vtop->c.i,0);
if(x) {
/* relocation case */
- greloc(S, cur_text_section, S->tccgen_vtop->sym, S->tccgen_ind, R_ARM_PC24);
- o(S, x|(is_jmp?0xE0000000:0xE1000000));
+ greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24);
+ o(x|(is_jmp?0xE0000000:0xE1000000));
} else {
r = TREG_LR;
- load_value(S, S->tccgen_vtop, r);
+ load_value(vtop, r);
if(is_jmp)
- o(S, 0xE1A0F000 | intr(S, r)); // mov pc, r
+ o(0xE1A0F000 | intr(r)); // mov pc, r
else
- o(S, 0xe12fff30 | intr(S, r)); // blx r
+ o(0xe12fff30 | intr(r)); // blx r
}
}else{
if(!is_jmp)
- o(S, 0xE28FE004); // add lr,pc,#4
- o(S, 0xE51FF004); // ldr pc,[pc,#-4]
- o(S, S->tccgen_vtop->c.i);
+ o(0xE28FE004); // add lr,pc,#4
+ o(0xE51FF004); // ldr pc,[pc,#-4]
+ o(vtop->c.i);
}
} else {
/* otherwise, indirect call */
#ifdef CONFIG_TCC_BCHECK
- S->tccgen_vtop->r &= ~VT_MUSTBOUND;
+ vtop->r &= ~VT_MUSTBOUND;
#endif
- r = gv(S, RC_INT);
+ r = gv(RC_INT);
if(!is_jmp)
- o(S, 0xE1A0E00F); // mov lr,pc
- o(S, 0xE1A0F000|intr(S, r)); // mov pc,r
+ o(0xE1A0E00F); // mov lr,pc
+ o(0xE1A0F000|intr(r)); // mov pc,r
}
}
#if defined(CONFIG_TCC_BCHECK)
-static void gen_bounds_call(TCCState* S, int v)
+static void gen_bounds_call(int v)
{
- Sym *sym = external_helper_sym(S, v);
+ Sym *sym = external_helper_sym(v);
- greloc(S, cur_text_section, sym, S->tccgen_ind, R_ARM_PC24);
- o(S, 0xebfffffe);
+ greloc(cur_text_section, sym, ind, R_ARM_PC24);
+ o(0xebfffffe);
}
-static void gen_bounds_prolog(TCCState* S)
+static void gen_bounds_prolog(void)
{
/* leave some room for bound checking code */
- S->func_bound_offset = lbounds_section->data_offset;
- S->func_bound_ind = S->tccgen_ind;
- S->func_bound_add_epilog = 0;
- o(S, 0xe1a00000); /* ld r0,lbounds_section->data_offset */
- o(S, 0xe1a00000);
- o(S, 0xe1a00000);
- o(S, 0xe1a00000);
- o(S, 0xe1a00000); /* call __bound_local_new */
+ func_bound_offset = lbounds_section->data_offset;
+ func_bound_ind = ind;
+ func_bound_add_epilog = 0;
+ o(0xe1a00000); /* ld r0,lbounds_section->data_offset */
+ o(0xe1a00000);
+ o(0xe1a00000);
+ o(0xe1a00000);
+ o(0xe1a00000); /* call __bound_local_new */
}
-static void gen_bounds_epilog(TCCState* S)
+static void gen_bounds_epilog(void)
{
addr_t saved_ind;
addr_t *bounds_ptr;
Sym *sym_data;
- int offset_modified = S->func_bound_offset != lbounds_section->data_offset;
+ int offset_modified = func_bound_offset != lbounds_section->data_offset;
- if (!offset_modified && !S->func_bound_add_epilog)
+ if (!offset_modified && !func_bound_add_epilog)
return;
/* add end of table info */
- bounds_ptr = section_ptr_add(S, lbounds_section, sizeof(addr_t));
+ bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
*bounds_ptr = 0;
- sym_data = get_sym_ref(S, &S->tccgen_char_pointer_type, lbounds_section,
- S->func_bound_offset, lbounds_section->data_offset);
+ sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
+ func_bound_offset, lbounds_section->data_offset);
/* generate bound local allocation */
if (offset_modified) {
- saved_ind = S->tccgen_ind;
- S->tccgen_ind = S->func_bound_ind;
- o(S, 0xe59f0000); /* ldr r0, [pc] */
- o(S, 0xea000000); /* b $+4 */
- greloc(S, cur_text_section, sym_data, S->tccgen_ind, R_ARM_REL32);
- o(S, -12); /* lbounds_section->data_offset */
- o(S, 0xe080000f); /* add r0,r0,pc */
- gen_bounds_call(S, TOK___bound_local_new);
- S->tccgen_ind = saved_ind;
+ saved_ind = ind;
+ ind = func_bound_ind;
+ o(0xe59f0000); /* ldr r0, [pc] */
+ o(0xea000000); /* b $+4 */
+ greloc(cur_text_section, sym_data, ind, R_ARM_REL32);
+ o(-12); /* lbounds_section->data_offset */
+ o(0xe080000f); /* add r0,r0,pc */
+ gen_bounds_call(TOK___bound_local_new);
+ ind = saved_ind;
}
/* generate bound check local freeing */
- o(S, 0xe92d0003); /* push {r0,r1} */
- o(S, 0xed2d0b02); /* vpush {d0} */
- o(S, 0xe59f0000); /* ldr r0, [pc] */
- o(S, 0xea000000); /* b $+4 */
- greloc(S, cur_text_section, sym_data, S->tccgen_ind, R_ARM_REL32);
- o(S, -12); /* lbounds_section->data_offset */
- o(S, 0xe080000f); /* add r0,r0,pc */
- gen_bounds_call(S, TOK___bound_local_delete);
- o(S, 0xecbd0b02); /* vpop {d0} */
- o(S, 0xe8bd0003); /* pop {r0,r1} */
+ o(0xe92d0003); /* push {r0,r1} */
+ o(0xed2d0b02); /* vpush {d0} */
+ o(0xe59f0000); /* ldr r0, [pc] */
+ o(0xea000000); /* b $+4 */
+ greloc(cur_text_section, sym_data, ind, R_ARM_REL32);
+ o(-12); /* lbounds_section->data_offset */
+ o(0xe080000f); /* add r0,r0,pc */
+ gen_bounds_call(TOK___bound_local_delete);
+ o(0xecbd0b02); /* vpop {d0} */
+ o(0xe8bd0003); /* pop {r0,r1} */
}
#endif
@@ -1070,7 +1077,7 @@ static void add_param_plan(struct plan* plan, int cls, int start, int end, SValu
Note: this function allocated an array in plan->pplans with tcc_malloc. It
is the responsibility of the caller to free this array once used (ie not
before copy_params). */
-static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *plan, int *todo)
+static int assign_regs(int nb_args, int float_abi, struct plan *plan, int *todo)
{
int i, size, align;
int ncrn /* next core register number */, nsaa /* next stacked argument address*/;
@@ -1081,12 +1088,12 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla
for(i = nb_args; i-- ;) {
int j, start_vfpreg = 0;
- CType type = S->tccgen_vtop[-i].type;
+ CType type = vtop[-i].type;
type.t &= ~VT_ARRAY;
size = type_size(&type, &align);
size = (size + 3) & ~3;
align = (align + 3) & ~3;
- switch(S->tccgen_vtop[-i].type.t & VT_BTYPE) {
+ switch(vtop[-i].type.t & VT_BTYPE) {
case VT_STRUCT:
case VT_FLOAT:
case VT_DOUBLE:
@@ -1094,15 +1101,15 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla
if (float_abi == ARM_HARD_FLOAT) {
int is_hfa = 0; /* Homogeneous float aggregate */
- if (is_float(S->tccgen_vtop[-i].type.t)
- || (is_hfa = is_hgen_float_aggr(&S->tccgen_vtop[-i].type))) {
+ if (is_float(vtop[-i].type.t)
+ || (is_hfa = is_hgen_float_aggr(&vtop[-i].type))) {
int end_vfpreg;
start_vfpreg = assign_vfpreg(&avregs, align, size);
end_vfpreg = start_vfpreg + ((size - 1) >> 2);
if (start_vfpreg >= 0) {
add_param_plan(plan, is_hfa ? VFP_STRUCT_CLASS : VFP_CLASS,
- start_vfpreg, end_vfpreg, &S->tccgen_vtop[-i]);
+ start_vfpreg, end_vfpreg, &vtop[-i]);
continue;
} else
break;
@@ -1115,7 +1122,7 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla
* CORE_STRUCT_CLASS or the first of STACK_CLASS. */
for (j = ncrn; j < 4 && j < ncrn + size / 4; j++)
*todo|=(1<<j);
- add_param_plan(plan, CORE_STRUCT_CLASS, ncrn, j, &S->tccgen_vtop[-i]);
+ add_param_plan(plan, CORE_STRUCT_CLASS, ncrn, j, &vtop[-i]);
ncrn += size/4;
if (ncrn > 4)
nsaa = (ncrn - 4) * 4;
@@ -1126,20 +1133,20 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla
continue;
default:
if (ncrn < 4) {
- int is_long = (S->tccgen_vtop[-i].type.t & VT_BTYPE) == VT_LLONG;
+ int is_long = (vtop[-i].type.t & VT_BTYPE) == VT_LLONG;
if (is_long) {
ncrn = (ncrn + 1) & -2;
if (ncrn == 4)
break;
}
- add_param_plan(plan, CORE_CLASS, ncrn, ncrn + is_long, &S->tccgen_vtop[-i]);
+ add_param_plan(plan, CORE_CLASS, ncrn, ncrn + is_long, &vtop[-i]);
ncrn += 1 + is_long;
continue;
}
}
nsaa = (nsaa + (align - 1)) & ~(align - 1);
- add_param_plan(plan, STACK_CLASS, nsaa, nsaa + size, &S->tccgen_vtop[-i]);
+ add_param_plan(plan, STACK_CLASS, nsaa, nsaa + size, &vtop[-i]);
nsaa += size; /* size already rounded up before */
}
return nsaa;
@@ -1153,7 +1160,7 @@ static int assign_regs(TCCState *S, int nb_args, int float_abi, struct plan *pla
todo: a bitmap indicating what core reg will hold a parameter
Returns the number of SValue added by this function on the value stack */
-static int copy_params(TCCState* S, int nb_args, struct plan *plan, int todo)
+static int copy_params(int nb_args, struct plan *plan, int todo)
{
int size, align, r, i, nb_extra_sval = 0;
struct param_plan *pplan;
@@ -1182,7 +1189,7 @@ again:
&& (i != CORE_CLASS || pplan->sval->r < VT_CONST))
continue;
- vpushv(S, pplan->sval);
+ vpushv(pplan->sval);
pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */
switch(i) {
case STACK_CLASS:
@@ -1197,16 +1204,16 @@ again:
padding = pplan->start - pplan->prev->end;
size += padding; /* Add padding if any */
/* allocate the necessary size on stack */
- gadd_sp(S, -size);
+ gadd_sp(-size);
/* generate structure store */
- r = get_reg(S, RC_INT);
- o(S, 0xE28D0000|(intr(S, r)<<12)|padding); /* add r, sp, padding */
- vset(S, &S->tccgen_vtop->type, r | VT_LVAL, 0);
- vswap(S);
+ r = get_reg(RC_INT);
+ o(0xE28D0000|(intr(r)<<12)|padding); /* add r, sp, padding */
+ vset(&vtop->type, r | VT_LVAL, 0);
+ vswap();
/* XXX: optimize. Save all register because memcpy can use them */
- o(S, 0xED2D0A00|(0&1)<<22|(0>>1)<<12|16); /* vpush {s0-s15} */
- vstore(S); /* memcpy to current sp + potential padding */
- o(S, 0xECBD0A00|(0&1)<<22|(0>>1)<<12|16); /* vpop {s0-s15} */
+ o(0xED2D0A00|(0&1)<<22|(0>>1)<<12|16); /* vpush {s0-s15} */
+ vstore(); /* memcpy to current sp + potential padding */
+ o(0xECBD0A00|(0&1)<<22|(0>>1)<<12|16); /* vpop {s0-s15} */
/* Homogeneous float aggregate are loaded to VFP registers
immediately since there is no way of loading data in multiple
@@ -1215,23 +1222,23 @@ again:
if (i == VFP_STRUCT_CLASS) {
int first = pplan->start, nb = pplan->end - first + 1;
/* vpop.32 {pplan->start, ..., pplan->end} */
- o(S, 0xECBD0A00|(first&1)<<22|(first>>1)<<12|nb);
+ o(0xECBD0A00|(first&1)<<22|(first>>1)<<12|nb);
/* No need to write the register used to a SValue since VFP regs
cannot be used for gcall_or_jmp */
}
} else {
if (is_float(pplan->sval->type.t)) {
#ifdef TCC_ARM_VFP
- r = vfpr(S, gv(S, RC_FLOAT)) << 12;
+ r = vfpr(gv(RC_FLOAT)) << 12;
if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
size = 4;
else {
size = 8;
r |= 0x101; /* vpush.32 -> vpush.64 */
}
- o(S, 0xED2D0A01 + r); /* vpush */
+ o(0xED2D0A01 + r); /* vpush */
#else
- r = fpr(S, gv(S, RC_FLOAT)) << 12;
+ r = fpr(gv(RC_FLOAT)) << 12;
if ((pplan->sval->type.t & VT_BTYPE) == VT_FLOAT)
size = 4;
else if ((pplan->sval->type.t & VT_BTYPE) == VT_DOUBLE)
@@ -1244,49 +1251,49 @@ again:
else if(size == 8)
r|=0x8000;
- o(S, 0xED2D0100|r|(size>>2)); /* some kind of vpush for FPA */
+ o(0xED2D0100|r|(size>>2)); /* some kind of vpush for FPA */
#endif
} else {
/* simple type (currently always same size) */
/* XXX: implicit cast ? */
size=4;
if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
- lexpand(S);
+ lexpand();
size = 8;
- r = gv(S, RC_INT);
- o(S, 0xE52D0004|(intr(S, r)<<12)); /* push r */
- S->tccgen_vtop--;
+ r = gv(RC_INT);
+ o(0xE52D0004|(intr(r)<<12)); /* push r */
+ vtop--;
}
- r = gv(S, RC_INT);
- o(S, 0xE52D0004|(intr(S, r)<<12)); /* push r */
+ r = gv(RC_INT);
+ o(0xE52D0004|(intr(r)<<12)); /* push r */
}
if (i == STACK_CLASS && pplan->prev)
- gadd_sp(S, pplan->prev->end - pplan->start); /* Add padding if any */
+ gadd_sp(pplan->prev->end - pplan->start); /* Add padding if any */
}
break;
case VFP_CLASS:
- gv(S, regmask(S, TREG_F0 + (pplan->start >> 1)));
+ gv(regmask(TREG_F0 + (pplan->start >> 1)));
if (pplan->start & 1) { /* Must be in upper part of double register */
- o(S, 0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */
- S->tccgen_vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */
+ o(0xEEF00A40|((pplan->start>>1)<<12)|(pplan->start>>1)); /* vmov.f32 s(n+1), sn */
+ vtop->r = VT_CONST; /* avoid being saved on stack by gv for next float */
}
break;
case CORE_CLASS:
if ((pplan->sval->type.t & VT_BTYPE) == VT_LLONG) {
- lexpand(S);
- gv(S, regmask(S, pplan->end));
- pplan->sval->r2 = S->tccgen_vtop->r;
- S->tccgen_vtop--;
+ lexpand();
+ gv(regmask(pplan->end));
+ pplan->sval->r2 = vtop->r;
+ vtop--;
}
- gv(S, regmask(S, pplan->start));
+ gv(regmask(pplan->start));
/* Mark register as used so that gcall_or_jmp use another one
(regs >=4 are free as never used to pass parameters) */
- pplan->sval->r = S->tccgen_vtop->r;
+ pplan->sval->r = vtop->r;
break;
}
- S->tccgen_vtop--;
+ vtop--;
}
}
@@ -1297,10 +1304,10 @@ again:
/* Manually free remaining registers since next parameters are loaded
* manually, without the help of gv(int). */
- save_regs(S, nb_args);
+ save_regs(nb_args);
if(todo) {
- o(S, 0xE8BD0000|todo); /* pop {todo} */
+ o(0xE8BD0000|todo); /* pop {todo} */
for(pplan = plan->clsplans[CORE_STRUCT_CLASS]; pplan; pplan = pplan->prev) {
int r;
pplan->sval->r = pplan->start;
@@ -1311,8 +1318,8 @@ again:
for (r = pplan->start + 1; r <= pplan->end; r++) {
if (todo & (1 << r)) {
nb_extra_sval++;
- vpushi(S, 0);
- S->tccgen_vtop->r = r;
+ vpushi(0);
+ vtop->r = r;
}
}
}
@@ -1323,7 +1330,7 @@ again:
/* Generate function call. The function address is pushed first, then
all the parameters in call order. This functions pops all the
parameters and the function address. */
-void gfunc_call(TCCState* S, int nb_args)
+void gfunc_call(int nb_args)
{
int r, args_size;
int def_float_abi = float_abi;
@@ -1334,62 +1341,62 @@ void gfunc_call(TCCState* S, int nb_args)
#endif
#ifdef CONFIG_TCC_BCHECK
- if (S->do_bounds_check)
- gbound_args(S, nb_args);
+ if (tcc_state->do_bounds_check)
+ gbound_args(nb_args);
#endif
#ifdef TCC_ARM_EABI
if (float_abi == ARM_HARD_FLOAT) {
- variadic = (S->tccgen_vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
- if (variadic || floats_in_core_regs(&S->tccgen_vtop[-nb_args]))
+ variadic = (vtop[-nb_args].type.ref->f.func_type == FUNC_ELLIPSIS);
+ if (variadic || floats_in_core_regs(&vtop[-nb_args]))
float_abi = ARM_SOFTFP_FLOAT;
}
#endif
/* cannot let cpu flags if other instruction are generated. Also avoid leaving
VT_JMP anywhere except on the top of the stack because it would complicate
the code generator. */
- r = S->tccgen_vtop->r & VT_VALMASK;
+ r = vtop->r & VT_VALMASK;
if (r == VT_CMP || (r & ~1) == VT_JMP)
- gv(S, RC_INT);
+ gv(RC_INT);
memset(&plan, 0, sizeof plan);
if (nb_args)
- plan.pplans = tcc_malloc(S, nb_args * sizeof(*plan.pplans));
+ plan.pplans = tcc_malloc(nb_args * sizeof(*plan.pplans));
- args_size = assign_regs(S, nb_args, float_abi, &plan, &todo);
+ args_size = assign_regs(nb_args, float_abi, &plan, &todo);
#ifdef TCC_ARM_EABI
if (args_size & 7) { /* Stack must be 8 byte aligned at fct call for EABI */
args_size = (args_size + 7) & ~7;
- o(S, 0xE24DD004); /* sub sp, sp, #4 */
+ o(0xE24DD004); /* sub sp, sp, #4 */
}
#endif
- nb_args += copy_params(S, nb_args, &plan, todo);
- tcc_free(S, plan.pplans);
+ nb_args += copy_params(nb_args, &plan, todo);
+ tcc_free(plan.pplans);
/* Move fct SValue on top as required by gcall_or_jmp */
- vrotb(S, nb_args + 1);
- gcall_or_jmp(S, 0);
+ vrotb(nb_args + 1);
+ gcall_or_jmp(0);
if (args_size)
- gadd_sp(S, args_size); /* pop all parameters passed on the stack */
+ gadd_sp(args_size); /* pop all parameters passed on the stack */
#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
- if(float_abi == ARM_SOFTFP_FLOAT && is_float(S->tccgen_vtop->type.ref->type.t)) {
- if((S->tccgen_vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
- o(S, 0xEE000A10); /*vmov s0, r0 */
+ if(float_abi == ARM_SOFTFP_FLOAT && is_float(vtop->type.ref->type.t)) {
+ if((vtop->type.ref->type.t & VT_BTYPE) == VT_FLOAT) {
+ o(0xEE000A10); /*vmov s0, r0 */
} else {
- o(S, 0xEE000B10); /* vmov.32 d0[0], r0 */
- o(S, 0xEE201B10); /* vmov.32 d0[1], r1 */
+ o(0xEE000B10); /* vmov.32 d0[0], r0 */
+ o(0xEE201B10); /* vmov.32 d0[1], r1 */
}
}
#endif
- S->tccgen_vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
+ vtop -= nb_args + 1; /* Pop all params and fct address from value stack */
leaffunc = 0; /* we are calling a function, so we aren't in a leaf function */
float_abi = def_float_abi;
}
/* generate function prolog of type 't' */
-void gfunc_prolog(TCCState* S, Sym *func_sym)
+void gfunc_prolog(Sym *func_sym)
{
CType *func_type = &func_sym->type;
Sym *sym,*sym2;
@@ -1404,17 +1411,17 @@ void gfunc_prolog(TCCState* S, Sym *func_sym)
sym = func_type->ref;
n = nf = 0;
- if ((S->tccgen_func_vt.t & VT_BTYPE) == VT_STRUCT &&
- !gfunc_sret(&S->tccgen_func_vt, S->tccgen_func_var, &ret_type, &align, &rs))
+ if ((func_vt.t & VT_BTYPE) == VT_STRUCT &&
+ !gfunc_sret(&func_vt, func_var, &ret_type, &align, &rs))
{
n++;
struct_ret = 1;
- S->tccgen_func_vc = 12; /* Offset from fp of the place to store the result */
+ func_vc = 12; /* Offset from fp of the place to store the result */
}
for(sym2 = sym->next; sym2 && (n < 4 || nf < 16); sym2 = sym2->next) {
size = type_size(&sym2->type, &align);
#ifdef TCC_ARM_EABI
- if (float_abi == ARM_HARD_FLOAT && !S->tccgen_func_var &&
+ if (float_abi == ARM_HARD_FLOAT && !func_var &&
(is_float(sym2->type.t) || is_hgen_float_aggr(&sym2->type))) {
int tmpnf = assign_vfpreg(&avregs, align, size);
tmpnf += (size + 3) / 4;
@@ -1424,8 +1431,8 @@ void gfunc_prolog(TCCState* S, Sym *func_sym)
if (n < 4)
n += (size + 3) / 4;
}
- o(S, 0xE1A0C00D); /* mov ip,sp */
- if (S->tccgen_func_var)
+ o(0xE1A0C00D); /* mov ip,sp */
+ if (func_var)
n=4;
if (n) {
if(n>4)
@@ -1433,22 +1440,22 @@ void gfunc_prolog(TCCState* S, Sym *func_sym)
#ifdef TCC_ARM_EABI
n=(n+1)&-2;
#endif
- o(S, 0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */
+ o(0xE92D0000|((1<<n)-1)); /* save r0-r4 on stack if needed */
}
if (nf) {
if (nf>16)
nf=16;
nf=(nf+1)&-2; /* nf => HARDFLOAT => EABI */
- o(S, 0xED2D0A00|nf); /* save s0-s15 on stack if needed */
+ o(0xED2D0A00|nf); /* save s0-s15 on stack if needed */
}
- o(S, 0xE92D5800); /* save fp, ip, lr */
- o(S, 0xE1A0B00D); /* mov fp, sp */
- func_sub_sp_offset = S->tccgen_ind;
- o(S, 0xE1A00000); /* nop, leave space for stack adjustment in epilog */
+ o(0xE92D5800); /* save fp, ip, lr */
+ o(0xE1A0B00D); /* mov fp, sp */
+ func_sub_sp_offset = ind;
+ o(0xE1A00000); /* nop, leave space for stack adjustment in epilog */
#ifdef TCC_ARM_EABI
if (float_abi == ARM_HARD_FLOAT) {
- S->tccgen_func_vc += nf * 4;
+ func_vc += nf * 4;
memset(&avregs, 0, sizeof avregs);
}
#endif
@@ -1460,7 +1467,7 @@ void gfunc_prolog(TCCState* S, Sym *func_sym)
size = (size + 3) >> 2;
align = (align + 3) & ~3;
#ifdef TCC_ARM_EABI
- if (float_abi == ARM_HARD_FLOAT && !S->tccgen_func_var && (is_float(sym->type.t)
+ if (float_abi == ARM_HARD_FLOAT && !func_var && (is_float(sym->type.t)
|| is_hgen_float_aggr(&sym->type))) {
int fpn = assign_vfpreg(&avregs, align, size << 2);
if (fpn >= 0)
@@ -1485,42 +1492,42 @@ from_stack:
addr = (n + nf + sn) * 4;
sn += size;
}
- sym_push(S, sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL,
+ sym_push(sym->v & ~SYM_FIELD, type, VT_LOCAL | VT_LVAL,
addr + 12);
}
last_itod_magic=0;
leaffunc = 1;
- S->tccgen_loc = 0;
+ loc = 0;
#ifdef CONFIG_TCC_BCHECK
- if (S->do_bounds_check)
- gen_bounds_prolog(S);
+ if (tcc_state->do_bounds_check)
+ gen_bounds_prolog();
#endif
}
/* generate function epilog */
-void gfunc_epilog(TCCState* S)
+void gfunc_epilog(void)
{
uint32_t x;
int diff;
#ifdef CONFIG_TCC_BCHECK
- if (S->do_bounds_check)
- gen_bounds_epilog(S);
+ if (tcc_state->do_bounds_check)
+ gen_bounds_epilog();
#endif
/* Copy float return value to core register if base standard is used and
float computation is made with VFP */
#if defined(TCC_ARM_EABI) && defined(TCC_ARM_VFP)
- if ((float_abi == ARM_SOFTFP_FLOAT || S->tccgen_func_var) && is_float(S->tccgen_func_vt.t)) {
- if((S->tccgen_func_vt.t & VT_BTYPE) == VT_FLOAT)
- o(S, 0xEE100A10); /* fmrs r0, s0 */
+ if ((float_abi == ARM_SOFTFP_FLOAT || func_var) && is_float(func_vt.t)) {
+ if((func_vt.t & VT_BTYPE) == VT_FLOAT)
+ o(0xEE100A10); /* fmrs r0, s0 */
else {
- o(S, 0xEE100B10); /* fmrdl r0, d0 */
- o(S, 0xEE301B10); /* fmrdh r1, d0 */
+ o(0xEE100B10); /* fmrdl r0, d0 */
+ o(0xEE301B10); /* fmrdh r1, d0 */
}
}
#endif
- o(S, 0xE89BA800); /* restore fp, sp, pc */
- diff = (-S->tccgen_loc + 3) & -4;
+ o(0xE89BA800); /* restore fp, sp, pc */
+ diff = (-loc + 3) & -4;
#ifdef TCC_ARM_EABI
if(!leaffunc)
diff = ((diff + 11) & -8) - 4;
@@ -1531,74 +1538,74 @@ void gfunc_epilog(TCCState* S)
*(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = x;
else {
int addr;
- addr=S->tccgen_ind;
- o(S, 0xE59FC004); /* ldr ip,[pc+4] */
- o(S, 0xE04BD00C); /* sub sp,fp,ip */
- o(S, 0xE1A0F00E); /* mov pc,lr */
- o(S, diff);
- *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(S, func_sub_sp_offset,addr,1);
+ addr=ind;
+ o(0xE59FC004); /* ldr ip,[pc+4] */
+ o(0xE04BD00C); /* sub sp,fp,ip */
+ o(0xE1A0F00E); /* mov pc,lr */
+ o(diff);
+ *(uint32_t *)(cur_text_section->data + func_sub_sp_offset) = 0xE1000000|encbranch(func_sub_sp_offset,addr,1);
}
}
}
-ST_FUNC void gen_fill_nops(TCCState* S, int bytes)
+ST_FUNC void gen_fill_nops(int bytes)
{
if ((bytes & 3))
- tcc_error(S, "alignment of code section not multiple of 4");
+ tcc_error("alignment of code section not multiple of 4");
while (bytes > 0) {
- o(S, 0xE1A00000);
+ o(0xE1A00000);
bytes -= 4;
}
}
/* generate a jump to a label */
-ST_FUNC int gjmp(TCCState* S, int t)
+ST_FUNC int gjmp(int t)
{
int r;
- if (S->tccgen_nocode_wanted)
+ if (nocode_wanted)
return t;
- r=S->tccgen_ind;
- o(S, 0xE0000000|encbranch(S, r,t,1));
+ r=ind;
+ o(0xE0000000|encbranch(r,t,1));
return r;
}
/* generate a jump to a fixed address */
-ST_FUNC void gjmp_addr(TCCState* S, int a)
+ST_FUNC void gjmp_addr(int a)
{
- gjmp(S, a);
+ gjmp(a);
}
-ST_FUNC int gjmp_cond(TCCState* S, int op, int t)
+ST_FUNC int gjmp_cond(int op, int t)
{
int r;
- if (S->tccgen_nocode_wanted)
+ if (nocode_wanted)
return t;
- r=S->tccgen_ind;
- op=mapcc(S, op);
- op|=encbranch(S, r,t,1);
- o(S, op);
+ r=ind;
+ op=mapcc(op);
+ op|=encbranch(r,t,1);
+ o(op);
return r;
}
-ST_FUNC int gjmp_append(TCCState* S, int n, int t)
+ST_FUNC int gjmp_append(int n, int t)
{
uint32_t *x;
int p,lp;
if(n) {
p = n;
do {
- p = decbranch(S, lp=p);
+ p = decbranch(lp=p);
} while(p);
x = (uint32_t *)(cur_text_section->data + lp);
*x &= 0xff000000;
- *x |= encbranch(S, lp,t,1);
+ *x |= encbranch(lp,t,1);
t = n;
}
return t;
}
/* generate an integer binary operation */
-void gen_opi(TCCState* S, int op)
+void gen_opi(int op)
{
int c, func = 0;
uint32_t opc = 0, r, fr;
@@ -1643,11 +1650,11 @@ void gen_opi(TCCState* S, int op)
c=1;
break;
case '*':
- gv2(S, RC_INT, RC_INT);
- r = S->tccgen_vtop[-1].r;
- fr = S->tccgen_vtop[0].r;
- S->tccgen_vtop--;
- o(S, 0xE0000090|(intr(S, r)<<16)|(intr(S, r)<<8)|intr(S, fr));
+ gv2(RC_INT, RC_INT);
+ r = vtop[-1].r;
+ fr = vtop[0].r;
+ vtop--;
+ o(0xE0000090|(intr(r)<<16)|(intr(r)<<8)|intr(fr));
return;
case TOK_SHL:
opc = 0;
@@ -1689,12 +1696,12 @@ void gen_opi(TCCState* S, int op)
c=3;
break;
case TOK_UMULL:
- gv2(S, RC_INT, RC_INT);
- r=intr(S, S->tccgen_vtop[-1].r2=get_reg(S, RC_INT));
- c=S->tccgen_vtop[-1].r;
- S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, c));
- S->tccgen_vtop--;
- o(S, 0xE0800090|(r<<16)|(intr(S, S->tccgen_vtop->r)<<12)|(intr(S, c)<<8)|intr(S, S->tccgen_vtop[1].r));
+ gv2(RC_INT, RC_INT);
+ r=intr(vtop[-1].r2=get_reg(RC_INT));
+ 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));
return;
default:
opc = 0x15;
@@ -1703,128 +1710,128 @@ void gen_opi(TCCState* S, int op)
}
switch(c) {
case 1:
- if((S->tccgen_vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+ if((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
if(opc == 4 || opc == 5 || opc == 0xc) {
- vswap(S);
+ vswap();
opc|=2; // sub -> rsb
}
}
- if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP ||
- (S->tccgen_vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
- gv(S, RC_INT);
- vswap(S);
- c=intr(S, gv(S, RC_INT));
- vswap(S);
+ if ((vtop->r & VT_VALMASK) == VT_CMP ||
+ (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
+ gv(RC_INT);
+ vswap();
+ c=intr(gv(RC_INT));
+ vswap();
opc=0xE0000000|(opc<<20);
- if((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
+ if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
uint32_t x;
- x=stuff_const(opc|0x2000000|(c<<16),S->tccgen_vtop->c.i);
+ x=stuff_const(opc|0x2000000|(c<<16),vtop->c.i);
if(x) {
if ((x & 0xfff00000) == 0xe3500000) // cmp rx,#c
- o(S, x);
+ o(x);
else {
- r=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->tccgen_vtop[-1].r)));
- o(S, x|(r<<12));
+ r=intr(vtop[-1].r=get_reg_ex(RC_INT,regmask(vtop[-1].r)));
+ o(x|(r<<12));
}
goto done;
}
}
- fr=intr(S, gv(S, RC_INT));
+ fr=intr(gv(RC_INT));
#ifdef CONFIG_TCC_BCHECK
- if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
- vswap(S);
- c=intr(S, gv(S, RC_INT));
- vswap(S);
+ if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
+ vswap();
+ c=intr(gv(RC_INT));
+ vswap();
}
#endif
if ((opc & 0xfff00000) == 0xe1500000) // cmp rx,ry
- o(S, opc|(c<<16)|fr);
+ o(opc|(c<<16)|fr);
else {
- r=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,two2mask(S, S->tccgen_vtop->r,S->tccgen_vtop[-1].r)));
- o(S, opc|(c<<16)|(r<<12)|fr);
+ r=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
+ o(opc|(c<<16)|(r<<12)|fr);
}
done:
- S->tccgen_vtop--;
+ vtop--;
if (op >= TOK_ULT && op <= TOK_GT)
- vset_VT_CMP(S, op);
+ vset_VT_CMP(op);
break;
case 2:
opc=0xE1A00000|(opc<<5);
- if ((S->tccgen_vtop->r & VT_VALMASK) == VT_CMP ||
- (S->tccgen_vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
- gv(S, RC_INT);
- vswap(S);
- r=intr(S, gv(S, RC_INT));
- vswap(S);
- if ((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
- fr=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,regmask(S, S->tccgen_vtop[-1].r)));
- c = S->tccgen_vtop->c.i & 0x1f;
- o(S, opc|r|(c<<7)|(fr<<12));
+ if ((vtop->r & VT_VALMASK) == VT_CMP ||
+ (vtop->r & (VT_VALMASK & ~1)) == VT_JMP)
+ gv(RC_INT);
+ vswap();
+ r=intr(gv(RC_INT));
+ vswap();
+ 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|r|(c<<7)|(fr<<12));
} else {
- fr=intr(S, gv(S, RC_INT));
+ fr=intr(gv(RC_INT));
#ifdef CONFIG_TCC_BCHECK
- if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
- vswap(S);
- r=intr(S, gv(S, RC_INT));
- vswap(S);
+ if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
+ vswap();
+ r=intr(gv(RC_INT));
+ vswap();
}
#endif
- c=intr(S, S->tccgen_vtop[-1].r=get_reg_ex(S, RC_INT,two2mask(S, S->tccgen_vtop->r,S->tccgen_vtop[-1].r)));
- o(S, opc|r|(c<<12)|(fr<<8)|0x10);
+ c=intr(vtop[-1].r=get_reg_ex(RC_INT,two2mask(vtop->r,vtop[-1].r)));
+ o(opc|r|(c<<12)|(fr<<8)|0x10);
}
- S->tccgen_vtop--;
+ vtop--;
break;
case 3:
- vpush_helper_func(S, func);
- vrott(S, 3);
- gfunc_call(S, 2);
- vpushi(S, 0);
- S->tccgen_vtop->r = retreg;
+ vpush_helper_func(func);
+ vrott(3);
+ gfunc_call(2);
+ vpushi(0);
+ vtop->r = retreg;
break;
default:
- tcc_error(S, "gen_opi %i unimplemented!",op);
+ tcc_error("gen_opi %i unimplemented!",op);
}
}
#ifdef TCC_ARM_VFP
-static int is_zero(TCCState* S, int i)
+static int is_zero(int i)
{
- if((S->tccgen_vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+ if((vtop[i].r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
return 0;
- if (S->tccgen_vtop[i].type.t == VT_FLOAT)
- return (S->tccgen_vtop[i].c.f == 0.f);
- else if (S->tccgen_vtop[i].type.t == VT_DOUBLE)
- return (S->tccgen_vtop[i].c.d == 0.0);
- return (S->tccgen_vtop[i].c.ld == 0.l);
+ if (vtop[i].type.t == VT_FLOAT)
+ return (vtop[i].c.f == 0.f);
+ else if (vtop[i].type.t == VT_DOUBLE)
+ return (vtop[i].c.d == 0.0);
+ return (vtop[i].c.ld == 0.l);
}
/* generate a floating point operation 'v = t1 op t2' instruction. The
* two operands are guaranteed to have the same floating point type */
-void gen_opf(TCCState* S, int op)
+void gen_opf(int op)
{
uint32_t x;
int fneg=0,r;
- x=0xEE000A00|T2CPR(S->tccgen_vtop->type.t);
+ x=0xEE000A00|T2CPR(vtop->type.t);
switch(op) {
case '+':
- if(is_zero(S, -1))
- vswap(S);
- if(is_zero(S, 0)) {
- S->tccgen_vtop--;
+ if(is_zero(-1))
+ vswap();
+ if(is_zero(0)) {
+ vtop--;
return;
}
x|=0x300000;
break;
case '-':
x|=0x300040;
- if(is_zero(S, 0)) {
- S->tccgen_vtop--;
+ if(is_zero(0)) {
+ vtop--;
return;
}
- if(is_zero(S, -1)) {
+ if(is_zero(-1)) {
x|=0x810000; /* fsubX -> fnegX */
- vswap(S);
- S->tccgen_vtop--;
+ vswap();
+ vtop--;
fneg=1;
}
break;
@@ -1836,11 +1843,11 @@ void gen_opf(TCCState* S, int op)
break;
default:
if(op < TOK_ULT || op > TOK_GT) {
- tcc_error(S, "unknown fp op %x!",op);
+ tcc_error("unknown fp op %x!",op);
return;
}
- if(is_zero(S, -1)) {
- vswap(S);
+ if(is_zero(-1)) {
+ vswap();
switch(op) {
case TOK_LT: op=TOK_GT; break;
case TOK_GE: op=TOK_ULE; break;
@@ -1851,16 +1858,16 @@ void gen_opf(TCCState* S, int op)
x|=0xB40040; /* fcmpX */
if(op!=TOK_EQ && op!=TOK_NE)
x|=0x80; /* fcmpX -> fcmpeX */
- if(is_zero(S, 0)) {
- S->tccgen_vtop--;
- o(S, x|0x10000|(vfpr(S, gv(S, RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */
+ if(is_zero(0)) {
+ vtop--;
+ o(x|0x10000|(vfpr(gv(RC_FLOAT))<<12)); /* fcmp(e)X -> fcmp(e)zX */
} else {
- gv2(S, RC_FLOAT,RC_FLOAT);
- x|=vfpr(S, S->tccgen_vtop[0].r);
- o(S, x|(vfpr(S, S->tccgen_vtop[-1].r) << 12));
- S->tccgen_vtop--;
+ gv2(RC_FLOAT,RC_FLOAT);
+ x|=vfpr(vtop[0].r);
+ o(x|(vfpr(vtop[-1].r) << 12));
+ vtop--;
}
- o(S, 0xEEF1FA10); /* fmstat */
+ o(0xEEF1FA10); /* fmstat */
switch(op) {
case TOK_LE: op=TOK_ULE; break;
@@ -1868,46 +1875,46 @@ void gen_opf(TCCState* S, int op)
case TOK_UGE: op=TOK_GE; break;
case TOK_UGT: op=TOK_GT; break;
}
- vset_VT_CMP(S, op);
+ vset_VT_CMP(op);
return;
}
- r=gv(S, RC_FLOAT);
- x|=vfpr(S, r);
- r=regmask(S, r);
+ r=gv(RC_FLOAT);
+ x|=vfpr(r);
+ r=regmask(r);
if(!fneg) {
int r2;
- vswap(S);
- r2=gv(S, RC_FLOAT);
- x|=vfpr(S, r2)<<16;
- r|=regmask(S, r2);
+ vswap();
+ r2=gv(RC_FLOAT);
+ x|=vfpr(r2)<<16;
+ r|=regmask(r2);
#ifdef CONFIG_TCC_BCHECK
- if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
- vswap(S);
- r=gv(S, RC_FLOAT);
- vswap(S);
- x=(x&~0xf)|vfpr(S, r);
+ if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
+ vswap();
+ r=gv(RC_FLOAT);
+ vswap();
+ x=(x&~0xf)|vfpr(r);
}
#endif
}
- S->tccgen_vtop->r=get_reg_ex(S, RC_FLOAT,r);
+ vtop->r=get_reg_ex(RC_FLOAT,r);
if(!fneg)
- S->tccgen_vtop--;
- o(S, x|(vfpr(S, S->tccgen_vtop->r)<<12));
+ vtop--;
+ o(x|(vfpr(vtop->r)<<12));
}
#else
-static uint32_t is_fconst(TCCState* S)
+static uint32_t is_fconst()
{
long double f;
uint32_t r;
- if((S->tccgen_vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
+ if((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) != VT_CONST)
return 0;
- if (S->tccgen_vtop->type.t == VT_FLOAT)
- f = S->tccgen_vtop->c.f;
- else if (S->tccgen_vtop->type.t == VT_DOUBLE)
- f = S->tccgen_vtop->c.d;
+ if (vtop->type.t == VT_FLOAT)
+ f = vtop->c.f;
+ else if (vtop->type.t == VT_DOUBLE)
+ f = vtop->c.d;
else
- f = S->tccgen_vtop->c.ld;
+ f = vtop->c.ld;
if(!ieee_finite(f))
return 0;
r=0x8;
@@ -1936,45 +1943,45 @@ static uint32_t is_fconst(TCCState* S)
/* generate a floating point operation 'v = t1 op t2' instruction. The
two operands are guaranteed to have the same floating point type */
-void gen_opf(TCCState* S, int op)
+void gen_opf(int op)
{
uint32_t x, r, r2, c1, c2;
//fputs("gen_opf\n",stderr);
- vswap(S);
- c1 = is_fconst(S);
- vswap(S);
- c2 = is_fconst(S);
+ vswap();
+ c1 = is_fconst();
+ vswap();
+ c2 = is_fconst();
x=0xEE000100;
#if LDOUBLE_SIZE == 8
- if ((S->tccgen_vtop->type.t & VT_BTYPE) != VT_FLOAT)
+ if ((vtop->type.t & VT_BTYPE) != VT_FLOAT)
x|=0x80;
#else
- if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_DOUBLE)
+ if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
x|=0x80;
- else if ((S->tccgen_vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
+ else if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE)
x|=0x80000;
#endif
switch(op)
{
case '+':
if(!c2) {
- vswap(S);
+ vswap();
c2=c1;
}
- vswap(S);
- r=fpr(S, gv(S, RC_FLOAT));
- vswap(S);
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
if(c2) {
if(c2>0xf)
x|=0x200000; // suf
r2=c2&0xf;
} else {
- r2=fpr(S, gv(S, RC_FLOAT));
+ r2=fpr(gv(RC_FLOAT));
#ifdef CONFIG_TCC_BCHECK
- if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
- vswap(S);
- r=fpr(S, gv(S, RC_FLOAT));
- vswap(S);
+ if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
}
#endif
}
@@ -1984,46 +1991,46 @@ void gen_opf(TCCState* S, int op)
if(c2<=0xf)
x|=0x200000; // suf
r2=c2&0xf;
- vswap(S);
- r=fpr(S, gv(S, RC_FLOAT));
- vswap(S);
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
} else if(c1 && c1<=0xf) {
x|=0x300000; // rsf
r2=c1;
- r=fpr(S, gv(S, RC_FLOAT));
- vswap(S);
+ r=fpr(gv(RC_FLOAT));
+ vswap();
} else {
x|=0x200000; // suf
- vswap(S);
- r=fpr(S, gv(S, RC_FLOAT));
- vswap(S);
- r2=fpr(S, gv(S, RC_FLOAT));
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
+ r2=fpr(gv(RC_FLOAT));
#ifdef CONFIG_TCC_BCHECK
- if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
- vswap(S);
- r=fpr(S, gv(S, RC_FLOAT));
- vswap(S);
+ if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
}
#endif
}
break;
case '*':
if(!c2 || c2>0xf) {
- vswap(S);
+ vswap();
c2=c1;
}
- vswap(S);
- r=fpr(S, gv(S, RC_FLOAT));
- vswap(S);
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
if(c2 && c2<=0xf)
r2=c2;
else {
- r2=fpr(S, gv(S, RC_FLOAT));
+ r2=fpr(gv(RC_FLOAT));
#ifdef CONFIG_TCC_BCHECK
- if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
- vswap(S);
- r=fpr(S, gv(S, RC_FLOAT));
- vswap(S);
+ if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
}
#endif
}
@@ -2033,25 +2040,25 @@ void gen_opf(TCCState* S, int op)
if(c2 && c2<=0xf) {
x|=0x400000; // dvf
r2=c2;
- vswap(S);
- r=fpr(S, gv(S, RC_FLOAT));
- vswap(S);
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
} else if(c1 && c1<=0xf) {
x|=0x500000; // rdf
r2=c1;
- r=fpr(S, gv(S, RC_FLOAT));
- vswap(S);
+ r=fpr(gv(RC_FLOAT));
+ vswap();
} else {
x|=0x400000; // dvf
- vswap(S);
- r=fpr(S, gv(S, RC_FLOAT));
- vswap(S);
- r2=fpr(S, gv(S, RC_FLOAT));
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
+ r2=fpr(gv(RC_FLOAT));
#ifdef CONFIG_TCC_BCHECK
- if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
- vswap(S);
- r=fpr(S, gv(S, RC_FLOAT));
- vswap(S);
+ if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
}
#endif
}
@@ -2066,7 +2073,7 @@ void gen_opf(TCCState* S, int op)
case TOK_UGE:
case TOK_ULE:
case TOK_UGT:
- tcc_error(S, "unsigned comparison on floats?");
+ tcc_error("unsigned comparison on floats?");
break;
case TOK_LT:
op=TOK_Nset;
@@ -2081,7 +2088,7 @@ void gen_opf(TCCState* S, int op)
}
if(c1 && !c2) {
c2=c1;
- vswap(S);
+ vswap();
switch(op) {
case TOK_Nset:
op=TOK_GT;
@@ -2097,86 +2104,86 @@ void gen_opf(TCCState* S, int op)
break;
}
}
- vswap(S);
- r=fpr(S, gv(S, RC_FLOAT));
- vswap(S);
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
if(c2) {
if(c2>0xf)
x|=0x200000;
r2=c2&0xf;
} else {
- r2=fpr(S, gv(S, RC_FLOAT));
+ r2=fpr(gv(RC_FLOAT));
#ifdef CONFIG_TCC_BCHECK
- if ((S->tccgen_vtop[-1].r & VT_VALMASK) >= VT_CONST) {
- vswap(S);
- r=fpr(S, gv(S, RC_FLOAT));
- vswap(S);
+ if ((vtop[-1].r & VT_VALMASK) >= VT_CONST) {
+ vswap();
+ r=fpr(gv(RC_FLOAT));
+ vswap();
}
#endif
}
- --S->tccgen_vtop;
- vset_VT_CMP(S, op);
- ++S->tccgen_vtop;
+ --vtop;
+ vset_VT_CMP(op);
+ ++vtop;
} else {
- tcc_error(S, "unknown fp op %x!",op);
+ tcc_error("unknown fp op %x!",op);
return;
}
}
- if(S->tccgen_vtop[-1].r == VT_CMP)
+ if(vtop[-1].r == VT_CMP)
c1=15;
else {
- c1=S->tccgen_vtop->r;
+ c1=vtop->r;
if(r2&0x8)
- c1=S->tccgen_vtop[-1].r;
- S->tccgen_vtop[-1].r=get_reg_ex(S, RC_FLOAT,two2mask(S, S->tccgen_vtop[-1].r,c1));
- c1=fpr(S, S->tccgen_vtop[-1].r);
+ c1=vtop[-1].r;
+ vtop[-1].r=get_reg_ex(RC_FLOAT,two2mask(vtop[-1].r,c1));
+ c1=fpr(vtop[-1].r);
}
- S->tccgen_vtop--;
- o(S, x|(r<<16)|(c1<<12)|r2);
+ vtop--;
+ o(x|(r<<16)|(c1<<12)|r2);
}
#endif
/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
and 'long long' cases. */
-ST_FUNC void gen_cvt_itof(TCCState* S, int t)
+ST_FUNC void gen_cvt_itof(int t)
{
uint32_t r, r2;
int bt;
- bt=S->tccgen_vtop->type.t & VT_BTYPE;
+ bt=vtop->type.t & VT_BTYPE;
if(bt == VT_INT || bt == VT_SHORT || bt == VT_BYTE) {
#ifndef TCC_ARM_VFP
uint32_t dsize = 0;
#endif
- r=intr(S, gv(S, RC_INT));
+ r=intr(gv(RC_INT));
#ifdef TCC_ARM_VFP
- r2=vfpr(S, S->tccgen_vtop->r=get_reg(S, RC_FLOAT));
- o(S, 0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */
+ r2=vfpr(vtop->r=get_reg(RC_FLOAT));
+ o(0xEE000A10|(r<<12)|(r2<<16)); /* fmsr */
r2|=r2<<12;
- if(!(S->tccgen_vtop->type.t & VT_UNSIGNED))
+ if(!(vtop->type.t & VT_UNSIGNED))
r2|=0x80; /* fuitoX -> fsituX */
- o(S, 0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/
+ o(0xEEB80A40|r2|T2CPR(t)); /* fYitoX*/
#else
- r2=fpr(S, S->tccgen_vtop->r=get_reg(S, RC_FLOAT));
+ r2=fpr(vtop->r=get_reg(RC_FLOAT));
if((t & VT_BTYPE) != VT_FLOAT)
dsize=0x80; /* flts -> fltd */
- o(S, 0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */
- if((S->tccgen_vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {
+ o(0xEE000110|dsize|(r2<<16)|(r<<12)); /* flts */
+ if((vtop->type.t & (VT_UNSIGNED|VT_BTYPE)) == (VT_UNSIGNED|VT_INT)) {
uint32_t off = 0;
- o(S, 0xE3500000|(r<<12)); /* cmp */
- r=fpr(S, get_reg(S, RC_FLOAT));
+ o(0xE3500000|(r<<12)); /* cmp */
+ r=fpr(get_reg(RC_FLOAT));
if(last_itod_magic) {
- off=S->tccgen_ind+8-last_itod_magic;
+ off=ind+8-last_itod_magic;
off/=4;
if(off>255)
off=0;
}
- o(S, 0xBD1F0100|(r<<12)|off); /* ldflts */
+ o(0xBD1F0100|(r<<12)|off); /* ldflts */
if(!off) {
- o(S, 0xEA000000); /* b */
- last_itod_magic=S->tccgen_ind;
- o(S, 0x4F800000); /* 4294967296.0f */
+ o(0xEA000000); /* b */
+ last_itod_magic=ind;
+ o(0x4F800000); /* 4294967296.0f */
}
- o(S, 0xBE000100|dsize|(r2<<16)|(r2<<12)|r); /* adflt */
+ o(0xBE000100|dsize|(r2<<16)|(r2<<12)|r); /* adflt */
}
#endif
return;
@@ -2184,15 +2191,15 @@ ST_FUNC void gen_cvt_itof(TCCState* S, int t)
int func;
CType *func_type = 0;
if((t & VT_BTYPE) == VT_FLOAT) {
- func_type = &S->armgen_func_float_type;
- if(S->tccgen_vtop->type.t & VT_UNSIGNED)
+ func_type = &func_float_type;
+ if(vtop->type.t & VT_UNSIGNED)
func=TOK___floatundisf;
else
func=TOK___floatdisf;
#if LDOUBLE_SIZE != 8
} else if((t & VT_BTYPE) == VT_LDOUBLE) {
- func_type = &S->armgen_func_ldouble_type;
- if(S->tccgen_vtop->type.t & VT_UNSIGNED)
+ func_type = &func_ldouble_type;
+ if(vtop->type.t & VT_UNSIGNED)
func=TOK___floatundixf;
else
func=TOK___floatdixf;
@@ -2200,39 +2207,39 @@ ST_FUNC void gen_cvt_itof(TCCState* S, int t)
#else
} else if((t & VT_BTYPE) == VT_DOUBLE || (t & VT_BTYPE) == VT_LDOUBLE) {
#endif
- func_type = &S->armgen_func_double_type;
- if(S->tccgen_vtop->type.t & VT_UNSIGNED)
+ func_type = &func_double_type;
+ if(vtop->type.t & VT_UNSIGNED)
func=TOK___floatundidf;
else
func=TOK___floatdidf;
}
if(func_type) {
- vpushsym(S, func_type, external_helper_sym(S, func));
- vswap(S);
- gfunc_call(S, 1);
- vpushi(S, 0);
- S->tccgen_vtop->r=TREG_F0;
+ vpushsym(func_type, external_helper_sym(func));
+ vswap();
+ gfunc_call(1);
+ vpushi(0);
+ vtop->r=TREG_F0;
return;
}
}
- tcc_error(S, "unimplemented gen_cvt_itof %x!",S->tccgen_vtop->type.t);
+ tcc_error("unimplemented gen_cvt_itof %x!",vtop->type.t);
}
/* convert fp to int 't' type */
-void gen_cvt_ftoi(TCCState* S, int t)
+void gen_cvt_ftoi(int t)
{
uint32_t r, r2;
int u, func = 0;
u=t&VT_UNSIGNED;
t&=VT_BTYPE;
- r2=S->tccgen_vtop->type.t & VT_BTYPE;
+ r2=vtop->type.t & VT_BTYPE;
if(t==VT_INT) {
#ifdef TCC_ARM_VFP
- r=vfpr(S, gv(S, RC_FLOAT));
+ r=vfpr(gv(RC_FLOAT));
u=u?0:0x10000;
- o(S, 0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u); /* ftoXizY */
- r2=intr(S, S->tccgen_vtop->r=get_reg(S, RC_INT));
- o(S, 0xEE100A10|(r<<16)|(r2<<12));
+ o(0xEEBC0AC0|(r<<12)|r|T2CPR(r2)|u); /* ftoXizY */
+ r2=intr(vtop->r=get_reg(RC_INT));
+ o(0xEE100A10|(r<<16)|(r2<<12));
return;
#else
if(u) {
@@ -2247,9 +2254,9 @@ void gen_cvt_ftoi(TCCState* S, int t)
#endif
func=TOK___fixunsdfsi;
} else {
- r=fpr(S, gv(S, RC_FLOAT));
- r2=intr(S, S->tccgen_vtop->r=get_reg(S, RC_INT));
- o(S, 0xEE100170|(r2<<12)|r);
+ r=fpr(gv(RC_FLOAT));
+ r2=intr(vtop->r=get_reg(RC_INT));
+ o(0xEE100170|(r2<<12)|r);
return;
}
#endif
@@ -2266,93 +2273,93 @@ void gen_cvt_ftoi(TCCState* S, int t)
func=TOK___fixdfdi;
}
if(func) {
- vpush_helper_func(S, func);
- vswap(S);
- gfunc_call(S, 1);
- vpushi(S, 0);
+ vpush_helper_func(func);
+ vswap();
+ gfunc_call(1);
+ vpushi(0);
if(t == VT_LLONG)
- S->tccgen_vtop->r2 = REG_IRE2;
- S->tccgen_vtop->r = REG_IRET;
+ vtop->r2 = REG_IRE2;
+ vtop->r = REG_IRET;
return;
}
- tcc_error(S, "unimplemented gen_cvt_ftoi!");
+ tcc_error("unimplemented gen_cvt_ftoi!");
}
/* convert from one floating point type to another */
-void gen_cvt_ftof(TCCState* S, int t)
+void gen_cvt_ftof(int t)
{
#ifdef TCC_ARM_VFP
- if(((S->tccgen_vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
- uint32_t r = vfpr(S, gv(S, RC_FLOAT));
- o(S, 0xEEB70AC0|(r<<12)|r|T2CPR(S->tccgen_vtop->type.t));
+ if(((vtop->type.t & VT_BTYPE) == VT_FLOAT) != ((t & VT_BTYPE) == VT_FLOAT)) {
+ uint32_t r = vfpr(gv(RC_FLOAT));
+ o(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 */
- gv(S, RC_FLOAT);
+ gv(RC_FLOAT);
#endif
}
/* increment tcov counter */
-ST_FUNC void gen_increment_tcov (TCCState* S, SValue *sv)
+ST_FUNC void gen_increment_tcov (SValue *sv)
{
int r1, r2;
- vpushv(S, sv);
- S->tccgen_vtop->r = r1 = get_reg(S, RC_INT);
- r2 = get_reg(S, RC_INT);
- o(S, 0xE59F0000 | (intr(S, r1)<<12)); // ldr r1,[pc]
- o(S, 0xEA000000); // b $+4
- greloc(S, cur_text_section, sv->sym, S->tccgen_ind, R_ARM_REL32);
- o(S, -12);
- o(S, 0xe080000f | (intr(S, r1)<<16) | (intr(S, r1)<<12)); // add r1,r1,pc
- o(S, 0xe5900000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // ldr r2, [r1]
- o(S, 0xe2900001 | (intr(S, r2)<<16) | (intr(S, r2)<<12)); // adds r2, r2, #1
- o(S, 0xe5800000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // str r2, [r1]
- o(S, 0xe2800004 | (intr(S, r1)<<16) | (intr(S, r1)<<12)); // add r1, r1, #4
- o(S, 0xe5900000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // ldr r2, [r1]
- o(S, 0xe2a00000 | (intr(S, r2)<<16) | (intr(S, r2)<<12)); // adc r2, r2, #0
- o(S, 0xe5800000 | (intr(S, r1)<<16) | (intr(S, r2)<<12)); // str r2, [r1]
- vpop(S);
+ vpushv(sv);
+ vtop->r = r1 = get_reg(RC_INT);
+ r2 = get_reg(RC_INT);
+ o(0xE59F0000 | (intr(r1)<<12)); // ldr r1,[pc]
+ o(0xEA000000); // b $+4
+ greloc(cur_text_section, sv->sym, ind, R_ARM_REL32);
+ o(-12);
+ o(0xe080000f | (intr(r1)<<16) | (intr(r1)<<12)); // add r1,r1,pc
+ o(0xe5900000 | (intr(r1)<<16) | (intr(r2)<<12)); // ldr r2, [r1]
+ o(0xe2900001 | (intr(r2)<<16) | (intr(r2)<<12)); // adds r2, r2, #1
+ o(0xe5800000 | (intr(r1)<<16) | (intr(r2)<<12)); // str r2, [r1]
+ o(0xe2800004 | (intr(r1)<<16) | (intr(r1)<<12)); // add r1, r1, #4
+ o(0xe5900000 | (intr(r1)<<16) | (intr(r2)<<12)); // ldr r2, [r1]
+ o(0xe2a00000 | (intr(r2)<<16) | (intr(r2)<<12)); // adc r2, r2, #0
+ o(0xe5800000 | (intr(r1)<<16) | (intr(r2)<<12)); // str r2, [r1]
+ vpop();
}
/* computed goto support */
-void ggoto(TCCState* S)
+void ggoto(void)
{
- gcall_or_jmp(S, 1);
- S->tccgen_vtop--;
+ gcall_or_jmp(1);
+ vtop--;
}
/* Save the stack pointer onto the stack and return the location of its address */
-ST_FUNC void gen_vla_sp_save(TCCState* S, int addr) {
+ST_FUNC void gen_vla_sp_save(int addr) {
SValue v;
v.type.t = VT_PTR;
v.r = VT_LOCAL | VT_LVAL;
v.c.i = addr;
- store(S, TREG_SP, &v);
+ store(TREG_SP, &v);
}
/* Restore the SP from a location on the stack */
-ST_FUNC void gen_vla_sp_restore(TCCState* S, int addr) {
+ST_FUNC void gen_vla_sp_restore(int addr) {
SValue v;
v.type.t = VT_PTR;
v.r = VT_LOCAL | VT_LVAL;
v.c.i = addr;
- load(S, TREG_SP, &v);
+ load(TREG_SP, &v);
}
/* Subtract from the stack pointer, and push the resulting value onto the stack */
-ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align) {
+ST_FUNC void gen_vla_alloc(CType *type, int align) {
int r;
#if defined(CONFIG_TCC_BCHECK)
- if (S->do_bounds_check)
- vpushv(S, S->tccgen_vtop);
+ if (tcc_state->do_bounds_check)
+ vpushv(vtop);
#endif
- r = intr(S, gv(S, RC_INT));
+ r = intr(gv(RC_INT));
#if defined(CONFIG_TCC_BCHECK)
- if (S->do_bounds_check)
- o(S, 0xe2800001 | (r<<16)|(r<<12)); /* add r,r,#1 */
+ if (tcc_state->do_bounds_check)
+ o(0xe2800001 | (r<<16)|(r<<12)); /* add r,r,#1 */
#endif
- o(S, 0xE04D0000|(r<<12)|r); /* sub r, sp, r */
+ o(0xE04D0000|(r<<12)|r); /* sub r, sp, r */
#ifdef TCC_ARM_EABI
if (align < 8)
align = 8;
@@ -2361,19 +2368,19 @@ ST_FUNC void gen_vla_alloc(TCCState* S, CType *type, int align) {
align = 4;
#endif
if (align & (align - 1))
- tcc_error(S, "alignment is not a power of 2: %i", align);
- o(S, stuff_const(0xE3C0D000|(r<<16), align - 1)); /* bic sp, r, #align-1 */
- vpop(S);
+ tcc_error("alignment is not a power of 2: %i", align);
+ o(stuff_const(0xE3C0D000|(r<<16), align - 1)); /* bic sp, r, #align-1 */
+ vpop();
#if defined(CONFIG_TCC_BCHECK)
- if (S->do_bounds_check) {
- vpushi(S, 0);
- S->tccgen_vtop->r = TREG_R0;
- o(S, 0xe1a0000d | (S->tccgen_vtop->r << 12)); // mov r0,sp
- vswap(S);
- vpush_helper_func(S, TOK___bound_new_region);
- vrott(S, 3);
- gfunc_call(S, 2);
- S->func_bound_add_epilog = 1;
+ if (tcc_state->do_bounds_check) {
+ vpushi(0);
+ vtop->r = TREG_R0;
+ o(0xe1a0000d | (vtop->r << 12)); // mov r0,sp
+ vswap();
+ vpush_helper_func(TOK___bound_new_region);
+ vrott(3);
+ gfunc_call(2);
+ func_bound_add_epilog = 1;
}
#endif
}