changelog shortlog tags branches changeset files file revisions raw help

Mercurial > hg > plan9front / annotate sys/src/cmd/7l/asm.c

changeset 7144: d0b9ab522e8b
child: 34f64dcbbc25
author: cinap_lenrek@felloff.net
date: Mon, 08 Apr 2019 14:05:27 +0200
permissions: -rw-r--r--
description: 7l: add arm64 linker (initial sync)
cinap_lenrek@7144 1
 #include	"l.h"
cinap_lenrek@7144 2
 
cinap_lenrek@7144 3
 long	OFFSET;
cinap_lenrek@7144 4
 
cinap_lenrek@7144 5
 #define PADDR(a)	((a) & ~0xfffffffff0000000ull)
cinap_lenrek@7144 6
 
cinap_lenrek@7144 7
 vlong
cinap_lenrek@7144 8
 entryvalue(void)
cinap_lenrek@7144 9
 {
cinap_lenrek@7144 10
 	char *a;
cinap_lenrek@7144 11
 	Sym *s;
cinap_lenrek@7144 12
 
cinap_lenrek@7144 13
 	a = INITENTRY;
cinap_lenrek@7144 14
 	if(*a >= '0' && *a <= '9')
cinap_lenrek@7144 15
 		return atolwhex(a);
cinap_lenrek@7144 16
 	s = lookup(a, 0);
cinap_lenrek@7144 17
 	if(s->type == 0)
cinap_lenrek@7144 18
 		return INITTEXT;
cinap_lenrek@7144 19
 	switch(s->type) {
cinap_lenrek@7144 20
 	case STEXT:
cinap_lenrek@7144 21
 	case SLEAF:
cinap_lenrek@7144 22
 		break;
cinap_lenrek@7144 23
 	case SDATA:
cinap_lenrek@7144 24
 		if(dlm)
cinap_lenrek@7144 25
 			return s->value+INITDAT;
cinap_lenrek@7144 26
 	default:
cinap_lenrek@7144 27
 		diag("entry not text: %s", s->name);
cinap_lenrek@7144 28
 	}
cinap_lenrek@7144 29
 	return s->value;
cinap_lenrek@7144 30
 }
cinap_lenrek@7144 31
 
cinap_lenrek@7144 32
 void
cinap_lenrek@7144 33
 cflush(void)
cinap_lenrek@7144 34
 {
cinap_lenrek@7144 35
 	int n;
cinap_lenrek@7144 36
 
cinap_lenrek@7144 37
 	n = sizeof(buf.cbuf) - cbc;
cinap_lenrek@7144 38
 	if(n)
cinap_lenrek@7144 39
 		write(cout, buf.cbuf, n);
cinap_lenrek@7144 40
 	cbp = buf.cbuf;
cinap_lenrek@7144 41
 	cbc = sizeof(buf.cbuf);
cinap_lenrek@7144 42
 }
cinap_lenrek@7144 43
 
cinap_lenrek@7144 44
 void
cinap_lenrek@7144 45
 asmb(void)
