Esempio n. 1
0
void
cmdwrite(int wcom, Map *map)
{
	ADDR savdot;
	char *format;
	int pass;

	if (wcom == 'w')
		format = "x";
	else
		format = "X";
	expr(1);
	pass = 0;
	do {
		pass++;  
		savdot=dot;
		exform(1, 1, format, map, 0, pass);
		dot=savdot;
		if (wcom == 'W') {
			if (put4(map, dot, expv) <= 0)
				error(badwrite);
		} else {
			if (put2(map, dot, expv) <= 0)
				error(badwrite);
		}
		savdot=dot;
		dprint("=%8t"); 
		exform(1, 0, format, map, 0, pass);
		newline();
	} while (expr(0));
	dot=savdot;
}
Esempio n. 2
0
/* fix_data -- fix up global refs in the data segment */
void fix_data(uchar *base, int bss) {
     int i, u, v;

     /* Shift BSS symbols by offset bss */
     for (i = 0; i < ndict; i++) {
          symbol s = dict[i];
          if (s->s_seg == BSS) s->s_value += bss;
     }

     /* Fix up each symbol */
     for (i = 0; i < ndict; i++) {
          symbol s = dict[i];
          int val;

          if (s->s_uchain == -1) continue;

          if (dflag > 0) printf("Fixing %s\n", s->s_name);

          val = sym_value(s);

          /* Run along the use chain, inserting the value */
          for (u = s->s_uchain; u != -1; u = v) {
               v = *((int *) &base[u]);
               put4(&base[u], val);
               relocate(u, (s->s_seg == ABS ? R_WORD : R_DATA));
          }
     }
}
Esempio n. 3
0
void
main(int argc, char **argv)
{
	DSApriv *k;
	char *comment;
	uchar buf[8192], *p;
	
	fmtinstall('B', mpfmt);
	fmtinstall('[', encodefmt);
	comment = "";
	ARGBEGIN{
	case 'c':
		comment = EARGF(usage());
		break;
	default:
		usage();
	}ARGEND

	if(argc > 1)
		usage();

	if((k = getdsakey(argc, argv, 0, nil)) == nil)
		sysfatal("%r");

	p = buf;
	p = put4(p, 7);
	p = putn(p, "ssh-dss", 7);
	p = putmp2(p, k->pub.p);
	p = putmp2(p, k->pub.q);
	p = putmp2(p, k->pub.alpha);
	p = putmp2(p, k->pub.key);
	print("ssh-dss %.*[ %s\n", (int)(p - buf), buf, comment);
	exits(nil);
}
Esempio n. 4
0
void
rput(Map *map, char *name, vlong v)
{
	Reglist *rp;
	int ret;

	rp = rname(name);
	if (!rp)
		error("invalid register name");
	if (rp->rflags & RRDONLY)
		error("register is read-only");
	switch (rp->rformat)
	{
	case 'x':
		ret = put2(map, rp->roffs, (ushort) v);
		break;
	case 'X':
	case 'f':
	case 'F':
		ret = put4(map, rp->roffs, (long) v);
		break;
	case 'Y':
		ret = put8(map, rp->roffs, v);
		break;
	default:
		ret = -1;
	}
	if (ret < 0)
		error("can't write register");
}
Esempio n. 5
0
int
puta(Map *map, uvlong addr, uvlong v)
{
	if (mach->szaddr == 8)
		return put8(map, addr, v);

	return put4(map, addr, v);
}
Esempio n. 6
0
int
puta(Map *map, uint64_t addr, uint64_t v)
{
	if (mach->szaddr == 8)
		return put8(map, addr, v);

	return put4(map, addr, v);
}
Esempio n. 7
0
int
puthdr(unsigned char *buf, unsigned long index, unsigned char type, unsigned int tag, unsigned long size) {
    put4(buf, index, size);
    buf[index++] = type;
    put2(buf, index, tag);

    return index;
}
Esempio n. 8
0
void putnetaddr( SPXHeader *l ) {

    putstring( " source" );
    putstring( " net " );
    put4( l->source.network.a );
    putstring( " node " );
    put6( l->source.node.a );
    putstring( " socket " );
    puthex( l->source.socket );
    putstring( "\r\ndestination" );
    putstring( " net " );
    put4( l->destination.network.a );
    putstring( " node " );
    put6( l->destination.node.a );
    putstring( " socket " );
    puthex( l->destination.socket );
    putstring( "\r\n" );
}
Esempio n. 9
0
void putnetaddr( SPX_HEADER *l ) {

    putstring( " source" );
    putstring( " net " );
    put4( (void *)&l->sourceNet );
    putstring( " node " );
    put6( (void *)&l->sourceNode );
    putstring( " socket " );
    puthex( l->sourceSocket );
    putstring( "\r\ndestination" );
    putstring( " net " );
    put4( (void *)&l->destNet );
    putstring( " node " );
    put6( (void *)&l->destNode );
    putstring( " socket " );
    puthex( (void *)&l->destSocket );
    putstring( "\r\n" );
}
Esempio n. 10
0
int
putstat(unsigned char *buffer, unsigned long index, Stat *stat) {
    unsigned int namelen = strlen(stat->name);
    unsigned int uidlen = strlen(stat->uid);
    unsigned int gidlen = strlen(stat->gid);
    unsigned int muidlen = strlen(stat->muid);

    unsigned int size = 2 + 4 + (1 + 4 + 8) + 4 + 4 + 4 + 8 + (2 * 4) + namelen + uidlen + gidlen + muidlen;
    put2(buffer, index, size);

    put2(buffer, index, stat->type);
    put4(buffer, index, stat->dev);
    buffer[index++] = stat->qid.type;
    put4(buffer, index, stat->qid.version);
    put8(buffer, index, stat->qid.path, 0);
    put4(buffer, index, stat->mode);
    put4(buffer, index, stat->atime);
    put4(buffer, index, stat->mtime);
    put8(buffer, index, stat->length, 0);

    put2(buffer, index, namelen);
    memcpy(&buffer[index], stat->name, namelen);
    index += namelen;

    put2(buffer, index, uidlen);
    memcpy(&buffer[index], stat->uid, uidlen);
    index += uidlen;

    put2(buffer, index, gidlen);
    memcpy(&buffer[index], stat->gid, gidlen);
    index += gidlen;

    put2(buffer, index, muidlen);
    memcpy(&buffer[index], stat->muid, muidlen);
    index += muidlen;

    return (size + 2);
}
Esempio n. 11
0
static void
relput4(Prog *p, Adr *a)
{
	vlong v;
	Reloc rel, *r;
	
	v = vaddr(a, &rel);
	if(rel.siz != 0) {
		if(rel.siz != 4)
			diag("bad reloc");
		r = addrel(cursym);
		*r = rel;
		r->off = p->pc + andptr - and;
	}
	put4(v);
}
Esempio n. 12
0
void
main(int argc, char **argv)
{
	RSApriv *k;
	int ssh2;
	char *comment;

	fmtinstall('B', mpfmt);
	fmtinstall('[', encodefmt);

	ssh2 = 0;
	comment = "";

	ARGBEGIN{
	case 'c':
		comment = EARGF(usage());
		break;
	case '2':
		ssh2 = 1;
		break;
	default:
		usage();
	}ARGEND

	if(argc > 1)
		usage();

	if((k = getkey(argc, argv, 0, nil)) == nil)
		sysfatal("%r");

	if(ssh2) {
		uchar buf[8192], *p;

		p = buf;
		p = put4(p, 7);
		p = putn(p, "ssh-rsa", 7);
		p = putmp2(p, k->pub.ek);
		p = putmp2(p, k->pub.n);

		print("ssh-rsa %.*[ %s\n", (int)(p-buf), buf, comment);
	} else {
		print("%d %.10B %.10B %s\n", mpsignif(k->pub.n), k->pub.ek, k->pub.n, comment);
	}

	exits(nil);
}
Esempio n. 13
0
void
savestate(Mach *m, void *buf)
{
	size_t i;

	u8 *p;

	p = buf;
	p += put4(p, m->ac);
	p += put4(p, m->io);
	p += put4(p, m->pc);
	p += put4(p, m->ov);
	for (i = 0; i < nelem(m->mem); i++)
		p += put4(p, m->mem[i]);
	p += putm(p, m->flag, sizeof(m->flag));
	p += putm(p, m->sense, sizeof(m->sense));
	p += put1(p, m->halt);
	for (i = 0; i < nelem(m->sym); i++)
		p += put4(p, m->sym[i]);
}
Esempio n. 14
0
void put6( byte *c )
{
    put4( c );
    put2( c+4 );
}
Esempio n. 15
0
unsigned long
proc9p(unsigned char *msg, unsigned long size, Callbacks *cb) {
    Fcall ifcall;
    Fcall *ofcall = NULL;
    unsigned long slen;
    unsigned long index;
    unsigned char i;

    index = 4;
    ifcall.type = msg[index++];
    get2(msg, index, ifcall.tag);

    if (size > MAX_MSG) {
        strcpy_P(pgmbuf, Etoobig);
        index = mkerr(msg, ifcall.tag, pgmbuf);
        goto END;
    }

    // if it isn't here, it isn't implemented
    switch(ifcall.type) {
    case TVersion:
        i = index;
        index = 7;

        get4(msg, i, ifcall.msize);
        get2(msg, i, slen);

        if (ifcall.msize > MAX_MSG)
            ifcall.msize = MAX_MSG;

        put4(msg, index, ifcall.msize);
        put2(msg, index, slen);

        index += slen;
        puthdr(msg, 0, RVersion, ifcall.tag, index);

        break;
    case TAttach:
        get4(msg, index, ifcall.fid);
        get4(msg, index, ifcall.afid);

        get2(msg, index, slen);
        ifcall.uname = (char*)&msg[index];
        index += slen;

        get2(msg, index, slen);
        msg[index-2] = '\0';

        ifcall.aname = (char*)&msg[index];
        index += slen;
        msg[index-2] = '\0';

        ofcall = cb->attach(&ifcall);

        if (ofcall->type == RError) {
            index = mkerr(msg, ifcall.tag, ofcall->ename);

            goto END;
        }

        index = 7;
        msg[index++] = ofcall->qid.type;
        put4(msg, index, ofcall->qid.version);
        put8(msg, index, ofcall->qid.path, 0);
        puthdr(msg, 0, RAttach, ifcall.tag, index);

        break;
    case TWalk:
        get4(msg, index, ifcall.fid);
        get4(msg, index, ifcall.newfid);
        get2(msg, index, ifcall.nwname);

        if (ifcall.nwname > MAX_WELEM)
            ifcall.nwname = MAX_WELEM;

        for (i = 0; i < ifcall.nwname; i++) {
            get2(msg, index, slen);
            msg[index-2] = '\0';
            ifcall.wname[i] = (char*)&msg[index];
            index += slen;
        }
        msg[index] = '\0';

        ofcall = cb->walk(&ifcall);

        if (ofcall->type == RError) {
            index = mkerr(msg, ifcall.tag, ofcall->ename);

            goto END;
        }

        index = puthdr(msg, 0, RWalk, ifcall.tag, 9 + ofcall->nwqid * 13);
        put2(msg, index, ofcall->nwqid);

        for (i = 0; i < ofcall->nwqid; i++) {
            msg[index++] = ofcall->wqid[i].type;
            put4(msg, index, ofcall->wqid[i].version);
            put8(msg, index, ofcall->wqid[i].path, 0);
        }

        break;
    case TStat:
        get4(msg, index, ifcall.fid);

        ofcall = cb->stat(&ifcall);

        if (ofcall->type == RError) {
            index = mkerr(msg, ifcall.tag, ofcall->ename);

            goto END;
        }

        slen = putstat(msg, 9, &(ofcall->stat));
        index = puthdr(msg, 0, RStat, ifcall.tag, slen + 9);
        put2(msg, index, slen);	// bleh?
        index += slen;

        break;
    case TClunk:
        get4(msg, index, ifcall.fid);

        ofcall = cb->clunk(&ifcall);

        if (ofcall->type == RError) {
            index = mkerr(msg, ifcall.tag, ofcall->ename);

            goto END;
        }

        index = puthdr(msg, 0, RClunk, ifcall.tag, 7);

        break;
    case TOpen:
        get4(msg, index, ifcall.fid);
        ifcall.mode = msg[index++];

        ofcall = cb->open(&ifcall);

        if (ofcall->type == RError) {
            index = mkerr(msg, ifcall.tag, ofcall->ename);

            goto END;
        }

        index = puthdr(msg, 0, ROpen, ifcall.tag, 24);
        msg[index++] = ofcall->qid.type;
        put4(msg, index, ofcall->qid.version);
        put8(msg, index, ofcall->qid.path, 0);
        put4(msg, index, MAX_IO);

        break;
    case TRead:
        get4(msg, index, ifcall.fid);
        get4(msg, index, ifcall.offset);
        index += 4; // :(
        get4(msg, index, ifcall.count);

        ofcall = cb->read(&ifcall, &msg[11]);

        if (ofcall->type == RError) {
            index = mkerr(msg, ifcall.tag, ofcall->ename);

            goto END;
        }

        // No response
        if (ofcall == NULL) {
            index = 0;

            goto END;
        }

        index = puthdr(msg, 0, RRead, ifcall.tag, 11 + ofcall->count);
        put4(msg, index, ofcall->count);
        index += ofcall->count;

        break;
    case TCreate:
        get4(msg, index, ifcall.fid);
        get2(msg, index, slen);
        ifcall.name = (char*)&msg[index];
        index += slen;
        get4(msg, index, ifcall.perm);
        msg[index-4] = '\0';
        ifcall.mode = msg[index++];

        ofcall = cb->create(&ifcall);

        if (ofcall->type == RError) {
            index = mkerr(msg, ifcall.tag, ofcall->ename);

            goto END;
        }

        index = puthdr(msg, 0, RCreate, ifcall.tag, 24);
        msg[index++] = ofcall->qid.type;
        put4(msg, index, ofcall->qid.version);
        put8(msg, index, ofcall->qid.path, 0);
        put4(msg, index, MAX_IO);

        break;
    case TWrite:
        get4(msg, index, ifcall.fid);
        get4(msg, index, ifcall.offset);
        index += 4; // bleh... again
        get4(msg, index, ifcall.count);

        ofcall = cb->write(&ifcall, &msg[index]);

        if (ofcall->type == RError) {
            index = mkerr(msg, ifcall.tag, ofcall->ename);

            goto END;
        }

        index = puthdr(msg, 0, RWrite, ifcall.tag, 11);
        put4(msg, index, ofcall->count);

        break;
    case TRemove:
        get4(msg, index, ifcall.fid);

        ofcall = cb->remove(&ifcall);

        if (ofcall->type == RError) {
            index = mkerr(msg, ifcall.tag, ofcall->ename);

            goto END;
        }

        index = puthdr(msg, 0, RRemove, ifcall.tag, 7);

        break;
    case TFlush:
        get2(msg, index, ifcall.oldtag);

        ofcall = cb->flush(&ifcall);

        if (ofcall->type == RError) {
            index = mkerr(msg, ifcall.tag, ofcall->ename);

            goto END;
        }

        index = puthdr(msg, 0, RFlush, ifcall.tag, 7);

        break;
    default:
        strcpy_P(pgmbuf, Ebadtype);
        index = mkerr(msg, ifcall.tag, pgmbuf);
        break;
    }

END:
    if (index > MAX_MSG) {
        strcpy_P(pgmbuf, Etoobig);
        index = mkerr(msg, ifcall.tag, pgmbuf);
    }

    return index;
}
Esempio n. 16
0
static void
hrprof_finish (void)
{
   struct gmon_hdr ghdr;
   struct gmon_hist_hdr thdr;
   struct gmon_cg_arc_record raw_arc;
   int h;
   struct arc *cp;
   double tsc_secs;
   double tod_secs;
   double charged_secs;
   double end_time;
   unsigned long long charged_ticks;
   unsigned long long used_ticks;
   char from_name[1000], to_name[1000];
   int idx;

   FILE *f;

   if (hrprof_state != 1)
      return;
   hrprof_state = 2;

   end_time = get_time ();
   tod_secs = end_time - start_time;

   if (hrprof_scale_ready == 0) {
      if (tod_secs < 10)
         hrprof_set_scale (1000);
      else
         hrprof_set_scale (1);
   }

   charged_ticks = build_hist ();

   used_ticks = last_tsc - start_tsc;

   charged_secs = charged_ticks / processor_clock;

   tsc_secs = used_ticks / processor_clock;

   remove ("hrprof.out");
   if ((f = fopen ("hrprof.out", "w")) != NULL) {
      fprintf (f, "processor clock %g MHz\n",
          processor_clock / 1000000.0);
      fprintf (f, "secs according to tsc: %g\n", tsc_secs);
      fprintf (f, "secs according to tod: %g\n", tod_secs);
      fprintf (f, "charged secs %g\n", charged_secs);
      fprintf (f, "given out %g\n",
          ticks_given_out / processor_clock);

      fprintf (f, "hist:\n");
      for (idx = 0; idx < kmax_idx; idx++) {
         if (kcount[idx]) {
            void *pc;
            pc = (void *)(idx * HISTFRACTION
                     * sizeof (HISTCOUNTER)
                     + lowpc);
            fprintf (f, "%s %d\n",
                hrprof_sym (from_name, pc),
                kcount[idx]);
         }
      }

      fclose (f);
   }

   remove ("gmon.out");
   if ((f = fopen ("gmon.out", "w")) == NULL)
      return;

   memset (&ghdr, 0, sizeof ghdr);
   memcpy (ghdr.cookie, GMON_MAGIC, sizeof ghdr.cookie);
   put4 (ghdr.version, GMON_VERSION);
   fwrite (&ghdr, 1, sizeof ghdr, f);

   memset (&thdr, 0, sizeof thdr);
   put4 (thdr.low_pc, lowpc);
   put4 (thdr.high_pc, highpc);
   put4 (thdr.hist_size, kcountsize / sizeof (HISTCOUNTER));
   put4 (thdr.prof_rate, profile_rate);
   if (hrprof_scale == 1) {
      strcpy (thdr.dimen, "secs");
      thdr.dimen_abbrev = 's';
   } else {
      strcpy (thdr.dimen, "msecs");
      thdr.dimen_abbrev = 'u';
   }

   putc (GMON_TAG_TIME_HIST, f);
   fwrite (&thdr, 1, sizeof thdr, f);
   fwrite (kcount, 1, kcountsize, f);

   for (h = 0; h < NHASH; h++) {
      for (cp = arc_hash[h]; cp; cp = cp->hash_next) {
         if (hrprof_trace)
            printf ("arc: %s %s %d\n",
               hrprof_sym (from_name, cp->call_site),
               hrprof_sym (to_name, cp->fn_addr),
               cp->count);
         put4 (raw_arc.from_pc,
               (unsigned int)cp->call_site);
         put4 (raw_arc.self_pc,
               (unsigned int)cp->fn_addr);
         put4 (raw_arc.count, cp->count);

         putc (GMON_TAG_CG_ARC, f);
         fwrite (&raw_arc, 1, sizeof raw_arc, f);
      }
   }

   fclose (f);

   free (kcount);
}
Esempio n. 17
0
void
asmand(Adr *a, int r)
{
	int32 v;
	int t, scale;
	Reloc rel;

	v = a->offset;
	t = a->type;
	rel.siz = 0;
	if(a->index != D_NONE && a->index != D_FS && a->index != D_GS) {
		if(t < D_INDIR || t >= 2*D_INDIR) {
			switch(t) {
			default:
				goto bad;
			case D_STATIC:
			case D_EXTERN:
				t = D_NONE;
				v = vaddr(a, &rel);
				break;
			case D_AUTO:
			case D_PARAM:
				t = D_SP;
				break;
			}
		} else
			t -= D_INDIR;

		if(t == D_NONE) {
			*andptr++ = (0 << 6) | (4 << 0) | (r << 3);
			asmidx(a->scale, a->index, t);
			goto putrelv;
		}
		if(v == 0 && rel.siz == 0 && t != D_BP) {
			*andptr++ = (0 << 6) | (4 << 0) | (r << 3);
			asmidx(a->scale, a->index, t);
			return;
		}
		if(v >= -128 && v < 128 && rel.siz == 0) {
			*andptr++ = (1 << 6) | (4 << 0) | (r << 3);
			asmidx(a->scale, a->index, t);
			*andptr++ = v;
			return;
		}
		*andptr++ = (2 << 6) | (4 << 0) | (r << 3);
		asmidx(a->scale, a->index, t);
		goto putrelv;
	}
	if(t >= D_AL && t <= D_F7 || t >= D_X0 && t <= D_X7) {
		if(v)
			goto bad;
		*andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
		return;
	}
	
	scale = a->scale;
	if(t < D_INDIR || t >= 2*D_INDIR) {
		switch(a->type) {
		default:
			goto bad;
		case D_STATIC:
		case D_EXTERN:
			t = D_NONE;
			v = vaddr(a, &rel);
			break;
		case D_AUTO:
		case D_PARAM:
			t = D_SP;
			break;
		}
		scale = 1;
	} else
		t -= D_INDIR;

	if(t == D_NONE || (D_CS <= t && t <= D_GS)) {
		*andptr++ = (0 << 6) | (5 << 0) | (r << 3);
		goto putrelv;
	}
	if(t == D_SP) {
		if(v == 0 && rel.siz == 0) {
			*andptr++ = (0 << 6) | (4 << 0) | (r << 3);
			asmidx(scale, D_NONE, t);
			return;
		}
		if(v >= -128 && v < 128 && rel.siz == 0) {
			*andptr++ = (1 << 6) | (4 << 0) | (r << 3);
			asmidx(scale, D_NONE, t);
			*andptr++ = v;
			return;
		}
		*andptr++ = (2 << 6) | (4 << 0) | (r << 3);
		asmidx(scale, D_NONE, t);
		goto putrelv;
	}
	if(t >= D_AX && t <= D_DI) {
		if(v == 0 && rel.siz == 0 && t != D_BP) {
			*andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
			return;
		}
		if(v >= -128 && v < 128 && rel.siz == 0 && a->index != D_FS && a->index != D_GS) {
			andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
			andptr[1] = v;
			andptr += 2;
			return;
		}
		*andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
		goto putrelv;
	}
	goto bad;

putrelv:
	if(rel.siz != 0) {
		Reloc *r;
		
		if(rel.siz != 4) {
			diag("bad rel");
			goto bad;
		}
		r = addrel(cursym);
		*r = rel;
		r->off = curp->pc + andptr - and;
	} else if(iself && linkmode == LinkExternal && istls(a) && HEADTYPE != Hopenbsd) {
		Reloc *r;
		Sym *s;

		r = addrel(cursym);
		r->off = curp->pc + andptr - and;
		r->add = a->offset-tlsoffset;
		r->xadd = r->add;
		r->siz = 4;
		r->type = D_TLS;
		s = lookup("runtime.tlsgm", 0);
		r->sym = s;
		r->xsym = s;
		v = 0;
	}

	put4(v);
	return;

bad:
	diag("asmand: bad address %D", a);
	return;
}
Esempio n. 18
0
void put6( unsigned char *c )
{
    put4( c );
    put2( c+4 );
}
Esempio n. 19
0
File: span.c Progetto: hfeeki/golang
void
asmand(Adr *a, int r)
{
	int32 v;
	int t, scale;
	Reloc rel;

	v = a->offset;
	t = a->type;
	rel.siz = 0;
	if(a->index != D_NONE) {
		if(t < D_INDIR || t >= 2*D_INDIR) {
			switch(t) {
			default:
				goto bad;
			case D_STATIC:
			case D_EXTERN:
				t = D_NONE;
				v = vaddr(a, &rel);
				break;
			case D_AUTO:
			case D_PARAM:
				t = D_SP;
				break;
			}
		} else
			t -= D_INDIR;

		if(t == D_NONE) {
			*andptr++ = (0 << 6) | (4 << 0) | (r << 3);
			asmidx(a->scale, a->index, t);
			goto putrelv;
		}
		if(v == 0 && rel.siz == 0 && t != D_BP) {
			*andptr++ = (0 << 6) | (4 << 0) | (r << 3);
			asmidx(a->scale, a->index, t);
			return;
		}
		if(v >= -128 && v < 128 && rel.siz == 0) {
			*andptr++ = (1 << 6) | (4 << 0) | (r << 3);
			asmidx(a->scale, a->index, t);
			*andptr++ = v;
			return;
		}
		*andptr++ = (2 << 6) | (4 << 0) | (r << 3);
		asmidx(a->scale, a->index, t);
		goto putrelv;
	}
	if(t >= D_AL && t <= D_F7 || t >= D_X0 && t <= D_X7) {
		if(v)
			goto bad;
		*andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
		return;
	}
	
	scale = a->scale;
	if(t < D_INDIR || t >= 2*D_INDIR) {
		switch(a->type) {
		default:
			goto bad;
		case D_STATIC:
		case D_EXTERN:
			t = D_NONE;
			v = vaddr(a, &rel);
			break;
		case D_AUTO:
		case D_PARAM:
			t = D_SP;
			break;
		}
		scale = 1;
	} else
		t -= D_INDIR;

	if(t == D_NONE || (D_CS <= t && t <= D_GS)) {
		*andptr++ = (0 << 6) | (5 << 0) | (r << 3);
		goto putrelv;
	}
	if(t == D_SP) {
		if(v == 0 && rel.siz == 0) {
			*andptr++ = (0 << 6) | (4 << 0) | (r << 3);
			asmidx(scale, D_NONE, t);
			return;
		}
		if(v >= -128 && v < 128 && rel.siz == 0) {
			*andptr++ = (1 << 6) | (4 << 0) | (r << 3);
			asmidx(scale, D_NONE, t);
			*andptr++ = v;
			return;
		}
		*andptr++ = (2 << 6) | (4 << 0) | (r << 3);
		asmidx(scale, D_NONE, t);
		goto putrelv;
	}
	if(t >= D_AX && t <= D_DI) {
		if(v == 0 && rel.siz == 0 && t != D_BP) {
			*andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
			return;
		}
		if(v >= -128 && v < 128 && rel.siz == 0) {
			andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
			andptr[1] = v;
			andptr += 2;
			return;
		}
		*andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
		goto putrelv;
	}
	goto bad;

putrelv:
	if(rel.siz != 0) {
		Reloc *r;
		
		if(rel.siz != 4) {
			diag("bad rel");
			goto bad;
		}
		r = addrel(cursym);
		*r = rel;
		r->off = curp->pc + andptr - and;
	}
	put4(v);
	return;

bad:
	diag("asmand: bad address %D", a);
	return;
}