Beispiel #1
0
static void assert2_pair_addresses_mapped( msgc_context_t *context, word w )
{
    { 
#ifndef NDEBUG2
      if (isptr(pair_cdr(w)) &&
          ! gc_is_address_mapped( context->gc, 
                                  ptrof(pair_cdr(w)), FALSE )) {
        gc_is_address_mapped( context->gc, ptrof(pair_cdr(w)), TRUE );
        consolemsg("unmapped address, pair 0x%08x in gen %d, cdr = 0x%08x",
                   w, gen_of(w), pair_cdr(w));
        consolemsg("(gno count: %d)", context->gc->gno_count);
        assert2(0);
      }
      if (isptr(pair_car(w)) &&
          ! gc_is_address_mapped( context->gc, 
                                  ptrof(pair_car(w)), FALSE )) {
        gc_is_address_mapped( context->gc, ptrof(pair_car(w)), TRUE );
        consolemsg("unmapped address, pair 0x%08x in gen %d, car = 0x%08x",
                   w, gen_of(w), pair_car(w));
        consolemsg("(gno count: %d)", context->gc->gno_count);
        assert2(0);
      }
#endif
    }
}
Beispiel #2
0
static int compatible(Type ty1, Type ty2) {
	ty1 = unqual(ty1);
	ty2 = unqual(ty2);
	return isptr(ty1) && !isfunc(ty1->type)
	    && isptr(ty2) && !isfunc(ty2->type)
	    && eqtype(unqual(ty1->type), unqual(ty2->type), 0);
}
Beispiel #3
0
Datei: emit.c Projekt: a8m/c
static void
incdec(Node *n)
{
	if(!isitype(n->type) && !isptr(n->type))
		panic("unimplemented incdec");
	addr(n->Incdec.operand);
	pushq("rax");
	load(n->type);
	if(isptr(n->type)) {
		if(n->Incdec.op == TOKINC)
			outi("add $%d, %%rax\n", n->type->Ptr.subty->size);
		else
			outi("add $%d, %%rax\n", -n->type->Ptr.subty->size);
	} else {
		if(n->Incdec.op == TOKINC)
			outi("inc %%rax\n");
		else
			outi("dec %%rax\n");
	}
	outi("movq %%rax, %%rcx\n");
	popq("rax");
	store(n->type);
	outi("movq %%rcx, %%rax\n");
	if(n->Incdec.post == 1) {
		if(n->Incdec.op == TOKINC)
			outi("dec %%rax\n");
		else
			outi("inc %%rax\n");
	}
}
Beispiel #4
0
static Tree addtree(int op, Tree l, Tree r) {
	Type ty = inttype;

	if (isarith(l->type) && isarith(r->type)) {
		ty = binary(l->type, r->type);
		l = cast(l, ty);
		r = cast(r, ty);		
	} else if (isptr(l->type) && isint(r->type))
		return addtree(ADD, r, l);
	else if (  isptr(r->type) && isint(l->type)
	&& !isfunc(r->type->type))
		{
			long n;
			ty = unqual(r->type);
			n = unqual(ty->type)->size;
			if (n == 0)
				error("unknown size for type `%t'\n", ty->type);
			l = cast(l, promote(l->type));
			if (n > 1)
				l = multree(MUL, cnsttree(signedptr, n), l);
			if (isunsigned(l->type))
				l = cast(l, unsignedptr);
			else
				l = cast(l, signedptr);
			if (YYcheck && !isaddrop(r->op))		/* omit */
				return nullcall(ty, YYcheck, r, l);	/* omit */
			return simplify(ADD, ty, l, r);
		}

	else
		typeerror(op, l, r);
	return simplify(op, ty, l, r);
}
Beispiel #5
0
Datei: types.c Projekt: xtao/c
int
isassignable(CTy *to, CTy *from)
{
	if((isarithtype(to) || isptr(to)) &&
		(isarithtype(from) || isptr(from)))
		return 1;
	if(compatiblestruct(to, from))
		return 1;
	return 0;
}
Beispiel #6
0
gint wr_equal_term(glb* g, gint x, gint y, int uniquestrflag) {  
  gptr db;
  gint encx,ency;
  gptr xptr,yptr;
  int xlen,ylen,uselen,i,ilimit;
  gint eqencx; // used by the WR_EQUAL_TERM macro
  
#ifdef DEBUG
  printf("wr_equal_term called with x %d and y %d\n",x,y);
#endif   
  // first check if immediately same: return 1 if yes 
  if (x==y)  return 1; 
  // handle immediate check cases: for these bit suffixes x is equal to y iff x==y   
  encx=(x&NORMALPTRMASK);
  if ((encx==LONGSTRBITS && uniquestrflag) || encx==SMALLINTBITS || encx==NORMALPTRMASK) return 0; 
  // immediate value: must be unequal since x==y checked before
  if (!isptr(x) || !isptr(y)) return 0;
  // here both x and y are ptr types
  // quick type check: last two bits
  if (((x)&NONPTRBITS)!=((y)&NONPTRBITS)) return 0;  
  // if one is datarec, the other must be as well
  if (!isdatarec(x)) {
    if (isdatarec(y)) return 0;
    // neither x nor y are datarecs
    // need to check pointed values
    if (wr_equal_ptr_primitives(g,x,y,uniquestrflag)) return 1;
    else return 0;          
  } else {
    if (!isdatarec(y)) return 0;
    // both x and y are datarecs 
    db=g->db;
    xptr=decode_record(db,x);
    yptr=decode_record(db,y);
    xlen=get_record_len(xptr);
    ylen=get_record_len(yptr);
    if (g->unify_samelen) {
      if (xlen!=ylen) return 0;
      uselen=xlen;      
    } else {
      if (xlen<=ylen) uselen=xlen;
      else uselen=ylen;
    }     
    if (g->unify_maxuseterms) {
      if (((g->unify_maxuseterms)+(g->unify_firstuseterm))<uselen) 
        uselen=(g->unify_firstuseterm)+(g->unify_maxuseterms);
    }    
    ilimit=RECORD_HEADER_GINTS+uselen;
    for(i=RECORD_HEADER_GINTS+(g->unify_firstuseterm); i<ilimit; i++) {
      encx=*(xptr+i);
      ency=*(yptr+i);
      if (!WR_EQUAL_TERM(g,encx,ency,uniquestrflag)) return 0;
    }           
    return 1;        
  }        
}  
Beispiel #7
0
/* Simulation of new write barrier */
void C_simulate_new_barrier( void )
{
  word *genv;
  word lhs;
  word rhs;
  unsigned gl, gr;
  word **ssbtopv, **ssblimv;
  int isvec = 0;

  genv = (word*)globals[ G_GENV ];
  lhs = globals[ G_RESULT ];
  rhs = globals[ G_ARGREG2 ];

  wb_total_assignments++;
  if (tagof(lhs) == VEC_TAG || tagof(lhs) == PROC_TAG) {
    isvec = 1;
    wb_array_assignments++;

    if (genv[pageof(lhs)] == 0) {
      wb_lhs_young_or_remembered++;
      return;
    }
    else if (gc_isremembered( the_gc(globals), lhs )) {
      wb_lhs_young_or_remembered++;
      return;
    }
    else if (!isptr( rhs )) {
      wb_rhs_constant++;
      return;
    }
  }
  else if (!isptr(rhs))
    return;

 record_trans:
  gl = genv[pageof(lhs)];
  gr = genv[pageof(rhs)];
  if (gl <= gr) {
    if (isvec) wb_cross_gen_check++; /* not old->young */
    return;
  }
  if (isvec)
    wb_trans_recorded++;
  ssbtopv = (word**)globals[G_SSBTOPV];
  ssblimv = (word**)globals[G_SSBLIMV];
  *ssbtopv[gl] = lhs;
  ssbtopv[gl] += 1;
  if (ssbtopv[gl] == ssblimv[gl]) C_wb_compact( gl );
}
Beispiel #8
0
/* subtree - construct tree for l - r */
static Tree subtree(int op, Tree l, Tree r) {
	long n;
	Type ty = inttype;

	if (isarith(l->type) && isarith(r->type)) {
		ty = binary(l->type, r->type);
		l = cast(l, ty);
		r = cast(r, ty);		
	} else if (isptr(l->type) && !isfunc(l->type->type) && isint(r->type)) {
		ty = unqual(l->type);
		n = unqual(ty->type)->size;
		if (n == 0)
			error("unknown size for type `%t'\n", ty->type);
		r = cast(r, promote(r->type));
		if (n > 1)
			r = multree(MUL, cnsttree(signedptr, n), r);
		if (isunsigned(r->type))
			r = cast(r, unsignedptr);
		else
			r = cast(r, signedptr);
		return simplify(SUB+P, ty, l, r);
	} else if (compatible(l->type, r->type)) {
		ty = unqual(l->type);
		n = unqual(ty->type)->size;
		if (n == 0)
			error("unknown size for type `%t'\n", ty->type);
		l = simplify(SUB+U, unsignedptr,
			cast(l, unsignedptr), cast(r, unsignedptr));
		return simplify(DIV+I, longtype,
			cast(l, longtype), cnsttree(longtype, n));
	} else
		typeerror(op, l, r);
	return simplify(op, ty, l, r);
}
Beispiel #9
0
Datei: emit.c Projekt: a8m/c
static void
load(CTy *t)
{
	if(isitype(t) || isptr(t)) {
		switch(t->size) {
		case 8:
			outi("movq (%%rax), %%rax\n");
			break;
		case 4:
			outi("movslq (%%rax), %%rax\n");
			break;
		case 2:
			outi("movswq (%%rax), %%rax\n");
			break;
		case 1:
			outi("movsbq (%%rax), %%rax\n");
			break;
		default:
			panic("internal error\n");
		}
		return;
	}
	if(isstruct(t)) {
		return;
	}
	if(isarray(t)) {
		return;
	}
	if(isfunc(t)) {
		return;
	}
	errorf("unimplemented load %d\n", t->t);
}
Beispiel #10
0
Datei: emit.c Projekt: a8m/c
static void
call(Node *n)
{
	int i, nargs, nintargs, cleanup;
	Vec  *args;
	Node *arg;

	args = n->Call.args;
	i = nargs = args->len;
	/* Push args in reverse order */
	while(i-- != 0) {
		arg = vecget(args, i);
		if(!isitype(arg->type) && !isptr(arg->type) && !isarray(arg->type) && !isfunc(arg->type))
			errorposf(&arg->pos, "unimplemented arg type\n");
		expr(arg);
		pushq("rax");
	}
	nintargs = nargs;
	if(nintargs > 6)
		nintargs = 6;
	for(i = 0; i < nintargs; i++)
		popq(intargregs[i]);
	expr(n->Call.funclike);
	outi("call *%%rax\n");
	cleanup = 8 * (nargs - nintargs);
	if(cleanup) {
		outi("add $%d, %%rsp\n", cleanup);
		stackoffset -= cleanup;
	}
}
Beispiel #11
0
Datei: emit.c Projekt: a8m/c
void
emitsym(Sym *sym)
{
	out("# emit sym %s\n", sym->name);
	switch(sym->k){
	case SYMGLOBAL:
		if(sym->Global.sclass == SCEXTERN)
			break;
		if(isfunc(sym->type)) {
			func(sym->init, sym->Global.label, sym->Global.sclass == SCGLOBAL);
			break;
		}
		penddata(sym->Global.label, sym->type, sym->init, sym->Global.sclass == SCGLOBAL);
		break;
	case SYMLOCAL:
		if(sym->init) {
			expr(sym->init);
			pushq("rax");
			outi("leaq %d(%%rbp), %%rax\n", sym->Local.slot->offset);
			popq("rcx");
			if(!isptr(sym->type) && !isitype(sym->type) && !isstruct(sym->type))
				errorf("unimplemented init\n");
			store(sym->type);
		}
		break;
	case SYMENUM:
	case SYMTYPE:
		panic("internal error");
	}
	out("\n");
}
//set a 2 operand reg/??? instruction using the given bytes
void AssemblyInstruction::setreg(int rtype, intptr_t regn, int type2, intptr_t val2,
	string ocbyteconstant, string ocbigconstant, int yy, string ocspecialconstant,
	string ocvalat) {
	//reg/constant
	if (type2 == TCONSTANT) {
		//EAX = AX = AL, all share the special
		if (regn == EAX && ocspecialconstant.length() > 0) {
			if (rtype == TREG8)
				bytes.assign(ocspecialconstant).append(1, (char)(val2));
			else
				bytes.assign(ocspecialconstant).append(rtype == TREG16 ? to2bytes((int)(val2)) : to4bytes((int)(val2)));
		//byte constant with any reg
		} else if (rtype == TREG8 || (val2 >= -128 && val2 <= 127 && ocbyteconstant.compare("") != 0))
			bytes.assign(ocbyteconstant).append(1, (char)(yy + regn)).append(1, (char)(val2));
		//word or dword constant
		else
			bytes.assign(ocbigconstant).append(1, (char)(yy + regn)).append(rtype == TREG16 ? to2bytes((int)(val2)) : to4bytes((int)(val2)));
	//reg/reg
	} else if (isreg(type2))
		bytes.assign(ocvalat).append(1, (char)(0xC0 + regn * 8 + val2));
	//reg/ptr
	else if (isptr(type2))
		bytes.assign(ocvalat).append(((MEMPTR*)(val2))->toptr(0, (char)(regn)));
	//reg/data ptr
	else if (isdataptr(type2)) {
		set(rtype, regn, ptrfromreg(rtype), blankdataptr);
		tag = TAGREGDATAPTR;
		tag2 = val2;
		tag3 = rtype;
		tag4 = regn;
	}
}
Beispiel #13
0
/* Request is ignored -- doesn't make sense in nursery. */
static void collect( young_heap_t *heap, int nbytes, int request )
{
  young_data_t *data = DATA(heap);

  supremely_annoyingmsg( "nursery: promoting (free=%d; request=%d)%s",
			 free_space( heap ), nbytes,
			 (nbytes == 0 ? " [stack overflow]" : "" ) );

#if PROFILE_FOR_FAST_REMSET
  { word *p;
    word *globals = data->globals;
    for ( p=(word*)globals[G_EBOT]; p < (word*)globals[G_ETOP] ; p++ ) {
      nursery.words_scanned++;
      if ((((word)p ^ *p) & BLOCKMASK) == 0)
	nursery.fast_check_succeeds++;
      if (isptr(*p)) {
	nursery.ptrs_scanned++;
	if ((((word)p ^ *p) & BLOCKMASK) == 0)
	  nursery.ptr_same_block++;
      }
    }
  }
#endif
  /* Why did Lars pass 0 instead of nbytes below? */
  gc_collect( heap->collector, data->gen_no, 0, GCTYPE_EVACUATE );
  data->nbytes_wanted = nbytes;  /* For use in after_collection() */
}
Beispiel #14
0
Datei: emit.c Projekt: a8m/c
static void
assign(Node *n)
{
	Node *l, *r;
	int op;

	op = n->Assign.op;
	l = n->Assign.l;
	r = n->Assign.r;
	if(op == '=') {
		expr(r);
		pushq("rax");
		addr(l);
		popq("rcx");
		if(!isptr(l->type) && !isitype(l->type) && !isstruct(l->type))
			errorf("unimplemented assign\n");
		store(l->type);
		outi("movq %%rcx, %%rax\n");
		return;
	}
	addr(l);
	pushq("rax");
	load(l->type);
	pushq("rax");
	expr(r);
	outi("movq %%rax, %%rcx\n");
	popq("rax");
	/* XXX this type is not correct for comparison ops works anyway, but should be changed*/
	obinop(op, n->type);
	outi("movq %%rax, %%rcx\n");
	popq("rax");
	store(l->type);
	outi("movq %%rcx, %%rax\n");
}
Beispiel #15
0
Datei: parse.c Projekt: xtao/c
static Node *
mkunop(SrcPos *p, int op, Node *o)
{
	Node *n;
	
	n = mknode(NUNOP, p);
	n->Unop.op = op;
	switch(op) {
	case '&':
		if(!islval(o))
			errorposf(&o->pos, "& expects an lvalue");
		n->type = mkptr(o->type);
		break;
	case '*':
		if(!isptr(o->type))
			errorposf(&o->pos, "cannot deref non pointer");
		n->type = o->type->Ptr.subty;
		break;
	default:
		o = ipromote(o);
		n->type = o->type;
		break;
	}
	n->Unop.operand = o;
	return n;
}
Beispiel #16
0
void retcode(Tree p) {
	Type ty;

	if (p == NULL) {
		if (events.returns)
			apply(events.returns, cfunc, NULL);
		return;
	}
	p = pointer(p);
	ty = assign(freturn(cfunc->type), p);
	if (ty == NULL) {
		error("illegal return type; found `%t' expected `%t'\n",
			p->type, freturn(cfunc->type));
		return;
	}
	p = cast(p, ty);
	if (retv)
		{
			if (iscallb(p))
				p = tree(RIGHT, p->type,
					tree(CALL+B, p->type,
						p->kids[0]->kids[0], idtree(retv)),
					rvalue(idtree(retv)));
			else {
				Type ty = retv->type->type;
				assert(isstruct(ty));
				if (ty->u.sym->u.s.cfields) {
					ty->u.sym->u.s.cfields = 0;
					p = asgntree(ASGN, rvalue(idtree(retv)), p);
					ty->u.sym->u.s.cfields = 1;
				} else
					p = asgntree(ASGN, rvalue(idtree(retv)), p);
			}
			walk(p, 0, 0);
			if (events.returns)
				apply(events.returns, cfunc, rvalue(idtree(retv)));
			return;
		}
	if (events.returns)
		{
			Symbol t1 = genident(AUTO, p->type, level);
			addlocal(t1);
			walk(asgn(t1, p), 0, 0);
			apply(events.returns, cfunc, idtree(t1));
			p = idtree(t1);
		}
	if (!isfloat(p->type))
		p = cast(p, promote(p->type));
	if (isptr(p->type))
		{
			Symbol q = localaddr(p);
			if (q && (q->computed || q->generated))
				warning("pointer to a %s is an illegal return value\n",
					q->scope == PARAM ? "parameter" : "local");
			else if (q)
				warning("pointer to %s `%s' is an illegal return value\n",
					q->scope == PARAM ? "parameter" : "local", q->name);
		}
	walk(tree(mkop(RET,p->type), p->type, p, NULL), 0, 0);
}
Beispiel #17
0
static void assert2_root_address_mapped( msgc_context_t *context, word *loc )
{
#ifndef NDEBUG2
  if (isptr(*loc) &&
      ! gc_is_address_mapped( context->gc, ptrof(*loc), FALSE )) {
    assert2(0);
  }
#endif
}
//set the DEC
void DEC::set(int type, intptr_t val) {
	if (type == TREG32)
		bytes.assign(1, (char)(0x48 + val));
	else if (type == TREG16)
		bytes.assign("\x66").append(1, (char)(0x48 + val));
	else if (type == TREG8 || isptr(type))
		setregptr(type, val, "\xFF", "\x66\xFF", "\xFE", 8);
	else if (isdataptr(type))
		setdataptr(type, val);
}
Beispiel #19
0
/* dbxout - output .stabs entry for type ty */
static void dbxout(Type ty) {
	ty = unqual(ty);
	if (!ty->x.printed) {
		int col = 0;
		print(".stabs \""), col += 8;
		if (ty->u.sym && !(isfunc(ty) || isarray(ty) || isptr(ty)))
			print("%s", ty->u.sym->name), col += strlen(ty->u.sym->name);
		print(":%c", isstruct(ty) || isenum(ty) ? 'T' : 't'), col += 2;
		emittype(ty, 0, col);
		print("\",%d,0,0,0\n", N_LSYM);
	}
}
Beispiel #20
0
bool msgc_object_marked_p( msgc_context_t *context, word obj )
{
  word bit_idx, word_idx, bit;

  assert2( isptr( obj ) );
  assert2( context->lowest_heap_address <= ptrof( obj ) &&
           ptrof( obj ) < context->highest_heap_address );

  bit_idx = (obj - (word)context->lowest_heap_address) >> BIT_IDX_SHIFT;
  word_idx = bit_idx >> BITS_TO_WORDS;
  bit = 1 << (bit_idx & BIT_IN_WORD_MASK);
  return (context->bitmap[ word_idx ] & bit);
}
Beispiel #21
0
Datei: emit.c Projekt: a8m/c
static void
addr(Node *n)
{
	int sz;
	int offset;
	Sym *sym;
	
	switch(n->t) {
	case NUNOP:
		expr(n->Unop.operand);
		break;
	case NSEL:
		expr(n->Sel.operand);
		if(isptr(n->Sel.operand->type))
			offset = structoffsetfromname(n->Sel.operand->type->Ptr.subty, n->Sel.name);
		else if(isstruct(n->Sel.operand->type))
			offset = structoffsetfromname(n->Sel.operand->type, n->Sel.name);
		else
			panic("internal error");
		if(offset < 0)
			panic("internal error");
		outi("addq $%d, %%rax\n", offset);
		break;
	case NIDENT:
		sym = n->Ident.sym;
		switch(sym->k) {
		case SYMGLOBAL:
			outi("leaq %s(%%rip), %%rax\n", sym->Global.label);
			break;
		case SYMLOCAL:
			outi("leaq %d(%%rbp), %%rax\n", sym->Local.slot->offset);
			break;
		default:
			panic("internal error");
		}
		break;
	case NIDX:
		expr(n->Idx.idx);
		sz = n->type->size;
		if(sz != 1) {
			outi("imul $%d, %%rax\n", sz);
		}
		pushq("rax");
		expr(n->Idx.operand);
		popq("rcx");
		outi("addq %%rcx, %%rax\n");
		break;
	default:
		errorf("unimplemented addr\n");
	}
}
Beispiel #22
0
Datei: simp.c Projekt: pipul/lab
static Tree addrtree(Tree e, long n, Type ty)
{
    Symbol p = e->u.sym, q;

    if (p->scope  == GLOBAL
        ||  p->sclass == STATIC || p->sclass == EXTERN)
        NEW0(q, PERM);
    else
        NEW0(q, FUNC);
    q->name = stringd(genlabel(1));
    q->sclass = p->sclass;
    q->scope = p->scope;
    assert(isptr(ty) || isarray(ty));
    q->type = isptr(ty) ? ty->type : ty;
    q->temporary = p->temporary;
    q->generated = p->generated;
    q->addressed = p->addressed;
    q->computed = 1;
    q->defined = 1;
    q->ref = 1;
    assert(IR->address);
    if (p->scope  == GLOBAL
        ||  p->sclass == STATIC || p->sclass == EXTERN) {
        if (p->sclass == AUTO)
            q->sclass = STATIC;
        (*IR->address)(q, p, n);
    } else {
        Code cp;
        addlocal(p);
        cp = code(Address);
        cp->u.addr.sym = q;
        cp->u.addr.base = p;
        cp->u.addr.offset = n;
    }
    e = tree(e->op, ty, NULL, NULL);
    e->u.sym = q;
    return e;
}
Beispiel #23
0
Tree asgntree(int op, Tree l, Tree r) {
    Type aty, ty;

    r = pointer(r);
    ty = assign(l->type, r);
    if (ty)
        r = cast(r, ty);
    else {
        typeerror(ASGN, l, r);
        if (r->type == voidtype)
            r = retype(r, inttype);
        ty = r->type;
    }
    if (l->op != FIELD)
        l = lvalue(l);
    aty = l->type;
    if (isptr(aty))
        aty = unqual(aty)->type;
    if (isconst(aty)
            || (isstruct(aty) && unqual(aty)->u.sym->u.s.cfields)) {
        if (isaddrop(l->op)
                && !l->u.sym->computed && !l->u.sym->generated)
            error("assignment to const identifier `%s'\n",
                  l->u.sym->name);
        else
            error("assignment to const location\n");
    }
    if (l->op == FIELD) {
        long n = 8 * l->u.field->type->size - fieldsize(l->u.field);
        if (n > 0 && isunsigned(l->u.field->type))
            r = bittree(BAND, r,
                        cnsttree(r->type, (unsigned long)fieldmask(l->u.field)));
        else if (n > 0) {
            if (r->op == CNST + I) {
                n = r->u.v.i;
                if (n & (1 << (fieldsize(l->u.field) - 1)))
                    n |= ~0UL << fieldsize(l->u.field);
                r = cnsttree(r->type, n);
            } else
                r = shtree(RSH,
                           shtree(LSH, r, cnsttree(inttype, n)),
                           cnsttree(inttype, n));
        }
    }
    if (isstruct(ty) && isaddrop(l->op) && iscallb(r))
        return tree(RIGHT, ty,
                    tree(CALL + B, ty, r->kids[0]->kids[0], l),
                    idtree(l->u.sym));
    return tree(mkop(op, ty), ty, l, r);
}
Beispiel #24
0
Datei: emit.c Projekt: a8m/c
static void
data(Data *d)
{
	InitMember *initmemb;
	int   i, offset;
	char *l;
	
	if(!d->init) {
		out(".comm %s, %d, %d\n", d->label, d->type->size, d->type->align);
		return;
	}
	if(d->isglobal)
		out(".globl %s\n", d->label);
	out("%s:\n", d->label);
	
	if(ischararray(d->type))
	if(d->init->t == NSTR) {
		out(".string %s\n", d->init->Str.v);
		return;
	}
	
	if(ischarptr(d->type))
	if(d->init->t == NSTR) {
		l = newlabel();
		out(".quad %s\n", l);
		out("%s:\n", l);
		out(".string %s\n", d->init->Str.v);
		return;
	}
	if(isitype(d->type) || isptr(d->type)) {
		itypedata(d->init);
		return;
	}
	if(isarray(d->type) || isstruct(d->type)) {
		if(d->init->t != NINIT)
			errorposf(&d->init->pos, "array/struct expects a '{' style initializer");
		offset = 0;
		for(i = 0; i < d->init->Init.inits->len ; i++) {
			initmemb = vecget(d->init->Init.inits, i);
			if(initmemb->offset != offset)
				out(".fill %d, 1, 0\n", initmemb->offset - offset);
			itypedata(initmemb->n);
			offset = initmemb->offset + initmemb->n->type->size;
		}
		if(offset < d->type->size)
			out(".fill %d, 1, 0\n", d->type->size - offset);
		return;
	}
	panic("internal error");
}
Beispiel #25
0
Datei: emit.c Projekt: a8m/c
static void
ereturn(Node *r)
{
	CTy *ty;
	
	if(r->Return.expr) {
		ty = r->Return.expr->type;
		if(!isitype(ty) && !isptr(ty))
			errorposf(&r->pos, "unimplemented return type");
		expr(r->Return.expr);
	}
	/* No need to cleanup with leave */
	outi("leave\n");
	outi("ret\n");
}
Beispiel #26
0
Datei: emit.c Projekt: a8m/c
static void
func(Node *f, char *label, int isglobal)
{
	Vec *v;
	Sym *sym;
	int  i;
	
	calcslotoffsets(f);
	out("\n");
	out(".text\n");
	out("# function %s\n", f->Func.name);
	if(isglobal)
		out(".globl %s\n", label);
	out("%s:\n", label);
	pushq("rbp");
	outi("movq %%rsp, %%rbp\n");
	if(f->type->Func.isvararg) {
		stackoffset += 176;
		outi("sub $176, %%rsp\n");
		outi("movq %%rdi, (%%rsp)\n");
		outi("movq %%rsi, 8(%%rsp)\n");
		outi("movq %%rdx, 16(%%rsp)\n");
		outi("movq %%rcx, 24(%%rsp)\n");
		outi("movq %%r8, 32(%%rsp)\n");
		outi("movq %%r9, 40(%%rsp)\n");
	}
	if(f->Func.localsz) {
		outi("sub $%d, %%rsp\n", f->Func.localsz);
		stackoffset += f->Func.localsz;
	}
	v = f->Func.params;
	for(i = 0; i < v->len; i++) {
		sym = vecget(v, i);
		if(!isitype(sym->type) && !isptr(sym->type) && !isarray(sym->type))
			errorposf(&f->pos, "unimplemented arg type");
		if(i < 6) {
			outi("movq %%%s, %d(%%rbp)\n", intargregs[i], sym->Local.slot->offset);
		} else {
			outi("movq %d(%%rbp), %%rcx\n", 16 + 8 * (i - 6));
			outi("leaq %d(%%rbp), %%rax\n", sym->Local.slot->offset);
			store(sym->type);
		}
	}
	block(f->Func.body);
	outi("leave\n");
	outi("ret\n");
}
Beispiel #27
0
static void assert2_object_contents_mapped( msgc_context_t *context, word w, 
                                            int n )
{
#ifndef NDEBUG2
      int i;
      for ( i=0 ; i < n ; i++ ) {
        if (isptr(vector_ref( w, i )) &&
            ! gc_is_address_mapped( context->gc, 
                                    ptrof(vector_ref( w, i )), FALSE )) {
          consolemsg("unmapped address, vector 0x%08x in gen %d, elem [%d] = 0x%08x", 
                     w, gen_of( w ), i, vector_ref( w, i ));
          consolemsg("(gno count: %d)", context->gc->gno_count);
          assert2(0);
        }
      }
#endif
}
Beispiel #28
0
Datei: types.c Projekt: xtao/c
StructMember *
getstructmember(CTy *t, char *n)
{
	int i;
	StructMember *sm;
	
	if(isptr(t))
		t = t->Ptr.subty;
	if(!isstruct(t))
		panic("internal error");
	for(i = 0; i < t->Struct.members->len; i++) {
		sm = vecget(t->Struct.members, i);
		if(strcmp(n, sm->name) == 0)
			return sm;
	}
	return 0;
}
Beispiel #29
0
Datei: emit.c Projekt: a8m/c
static void
itypedata(Node *prim)
{
	Const *c;

	if(!isitype(prim->type) && !isptr(prim->type))
		panic("internal error %d");
	c = foldexpr(prim);
	if(!c)
		errorposf(&prim->pos, "not a constant expression");
	if(c->p) {
		switch(prim->type->size) {
		case 8:
			out(".quad %s + %d\n", c->p, c->v);
			return;
		case 4:
			out(".long %s + %d\n", c->p, c->v);
			return;
		case 2:
			out(".short %s + %d\n", c->p, c->v);
			return;
		case 1:
			out(".byte %s + %d\n", c->p, c->v);
			return;
		default:
			panic("unimplemented");
		}
	}
	switch(prim->type->size) {
	case 8:
		out(".quad %d\n", c->v);
		return;
	case 4:
		out(".long %d\n", c->v);
		return;
	case 2:
		out(".short %d\n", c->v);
		return;
	case 1:
		out(".byte %d\n", c->v);
		return;
	default:
		panic("unimplemented");
	}
	panic("internal error");
}
Beispiel #30
0
/* stabsym - output a stab entry for symbol p */
void stabsym(Symbol p) {
	int code, tc, sz = p->type->size;

	if (p->generated || p->computed)
		return;
	if (isfunc(p->type)) {
		print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name,
			p->sclass == STATIC ? 'f' : 'F', dbxtype(freturn(p->type)),
			N_FUN, p->x.name);
		return;
	}
	if (!IR->wants_argb && p->scope == PARAM && p->structarg) {
		assert(isptr(p->type) && isstruct(p->type->type));
		tc = dbxtype(p->type->type);
		sz = p->type->type->size;
	} else
		tc = dbxtype(p->type);
	if (p->sclass == AUTO && p->scope == GLOBAL || p->sclass == EXTERN) {
		print(".stabs \"%s:G", p->name);
		code = N_GSYM;
	} else if (p->sclass == STATIC) {
		print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name, p->scope == GLOBAL ? 'S' : 'V',
			tc, p->u.seg == BSS ? N_LCSYM : N_STSYM, p->x.name);
		return;
	} else if (p->sclass == REGISTER) {
		if (p->x.regnode) {
			int r = p->x.regnode->number;
			if (p->x.regnode->set == FREG)
				r += 32;	/* floating point */
				print(".stabs \"%s:%c%d\",%d,0,", p->name,
					p->scope == PARAM ? 'P' : 'r', tc, N_RSYM);
			print("%d,%d\n", sz, r);
		}
		return;
	} else if (p->scope == PARAM) {
		print(".stabs \"%s:p", p->name);
		code = N_PSYM;
	} else if (p->scope >= LOCAL) {
		print(".stabs \"%s:", p->name);
		code = N_LSYM;
	} else
		assert(0);
	print("%d\",%d,0,0,%s\n", tc, code,
		p->scope >= PARAM && p->sclass != EXTERN ? p->x.name : "0");
}