cinap_lenrek@7144 46
 {
cinap_lenrek@7144 47
 	Prog *p;
cinap_lenrek@7144 48
 	long magic, t, etext;
cinap_lenrek@7144 49
 	vlong vl;
cinap_lenrek@7144 50
 	Optab *o;
cinap_lenrek@7144 51
 
cinap_lenrek@7144 52
 	if(debug['v'])
cinap_lenrek@7144 53
 		Bprint(&bso, "%5.2f asm\n", cputime());
cinap_lenrek@7144 54
 	Bflush(&bso);
cinap_lenrek@7144 55
 	OFFSET = HEADR;
cinap_lenrek@7144 56
 	seek(cout, OFFSET, 0);
cinap_lenrek@7144 57
 	pc = INITTEXT;
cinap_lenrek@7144 58
 	for(p = firstp; p != P; p = p->link) {
cinap_lenrek@7144 59
 		if(p->as == ATEXT) {
cinap_lenrek@7144 60
 			curtext = p;
cinap_lenrek@7144 61
 			autosize = p->to.offset + PCSZ;
cinap_lenrek@7144 62
 		}
cinap_lenrek@7144 63
 		if(p->as == ADWORD && (pc & 7) != 0) {
cinap_lenrek@7144 64
 			lputl(0);
cinap_lenrek@7144 65
 			pc += 4;
cinap_lenrek@7144 66
 		}
cinap_lenrek@7144 67
 		if(p->pc != pc) {
cinap_lenrek@7144 68
 			diag("phase error %llux sb %llux",
cinap_lenrek@7144 69
 				p->pc, pc);
cinap_lenrek@7144 70
 			if(!debug['a'])
cinap_lenrek@7144 71
 				prasm(curp);
cinap_lenrek@7144 72
 			pc = p->pc;
cinap_lenrek@7144 73
 		}
cinap_lenrek@7144 74
 		curp = p;
cinap_lenrek@7144 75
 		o = oplook(p);	/* could probably avoid this call */
cinap_lenrek@7144 76
 		asmout(p, o);
cinap_lenrek@7144 77
 		pc += o->size;
cinap_lenrek@7144 78
 	}
cinap_lenrek@7144 79
 
cinap_lenrek@7144 80
 	if(debug['a'])
cinap_lenrek@7144 81
 		Bprint(&bso, "\n");
cinap_lenrek@7144 82
 	Bflush(&bso);
cinap_lenrek@7144 83
 	cflush();
cinap_lenrek@7144 84
 
cinap_lenrek@7144 85
 	/* output strings in text segment */
cinap_lenrek@7144 86
 	etext = INITTEXT + textsize;
cinap_lenrek@7144 87
 	for(t = pc; t < etext; t += sizeof(buf)-100) {
cinap_lenrek@7144 88
 		if(etext-t > sizeof(buf)-100)
cinap_lenrek@7144 89
 			datblk(t, sizeof(buf)-100, 1);
cinap_lenrek@7144 90
 		else
cinap_lenrek@7144 91
 			datblk(t, etext-t, 1);
cinap_lenrek@7144 92
 	}
cinap_lenrek@7144 93
 
cinap_lenrek@7144 94
 	curtext = P;
cinap_lenrek@7144 95
 	switch(HEADTYPE) {
cinap_lenrek@7144 96
 	case 0:
cinap_lenrek@7144 97
 	case 2:
cinap_lenrek@7144 98
 	case 7:
cinap_lenrek@7144 99
 		OFFSET = HEADR+textsize;
cinap_lenrek@7144 100
 		seek(cout, OFFSET, 0);
cinap_lenrek@7144 101
 		break;
cinap_lenrek@7144 102
 	case 6:	/* no header, padded segments */
cinap_lenrek@7144 103
 		OFFSET = rnd(HEADR+textsize, 4096);
cinap_lenrek@7144 104
 		seek(cout, OFFSET, 0);
cinap_lenrek@7144 105
 		break;
cinap_lenrek@7144 106
 	}
cinap_lenrek@7144 107
 	if(dlm){
cinap_lenrek@7144 108
 		char buf[8];
cinap_lenrek@7144 109
 
cinap_lenrek@7144 110
 		write(cout, buf, INITDAT-textsize);
cinap_lenrek@7144 111
 		textsize = INITDAT;
cinap_lenrek@7144 112
 	}
cinap_lenrek@7144 113
 	for(t = 0; t < datsize; t += sizeof(buf)-100) {
cinap_lenrek@7144 114
 		if(datsize-t > sizeof(buf)-100)
cinap_lenrek@7144 115
 			datblk(t, sizeof(buf)-100, 0);
cinap_lenrek@7144 116
 		else
cinap_lenrek@7144 117
 			datblk(t, datsize-t, 0);
cinap_lenrek@7144 118
 	}
cinap_lenrek@7144 119
 
cinap_lenrek@7144 120
 	symsize = 0;
cinap_lenrek@7144 121
 	lcsize = 0;
cinap_lenrek@7144 122
 	if(!debug['s']) {
cinap_lenrek@7144 123
 		if(debug['v'])
cinap_lenrek@7144 124
 			Bprint(&bso, "%5.2f sym\n", cputime());
cinap_lenrek@7144 125
 		Bflush(&bso);
cinap_lenrek@7144 126
 		switch(HEADTYPE) {
cinap_lenrek@7144 127
 		case 0:
cinap_lenrek@7144 128
 			debug['s'] = 1;
cinap_lenrek@7144 129
 			break;
cinap_lenrek@7144 130
 		case 2:
cinap_lenrek@7144 131
 			OFFSET = HEADR+textsize+datsize;
cinap_lenrek@7144 132
 			seek(cout, OFFSET, 0);
cinap_lenrek@7144 133
 			break;
cinap_lenrek@7144 134
 		case 6:	/* no header, padded segments */
cinap_lenrek@7144 135
 			OFFSET += rnd(datsize, 4096);
cinap_lenrek@7144 136
 			seek(cout, OFFSET, 0);
cinap_lenrek@7144 137
 			break;
cinap_lenrek@7144 138
 		case 7:
cinap_lenrek@7144 139
 			break;
cinap_lenrek@7144 140
 		}
cinap_lenrek@7144 141
 		if(!debug['s'])
cinap_lenrek@7144 142
 			asmsym();
cinap_lenrek@7144 143
 		if(debug['v'])
cinap_lenrek@7144 144
 			Bprint(&bso, "%5.2f pc\n", cputime());
cinap_lenrek@7144 145
 		Bflush(&bso);
cinap_lenrek@7144 146
 		if(!debug['s'])
cinap_lenrek@7144 147
 			asmlc();
cinap_lenrek@7144 148
 		if(dlm)
cinap_lenrek@7144 149
 			asmdyn();
cinap_lenrek@7144 150
 		cflush();
cinap_lenrek@7144 151
 	}
cinap_lenrek@7144 152
 	else if(dlm){
cinap_lenrek@7144 153
 		seek(cout, HEADR+textsize+datsize, 0);
cinap_lenrek@7144 154
 		asmdyn();
cinap_lenrek@7144 155
 		cflush();
cinap_lenrek@7144 156
 	}
cinap_lenrek@7144 157
 
cinap_lenrek@7144 158
 	if(debug['v'])
cinap_lenrek@7144 159
 		Bprint(&bso, "%5.2f header\n", cputime());
cinap_lenrek@7144 160
 	Bflush(&bso);
cinap_lenrek@7144 161
 	OFFSET = 0;
cinap_lenrek@7144 162
 	seek(cout, OFFSET, 0);
cinap_lenrek@7144 163
 	switch(HEADTYPE) {
cinap_lenrek@7144 164
 	case 0:	/* no header */
cinap_lenrek@7144 165
 	case 6:	/* no header, padded segments */
cinap_lenrek@7144 166
 		break;
cinap_lenrek@7144 167
 	case 2:	/* plan 9 */
cinap_lenrek@7144 168
 		magic = 4*28*28+7;
cinap_lenrek@7144 169
 		magic |= 0x00008000;		/* fat header */
cinap_lenrek@7144 170
 		if(dlm)
cinap_lenrek@7144 171
 			magic |= 0x80000000;	/* dlm */
cinap_lenrek@7144 172
 		lput(magic);			/* magic */
cinap_lenrek@7144 173
 		lput(textsize);			/* sizes */
cinap_lenrek@7144 174
 		lput(datsize);
cinap_lenrek@7144 175
 		lput(bsssize);
cinap_lenrek@7144 176
 		lput(symsize);			/* nsyms */
cinap_lenrek@7144 177
 		vl = entryvalue();
cinap_lenrek@7144 178
 		lput(PADDR(vl));		/* va of entry */
cinap_lenrek@7144 179
 		lput(0L);
cinap_lenrek@7144 180
 		lput(lcsize);
cinap_lenrek@7144 181
 		llput(vl);			/* va of entry */
cinap_lenrek@7144 182
 		break;
cinap_lenrek@7144 183
 	}
cinap_lenrek@7144 184
 	cflush();
cinap_lenrek@7144 185
 }
cinap_lenrek@7144 186
 
cinap_lenrek@7144 187
 void
cinap_lenrek@7144 188
 cput(int c)
cinap_lenrek@7144 189
 {
cinap_lenrek@7144 190
 	cbp[0] = c;
cinap_lenrek@7144 191
 	cbp++;
cinap_lenrek@7144 192
 	cbc--;
cinap_lenrek@7144 193
 	if(cbc <= 0)
cinap_lenrek@7144 194
 		cflush();
cinap_lenrek@7144 195
 }
cinap_lenrek@7144 196
 
cinap_lenrek@7144 197
 void
cinap_lenrek@7144 198
 wput(long l)
cinap_lenrek@7144 199
 {
cinap_lenrek@7144 200
 
cinap_lenrek@7144 201
 	cbp[0] = l>>8;
cinap_lenrek@7144 202
 	cbp[1] = l;
cinap_lenrek@7144 203
 	cbp += 2;
cinap_lenrek@7144 204
 	cbc -= 2;
cinap_lenrek@7144 205
 	if(cbc <= 0)
cinap_lenrek@7144 206
 		cflush();
cinap_lenrek@7144 207
 }
cinap_lenrek@7144 208
 
cinap_lenrek@7144 209
 void
cinap_lenrek@7144 210
 wputl(long l)
cinap_lenrek@7144 211
 {
cinap_lenrek@7144 212
 
cinap_lenrek@7144 213
 	cbp[0] = l;
cinap_lenrek@7144 214
 	cbp[1] = l>>8;
cinap_lenrek@7144 215
 	cbp += 2;
cinap_lenrek@7144 216
 	cbc -= 2;
cinap_lenrek@7144 217
 	if(cbc <= 0)
cinap_lenrek@7144 218
 		cflush();
cinap_lenrek@7144 219
 }
cinap_lenrek@7144 220
 
cinap_lenrek@7144 221
 void
cinap_lenrek@7144 222
 lput(long l)
cinap_lenrek@7144 223
 {
cinap_lenrek@7144 224
 
cinap_lenrek@7144 225
 	cbp[0] = l>>24;
cinap_lenrek@7144 226
 	cbp[1] = l>>16;
cinap_lenrek@7144 227
 	cbp[2] = l>>8;
cinap_lenrek@7144 228
 	cbp[3] = l;
cinap_lenrek@7144 229
 	cbp += 4;
cinap_lenrek@7144 230
 	cbc -= 4;
cinap_lenrek@7144 231
 	if(cbc <= 0)
cinap_lenrek@7144 232
 		cflush();
cinap_lenrek@7144 233
 }
cinap_lenrek@7144 234
 
cinap_lenrek@7144 235
 void
cinap_lenrek@7144 236
 lputl(long l)
cinap_lenrek@7144 237
 {
cinap_lenrek@7144 238
 
cinap_lenrek@7144 239
 	cbp[3] = l>>24;
cinap_lenrek@7144 240
 	cbp[2] = l>>16;
cinap_lenrek@7144 241
 	cbp[1] = l>>8;
cinap_lenrek@7144 242
 	cbp[0] = l;
cinap_lenrek@7144 243
 	cbp += 4;
cinap_lenrek@7144 244
 	cbc -= 4;
cinap_lenrek@7144 245
 	if(cbc <= 0)
cinap_lenrek@7144 246
 		cflush();
cinap_lenrek@7144 247
 }
cinap_lenrek@7144 248
 
cinap_lenrek@7144 249
 void
cinap_lenrek@7144 250
 llput(vlong v)
cinap_lenrek@7144 251
 {
cinap_lenrek@7144 252
 	lput(v>>32);
cinap_lenrek@7144 253
 	lput(v);
cinap_lenrek@7144 254
 }
cinap_lenrek@7144 255
 
cinap_lenrek@7144 256
 void
cinap_lenrek@7144 257
 llputl(vlong v)
cinap_lenrek@7144 258
 {
cinap_lenrek@7144 259
 	lputl(v);
cinap_lenrek@7144 260
 	lputl(v>>32);
cinap_lenrek@7144 261
 }
cinap_lenrek@7144 262
 
cinap_lenrek@7144 263
 void
cinap_lenrek@7144 264
 asmsym(void)
cinap_lenrek@7144 265
 {
cinap_lenrek@7144 266
 	Prog *p;
cinap_lenrek@7144 267
 	Auto *a;
cinap_lenrek@7144 268
 	Sym *s;
cinap_lenrek@7144 269
 	int h;
cinap_lenrek@7144 270
 
cinap_lenrek@7144 271
 	s = lookup("etext", 0);
cinap_lenrek@7144 272
 	if(s->type == STEXT)
cinap_lenrek@7144 273
 		putsymb(s->name, 'T', s->value, s->version);
cinap_lenrek@7144 274
 
cinap_lenrek@7144 275
 	for(h=0; h<NHASH; h++)
cinap_lenrek@7144 276
 		for(s=hash[h]; s!=S; s=s->link)
cinap_lenrek@7144 277
 			switch(s->type) {
cinap_lenrek@7144 278
 			case SCONST:
cinap_lenrek@7144 279
 				putsymb(s->name, 'D', s->value, s->version);
cinap_lenrek@7144 280
 				continue;
cinap_lenrek@7144 281
 
cinap_lenrek@7144 282
 			case SDATA:
cinap_lenrek@7144 283
 				putsymb(s->name, 'D', s->value+INITDAT, s->version);
cinap_lenrek@7144 284
 				continue;
cinap_lenrek@7144 285
 
cinap_lenrek@7144 286
 			case SBSS:
cinap_lenrek@7144 287
 				putsymb(s->name, 'B', s->value+INITDAT, s->version);
cinap_lenrek@7144 288
 				continue;
cinap_lenrek@7144 289
 
cinap_lenrek@7144 290
 			case SSTRING:
cinap_lenrek@7144 291
 				putsymb(s->name, 'T', s->value, s->version);
cinap_lenrek@7144 292
 				continue;
cinap_lenrek@7144 293
 
cinap_lenrek@7144 294
 			case SFILE:
cinap_lenrek@7144 295
 				putsymb(s->name, 'f', s->value, s->version);
cinap_lenrek@7144 296
 				continue;
cinap_lenrek@7144 297
 			}
cinap_lenrek@7144 298
 
cinap_lenrek@7144 299
 	for(p=textp; p!=P; p=p->cond) {
cinap_lenrek@7144 300
 		s = p->from.sym;
cinap_lenrek@7144 301
 		if(s->type != STEXT && s->type != SLEAF)
cinap_lenrek@7144 302
 			continue;
cinap_lenrek@7144 303
 
cinap_lenrek@7144 304
 		/* filenames first */
cinap_lenrek@7144 305
 		for(a=p->to.autom; a; a=a->link)
cinap_lenrek@7144 306
 			if(a->type == D_FILE)
cinap_lenrek@7144 307
 				putsymb(a->asym->name, 'z', a->aoffset, 0);
cinap_lenrek@7144 308
 			else
cinap_lenrek@7144 309
 			if(a->type == D_FILE1)
cinap_lenrek@7144 310
 				putsymb(a->asym->name, 'Z', a->aoffset, 0);
cinap_lenrek@7144 311
 
cinap_lenrek@7144 312
 		if(s->type == STEXT)
cinap_lenrek@7144 313
 			putsymb(s->name, 'T', s->value, s->version);
cinap_lenrek@7144 314
 		else
cinap_lenrek@7144 315
 			putsymb(s->name, 'L', s->value, s->version);
cinap_lenrek@7144 316
 
cinap_lenrek@7144 317
 		/* frame, auto and param after */
cinap_lenrek@7144 318
 		putsymb(".frame", 'm', p->to.offset+PCSZ, 0);
cinap_lenrek@7144 319
 		for(a=p->to.autom; a; a=a->link)
cinap_lenrek@7144 320
 			if(a->type == D_AUTO)
cinap_lenrek@7144 321
 				putsymb(a->asym->name, 'a', -a->aoffset, 0);
cinap_lenrek@7144 322
 			else
cinap_lenrek@7144 323
 			if(a->type == D_PARAM)
cinap_lenrek@7144 324
 				putsymb(a->asym->name, 'p', a->aoffset, 0);
cinap_lenrek@7144 325
 	}
cinap_lenrek@7144 326
 	if(debug['v'] || debug['n'])
cinap_lenrek@7144 327
 		Bprint(&bso, "symsize = %lud\n", symsize);
cinap_lenrek@7144 328
 	Bflush(&bso);
cinap_lenrek@7144 329
 }
cinap_lenrek@7144 330
 
cinap_lenrek@7144 331
 void
cinap_lenrek@7144 332
 putsymb(char *s, int t, vlong v, int ver)
cinap_lenrek@7144 333
 {
cinap_lenrek@7144 334
 	int i, f, l;
cinap_lenrek@7144 335
 
cinap_lenrek@7144 336
 	if(t == 'f')
cinap_lenrek@7144 337
 		s++;
cinap_lenrek@7144 338
 	l = 4;
cinap_lenrek@7144 339
 	switch(HEADTYPE){
cinap_lenrek@7144 340
 	default:
cinap_lenrek@7144 341
 		break;
cinap_lenrek@7144 342
 	case 2:
cinap_lenrek@7144 343
 		lput(v>>32);
cinap_lenrek@7144 344
 		l = 8;
cinap_lenrek@7144 345
 		break;
cinap_lenrek@7144 346
 	}
cinap_lenrek@7144 347
 	lput(v);
cinap_lenrek@7144 348
 	if(ver)
cinap_lenrek@7144 349
 		t += 'a' - 'A';
cinap_lenrek@7144 350
 	cput(t+0x80);			/* 0x80 is variable length */
cinap_lenrek@7144 351
 
cinap_lenrek@7144 352
 	if(t == 'Z' || t == 'z') {
cinap_lenrek@7144 353
 		cput(s[0]);
cinap_lenrek@7144 354
 		for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
cinap_lenrek@7144 355
 			cput(s[i]);
cinap_lenrek@7144 356
 			cput(s[i+1]);
cinap_lenrek@7144 357
 		}
cinap_lenrek@7144 358
 		cput(0);
cinap_lenrek@7144 359
 		cput(0);
cinap_lenrek@7144 360
 		i++;
cinap_lenrek@7144 361
 	}
cinap_lenrek@7144 362
 	else {
cinap_lenrek@7144 363
 		for(i=0; s[i]; i++)
cinap_lenrek@7144 364
 			cput(s[i]);
cinap_lenrek@7144 365
 		cput(0);
cinap_lenrek@7144 366
 	}
cinap_lenrek@7144 367
 	symsize += l + 1 + i + 1;
cinap_lenrek@7144 368
 
cinap_lenrek@7144 369
 	if(debug['n']) {
cinap_lenrek@7144 370
 		if(t == 'z' || t == 'Z') {
cinap_lenrek@7144 371
 			Bprint(&bso, "%c %.8llux ", t, v);
cinap_lenrek@7144 372
 			for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
cinap_lenrek@7144 373
 				f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
cinap_lenrek@7144 374
 				Bprint(&bso, "/%x", f);
cinap_lenrek@7144 375
 			}
cinap_lenrek@7144 376
 			Bprint(&bso, "\n");
cinap_lenrek@7144 377
 			return;
cinap_lenrek@7144 378
 		}
cinap_lenrek@7144 379
 		if(ver)
cinap_lenrek@7144 380
 			Bprint(&bso, "%c %.8llux %s<%d>\n", t, v, s, ver);
cinap_lenrek@7144 381
 		else
cinap_lenrek@7144 382
 			Bprint(&bso, "%c %.8llux %s\n", t, v, s);
cinap_lenrek@7144 383
 	}
cinap_lenrek@7144 384
 }
cinap_lenrek@7144 385
 
cinap_lenrek@7144 386
 #define	MINLC	4
cinap_lenrek@7144 387
 void
cinap_lenrek@7144 388
 asmlc(void)
cinap_lenrek@7144 389
 {
cinap_lenrek@7144 390
 	long oldpc, oldlc;
cinap_lenrek@7144 391
 	Prog *p;
cinap_lenrek@7144 392
 	long v, s;
cinap_lenrek@7144 393
 
cinap_lenrek@7144 394
 	oldpc = INITTEXT;
cinap_lenrek@7144 395
 	oldlc = 0;
cinap_lenrek@7144 396
 	for(p = firstp; p != P; p = p->link) {
cinap_lenrek@7144 397
 		if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
cinap_lenrek@7144 398
 			if(p->as == ATEXT)
cinap_lenrek@7144 399
 				curtext = p;
cinap_lenrek@7144 400
 			if(debug['V'])
cinap_lenrek@7144 401
 				Bprint(&bso, "%6llux %P\n",
cinap_lenrek@7144 402
 					p->pc, p);
cinap_lenrek@7144 403
 			continue;
cinap_lenrek@7144 404
 		}
cinap_lenrek@7144 405
 		if(debug['V'])
cinap_lenrek@7144 406
 			Bprint(&bso, "\t\t%6ld", lcsize);
cinap_lenrek@7144 407
 		v = (p->pc - oldpc) / MINLC;
cinap_lenrek@7144 408
 		while(v) {
cinap_lenrek@7144 409
 			s = 127;
cinap_lenrek@7144 410
 			if(v < 127)
cinap_lenrek@7144 411
 				s = v;
cinap_lenrek@7144 412
 			cput(s+128);	/* 129-255 +pc */
cinap_lenrek@7144 413
 			if(debug['V'])
cinap_lenrek@7144 414
 				Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
cinap_lenrek@7144 415
 			v -= s;
cinap_lenrek@7144 416
 			lcsize++;
cinap_lenrek@7144 417
 		}
cinap_lenrek@7144 418
 		s = p->line - oldlc;
cinap_lenrek@7144 419
 		oldlc = p->line;
cinap_lenrek@7144 420
 		oldpc = p->pc + MINLC;
cinap_lenrek@7144 421
 		if(s > 64 || s < -64) {
cinap_lenrek@7144 422
 			cput(0);	/* 0 vv +lc */
cinap_lenrek@7144 423
 			cput(s>>24);
cinap_lenrek@7144 424
 			cput(s>>16);
cinap_lenrek@7144 425
 			cput(s>>8);
cinap_lenrek@7144 426
 			cput(s);
cinap_lenrek@7144 427
 			if(debug['V']) {
cinap_lenrek@7144 428
 				if(s > 0)
cinap_lenrek@7144 429
 					Bprint(&bso, " lc+%ld(%d,%ld)\n",
cinap_lenrek@7144 430
 						s, 0, s);
cinap_lenrek@7144 431
 				else
cinap_lenrek@7144 432
 					Bprint(&bso, " lc%ld(%d,%ld)\n",
cinap_lenrek@7144 433
 						s, 0, s);
cinap_lenrek@7144 434
 				Bprint(&bso, "%6llux %P\n",
cinap_lenrek@7144 435
 					p->pc, p);
cinap_lenrek@7144 436
 			}
cinap_lenrek@7144 437
 			lcsize += 5;
cinap_lenrek@7144 438
 			continue;
cinap_lenrek@7144 439
 		}
cinap_lenrek@7144 440
 		if(s > 0) {
cinap_lenrek@7144 441
 			cput(0+s);	/* 1-64 +lc */
cinap_lenrek@7144 442
 			if(debug['V']) {
cinap_lenrek@7144 443
 				Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
cinap_lenrek@7144 444
 				Bprint(&bso, "%6llux %P\n",
cinap_lenrek@7144 445
 					p->pc, p);
cinap_lenrek@7144 446
 			}
cinap_lenrek@7144 447
 		} else {
cinap_lenrek@7144 448
 			cput(64-s);	/* 65-128 -lc */
cinap_lenrek@7144 449
 			if(debug['V']) {
cinap_lenrek@7144 450
 				Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
cinap_lenrek@7144 451
 				Bprint(&bso, "%6llux %P\n",
cinap_lenrek@7144 452
 					p->pc, p);
cinap_lenrek@7144 453
 			}
cinap_lenrek@7144 454
 		}
cinap_lenrek@7144 455
 		lcsize++;
cinap_lenrek@7144 456
 	}
cinap_lenrek@7144 457
 	while(lcsize & 1) {
cinap_lenrek@7144 458
 		s = 129;
cinap_lenrek@7144 459
 		cput(s);
cinap_lenrek@7144 460
 		lcsize++;
cinap_lenrek@7144 461
 	}
cinap_lenrek@7144 462
 	if(debug['v'] || debug['V'])
cinap_lenrek@7144 463
 		Bprint(&bso, "lcsize = %ld\n", lcsize);
cinap_lenrek@7144 464
 	Bflush(&bso);
cinap_lenrek@7144 465
 }
cinap_lenrek@7144 466
 
cinap_lenrek@7144 467
 void
cinap_lenrek@7144 468
 datblk(long s, long n, int str)
cinap_lenrek@7144 469
 {
cinap_lenrek@7144 470
 	Sym *v;
cinap_lenrek@7144 471
 	Prog *p;
cinap_lenrek@7144 472
 	char *cast;
cinap_lenrek@7144 473
 	long a, l, fl, j;
cinap_lenrek@7144 474
 	vlong d;
cinap_lenrek@7144 475
 	int i, c;
cinap_lenrek@7144 476
 
cinap_lenrek@7144 477
 	memset(buf.dbuf, 0, n+100);
cinap_lenrek@7144 478
 	for(p = datap; p != P; p = p->link) {
cinap_lenrek@7144 479
 		if(str != (p->from.sym->type == SSTRING))
cinap_lenrek@7144 480
 			continue;
cinap_lenrek@7144 481
 		curp = p;
cinap_lenrek@7144 482
 		a = p->from.sym->value + p->from.offset;
cinap_lenrek@7144 483
 		l = a - s;
cinap_lenrek@7144 484
 		c = p->reg;
cinap_lenrek@7144 485
 		i = 0;
cinap_lenrek@7144 486
 		if(l < 0) {
cinap_lenrek@7144 487
 			if(l+c <= 0)
cinap_lenrek@7144 488
 				continue;
cinap_lenrek@7144 489
 			while(l < 0) {
cinap_lenrek@7144 490
 				l++;
cinap_lenrek@7144 491
 				i++;
cinap_lenrek@7144 492
 			}
cinap_lenrek@7144 493
 		}
cinap_lenrek@7144 494
 		if(l >= n)
cinap_lenrek@7144 495
 			continue;
cinap_lenrek@7144 496
 		if(p->as != AINIT && p->as != ADYNT) {
cinap_lenrek@7144 497
 			for(j=l+(c-i)-1; j>=l; j--)
cinap_lenrek@7144 498
 				if(buf.dbuf[j]) {
cinap_lenrek@7144 499
 					print("%P\n", p);
cinap_lenrek@7144 500
 					diag("multiple initialization");
cinap_lenrek@7144 501
 					break;
cinap_lenrek@7144 502
 				}
cinap_lenrek@7144 503
 		}
cinap_lenrek@7144 504
 		switch(p->to.type) {
cinap_lenrek@7144 505
 		default:
cinap_lenrek@7144 506
 			diag("unknown mode in initialization%P", p);
cinap_lenrek@7144 507
 			break;
cinap_lenrek@7144 508
 
cinap_lenrek@7144 509
 		case D_FCONST:
cinap_lenrek@7144 510
 			switch(c) {
cinap_lenrek@7144 511
 			default:
cinap_lenrek@7144 512
 			case 4:
cinap_lenrek@7144 513
 				fl = ieeedtof(p->to.ieee);
cinap_lenrek@7144 514
 				cast = (char*)&fl;
cinap_lenrek@7144 515
 				for(; i<c; i++) {
cinap_lenrek@7144 516
 					buf.dbuf[l] = cast[fnuxi4[i]];
cinap_lenrek@7144 517
 					l++;
cinap_lenrek@7144 518
 				}
cinap_lenrek@7144 519
 				break;
cinap_lenrek@7144 520
 			case 8:
cinap_lenrek@7144 521
 				cast = (char*)p->to.ieee;
cinap_lenrek@7144 522
 				for(; i<c; i++) {
cinap_lenrek@7144 523
 					buf.dbuf[l] = cast[fnuxi8[i]];
cinap_lenrek@7144 524
 					l++;
cinap_lenrek@7144 525
 				}
cinap_lenrek@7144 526
 				break;
cinap_lenrek@7144 527
 			}
cinap_lenrek@7144 528
 			break;
cinap_lenrek@7144 529
 
cinap_lenrek@7144 530
 		case D_SCONST:
cinap_lenrek@7144 531
 			for(; i<c; i++) {
cinap_lenrek@7144 532
 				buf.dbuf[l] = p->to.sval[i];
cinap_lenrek@7144 533
 				l++;
cinap_lenrek@7144 534
 			}
cinap_lenrek@7144 535
 			break;
cinap_lenrek@7144 536
 
cinap_lenrek@7144 537
 		case D_CONST:
cinap_lenrek@7144 538
 			d = p->to.offset;
cinap_lenrek@7144 539
 			v = p->to.sym;
cinap_lenrek@7144 540
 			if(v) {
cinap_lenrek@7144 541
 				switch(v->type) {
cinap_lenrek@7144 542
 				case SUNDEF:
cinap_lenrek@7144 543
 					ckoff(v, d);
cinap_lenrek@7144 544
 				case STEXT:
cinap_lenrek@7144 545
 				case SLEAF:
cinap_lenrek@7144 546
 				case SSTRING:
cinap_lenrek@7144 547
 					d += p->to.sym->value;
cinap_lenrek@7144 548
 					break;
cinap_lenrek@7144 549
 				case SDATA:
cinap_lenrek@7144 550
 				case SBSS:
cinap_lenrek@7144 551
 					d += p->to.sym->value + INITDAT;
cinap_lenrek@7144 552
 				}
cinap_lenrek@7144 553
 				if(dlm)
cinap_lenrek@7144 554
 					dynreloc(v, a+INITDAT, 1);
cinap_lenrek@7144 555
 			}
cinap_lenrek@7144 556
 			cast = (char*)&d;
cinap_lenrek@7144 557
 			switch(c) {
cinap_lenrek@7144 558
 			default:
cinap_lenrek@7144 559
 				diag("bad nuxi %d %d%P", c, i, curp);
cinap_lenrek@7144 560
 				break;
cinap_lenrek@7144 561
 			case 1:
cinap_lenrek@7144 562
 				for(; i<c; i++) {
cinap_lenrek@7144 563
 					buf.dbuf[l] = cast[inuxi1[i]];
cinap_lenrek@7144 564
 					l++;
cinap_lenrek@7144 565
 				}
cinap_lenrek@7144 566
 				break;
cinap_lenrek@7144 567
 			case 2:
cinap_lenrek@7144 568
 				for(; i<c; i++) {
cinap_lenrek@7144 569
 					buf.dbuf[l] = cast[inuxi2[i]];
cinap_lenrek@7144 570
 					l++;
cinap_lenrek@7144 571
 				}
cinap_lenrek@7144 572
 				break;
cinap_lenrek@7144 573
 			case 4:
cinap_lenrek@7144 574
 				for(; i<c; i++) {
cinap_lenrek@7144 575
 					buf.dbuf[l] = cast[inuxi4[i]];
cinap_lenrek@7144 576
 					l++;
cinap_lenrek@7144 577
 				}
cinap_lenrek@7144 578
 				break;
cinap_lenrek@7144 579
 			case 8:
cinap_lenrek@7144 580
 				for(; i<c; i++) {
cinap_lenrek@7144 581
 					buf.dbuf[l] = cast[inuxi8[i]];
cinap_lenrek@7144 582
 					l++;
cinap_lenrek@7144 583
 				}
cinap_lenrek@7144 584
 				break;
cinap_lenrek@7144 585
 			}
cinap_lenrek@7144 586
 			break;
cinap_lenrek@7144 587
 		}
cinap_lenrek@7144 588
 	}
cinap_lenrek@7144 589
 	write(cout, buf.dbuf, n);
cinap_lenrek@7144 590
 }
cinap_lenrek@7144 591
 
cinap_lenrek@7144 592
 static Ieee chipfloats[] = {
cinap_lenrek@7144 593
 	{0x00000000, 0x00000000}, /* 0 */
cinap_lenrek@7144 594
 	{0x00000000, 0x3ff00000}, /* 1 */
cinap_lenrek@7144 595
 	{0x00000000, 0x40000000}, /* 2 */
cinap_lenrek@7144 596
 	{0x00000000, 0x40080000}, /* 3 */
cinap_lenrek@7144 597
 	{0x00000000, 0x40100000}, /* 4 */
cinap_lenrek@7144 598
 	{0x00000000, 0x40140000}, /* 5 */
cinap_lenrek@7144 599
 	{0x00000000, 0x3fe00000}, /* .5 */
cinap_lenrek@7144 600
 	{0x00000000, 0x40240000}, /* 10 */
cinap_lenrek@7144 601
 };
cinap_lenrek@7144 602
 
cinap_lenrek@7144 603
 int
cinap_lenrek@7144 604
 chipfloat(Ieee *e)
cinap_lenrek@7144 605
 {
cinap_lenrek@7144 606
 	Ieee *p;
cinap_lenrek@7144 607
 	int n;
cinap_lenrek@7144 608
 
cinap_lenrek@7144 609
 	for(n = sizeof(chipfloats)/sizeof(chipfloats[0]); --n >= 0;){
cinap_lenrek@7144 610
 		p = &chipfloats[n];
cinap_lenrek@7144 611
 		if(p->l == e->l && p->h == e->h && 0)
cinap_lenrek@7144 612
 			return n;		/* TO DO: return imm8 encoding */
cinap_lenrek@7144 613
 	}
cinap_lenrek@7144 614
 	return -1;
cinap_lenrek@7144 615
 }