changelog shortlog tags branches changeset files file revisions raw help

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

changeset 0: eaccc3e8d226
author: Taru Karttunen <taruti@taruti.net>
date: Wed, 30 Mar 2011 15:46:40 +0300
permissions: -rwxr-xr-x
description: Import sources from 2011-03-30 iso image
taruti@0 1
 #include	"l.h"
taruti@0 2
 
taruti@0 3
 #define	LPUT(c)\
taruti@0 4
 	{\
taruti@0 5
 		cbp[0] = (c);\
taruti@0 6
 		cbp[1] = (c)>>8;\
taruti@0 7
 		cbp[2] = (c)>>16;\
taruti@0 8
 		cbp[3] = (c)>>24;\
taruti@0 9
 		cbp += 4;\
taruti@0 10
 		cbc -= 4;\
taruti@0 11
 		if(cbc <= 0)\
taruti@0 12
 			cflush();\
taruti@0 13
 	}
taruti@0 14
 
taruti@0 15
 #define	CPUT(c)\
taruti@0 16
 	{\
taruti@0 17
 		cbp[0] = (c);\
taruti@0 18
 		cbp++;\
taruti@0 19
 		cbc--;\
taruti@0 20
 		if(cbc <= 0)\
taruti@0 21
 			cflush();\
taruti@0 22
 	}
taruti@0 23
 
taruti@0 24
 #define	VLPUT(c)\
taruti@0 25
 	{\
taruti@0 26
 		cbp[0] = (c);\
taruti@0 27
 		cbp[1] = (c)>>8;\
taruti@0 28
 		cbp[2] = (c)>>16;\
taruti@0 29
 		cbp[3] = (c)>>24;\
taruti@0 30
 		cbp[4] = (c)>>32;\
taruti@0 31
 		cbp[5] = (c)>>40;\
taruti@0 32
 		cbp[6] = (c)>>48;\
taruti@0 33
 		cbp[7] = (c)>>56;\
taruti@0 34
 		cbp += 8;\
taruti@0 35
 		cbc -= 8;\
taruti@0 36
 		if(cbc <= 0)\
taruti@0 37
 			cflush();\
taruti@0 38
 	}
taruti@0 39
 #define	LPUTBE(c)\
taruti@0 40
 	{\
taruti@0 41
 		cbp[0] = (c)>>24;\
taruti@0 42
 		cbp[1] = (c)>>16;\
taruti@0 43
 		cbp[2] = (c)>>8;\
taruti@0 44
 		cbp[3] = (c);\
taruti@0 45
 		cbp += 4;\
taruti@0 46
 		cbc -= 4;\
taruti@0 47
 		if(cbc <= 0)\
taruti@0 48
 			cflush();\
taruti@0 49
 	}
taruti@0 50
 
taruti@0 51
 long
taruti@0 52
 entryvalue(void)
taruti@0 53
 {
taruti@0 54
 	char *a;
taruti@0 55
 	Sym *s;
taruti@0 56
 
taruti@0 57
 	a = INITENTRY;
taruti@0 58
 	if(*a >= '0' && *a <= '9')
taruti@0 59
 		return atolwhex(a);
taruti@0 60
 	s = lookup(a, 0);
taruti@0 61
 	if(s->type == 0)
taruti@0 62
 		return INITTEXT;
taruti@0 63
 	if(s->type != STEXT && s->type != SLEAF)
taruti@0 64
 		diag("entry not text: %s", s->name);
taruti@0 65
 	return s->value;
taruti@0 66
 }
taruti@0 67
 
taruti@0 68
 void
taruti@0 69
 asmb(void)
taruti@0 70
 {
taruti@0 71
 	Prog *p;
taruti@0 72
 	vlong t;
taruti@0 73
 	Optab *o;
taruti@0 74
 
taruti@0 75
 	if(debug['v'])
taruti@0 76
 		Bprint(&bso, "%5.2f asm\n", cputime());
taruti@0 77
 	Bflush(&bso);
taruti@0 78
 	seek(cout, HEADR, 0);
taruti@0 79
 	pc = INITTEXT;
taruti@0 80
 	for(p = firstp; p != P; p = p->link) {
taruti@0 81
 		if(p->as == ATEXT) {
taruti@0 82
 			curtext = p;
taruti@0 83
 			autosize = p->to.offset + 8;
taruti@0 84
 		}
taruti@0 85
 		if(p->pc != pc) {
taruti@0 86
 			diag("phase error %lux sb %lux",
taruti@0 87
 				p->pc, pc);
taruti@0 88
 			if(!debug['a'])
taruti@0 89
 				prasm(curp);
taruti@0 90
 			pc = p->pc;
taruti@0 91
 		}
taruti@0 92
 		if (p->as == AMOVQ || p->as == AMOVT) {
taruti@0 93
 			if ((p->from.reg == REGSP) && (p->from.offset&7) != 0
taruti@0 94
 			|| (p->to.reg == REGSP) && (p->to.offset&7) != 0)
taruti@0 95
 				diag("bad stack alignment: %P", p);
taruti@0 96
 			if ((p->from.reg == REGSB) && (p->from.offset&7) != 0
taruti@0 97
 			|| (p->to.reg == REGSB) && (p->to.offset&7) != 0)
taruti@0 98
 				diag("bad global alignment: %P", p);
taruti@0 99
 		}
taruti@0 100
 		curp = p;
taruti@0 101
 		o = oplook(p);	/* could probably avoid this call */
taruti@0 102
 		if(asmout(p, o)) {
taruti@0 103
 			p = p->link;
taruti@0 104
 			pc += 4;
taruti@0 105
 		}
taruti@0 106
 		pc += o->size;
taruti@0 107
 	}
taruti@0 108
 	if(debug['a'])
taruti@0 109
 		Bprint(&bso, "\n");
taruti@0 110
 	Bflush(&bso);
taruti@0 111
 	cflush();
taruti@0 112
 
taruti@0 113
 	curtext = P;
taruti@0 114
 	switch(HEADTYPE) {
taruti@0 115
 	case 0:
taruti@0 116
 		seek(cout, rnd(HEADR+textsize, 8192), 0);
taruti@0 117
 		break;
taruti@0 118
 	case 1:
taruti@0 119
 	case 2:
taruti@0 120
 	case 3:
taruti@0 121
 		seek(cout, HEADR+textsize, 0);
taruti@0 122
 		break;
taruti@0 123
 	}
taruti@0 124
 	for(t = 0; t < datsize; t += sizeof(buf)-100) {
taruti@0 125
 		if(datsize-t > sizeof(buf)-100)
taruti@0 126
 			datblk(t, sizeof(buf)-100);
taruti@0 127
 		else
taruti@0 128
 			datblk(t, datsize-t);
taruti@0 129
 	}
taruti@0 130
 
taruti@0 131
 	symsize = 0;
taruti@0 132
 	lcsize = 0;
taruti@0 133
 	if(!debug['s']) {
taruti@0 134
 		if(debug['v'])
taruti@0 135
 			Bprint(&bso, "%5.2f sym\n", cputime());
taruti@0 136
 		Bflush(&bso);
taruti@0 137
 		switch(HEADTYPE) {
taruti@0 138
 		case 0:
taruti@0 139
 			seek(cout, rnd(HEADR+textsize, 8192)+datsize, 0);
taruti@0 140
 			break;
taruti@0 141
 		case 2:
taruti@0 142
 		case 1:
taruti@0 143
 		case 3:
taruti@0 144
 			seek(cout, HEADR+textsize+datsize, 0);
taruti@0 145
 			break;
taruti@0 146
 		}
taruti@0 147
 		if(!debug['s'])
taruti@0 148
 			asmsym();
taruti@0 149
 		if(debug['v'])
taruti@0 150
 			Bprint(&bso, "%5.2f pc\n", cputime());
taruti@0 151
 		Bflush(&bso);
taruti@0 152
 		if(!debug['s'])
taruti@0 153
 			asmlc();
taruti@0 154
 		cflush();
taruti@0 155
 	}
taruti@0 156
 
taruti@0 157
 	if(debug['v'])
taruti@0 158
 		Bprint(&bso, "%5.2f header\n", cputime());
taruti@0 159
 	Bflush(&bso);
taruti@0 160
 	seek(cout, 0L, 0);
taruti@0 161
 	switch(HEADTYPE) {
taruti@0 162
 	case 0:
taruti@0 163
 		lput(0x0183L);		/* magic and sections */
taruti@0 164
 		lput(0L);			/* time and date */
taruti@0 165
 		vlput(rnd(HEADR+textsize, 8192)+datsize);
taruti@0 166
 		lput(symsize);			/* nsyms */
taruti@0 167
 		lput(0x50L|(7L<<16));		/* size of optional hdr and flags */
taruti@0 168
 		lput(0413|(0x101L<<16));	/* magic and version */
taruti@0 169
 		lput(-1);			/* pad for alignment */
taruti@0 170
 
taruti@0 171
 		vlput(rnd(HEADR+textsize, 8192));		/* sizes */
taruti@0 172
 		vlput(datsize);
taruti@0 173
 		vlput(bsssize);
taruti@0 174
 		vlput(entryvalue());		/* va of entry */
taruti@0 175
 		vlput(INITTEXT-HEADR);		/* va of base of text */
taruti@0 176
 		vlput(INITDAT);			/* va of base of data */
taruti@0 177
 		vlput(INITDAT+datsize);		/* va of base of bss */
taruti@0 178
 		lput(~0L);			/* gp reg mask */
taruti@0 179
 		/* dubious stuff starts here */
taruti@0 180
 		lput(0L);
taruti@0 181
 		lput(0L);
taruti@0 182
 		lput(0L);
taruti@0 183
 		lput(0L);
taruti@0 184
 		lput(~0L);			/* gp value ?? */
taruti@0 185
 		break;
taruti@0 186
 	case 1:
taruti@0 187
 		lput(0x0183L);		/* magic and sections */
taruti@0 188
 		lput(0L);			/* time and date */
taruti@0 189
 		vlput(HEADR+textsize+datsize);
taruti@0 190
 		lput(symsize);			/* nsyms */
taruti@0 191
 		lput(0x54L|(7L<<16));		/* size of optional hdr and flags */
taruti@0 192
 		lput(0407|(0x101L<<16));	/* magic and version */
taruti@0 193
 		lput(-1);			/* pad for alignment */
taruti@0 194
 
taruti@0 195
 		vlput(textsize);		/* sizes */
taruti@0 196
 		vlput(datsize);
taruti@0 197
 		vlput(bsssize);
taruti@0 198
 		vlput(entryvalue());		/* va of entry */
taruti@0 199
 		vlput(INITTEXT);		/* va of base of text */
taruti@0 200
 		vlput(INITDAT);			/* va of base of data */
taruti@0 201
 		vlput(INITDAT+datsize);		/* va of base of bss */
taruti@0 202
 		lput(~0L);			/* gp reg mask */
taruti@0 203
 		/* dubious stuff starts here */
taruti@0 204
 		lput(lcsize);
taruti@0 205
 		lput(0L);
taruti@0 206
 		lput(0L);
taruti@0 207
 		lput(0L);
taruti@0 208
 		lput(~0L);			/* gp value ?? */
taruti@0 209
 		lput(0L);			/* complete mystery */
taruti@0 210
 		break;
taruti@0 211
 	case 2:
taruti@0 212
 		lputbe(0x84b);			/* magic */
taruti@0 213
 		lputbe(textsize);		/* sizes */
taruti@0 214
 		lputbe(datsize);
taruti@0 215
 		lputbe(bsssize);
taruti@0 216
 		lputbe(symsize);		/* nsyms */
taruti@0 217
 		lputbe(entryvalue());		/* va of entry */
taruti@0 218
 		lputbe(0L);
taruti@0 219
 		lputbe(lcsize);
taruti@0 220
 		break;
taruti@0 221
 	case 3:
taruti@0 222
 		/* ``headerless'' boot image -- magic no is a branch */
taruti@0 223
 		lput(0xc3e00007);		/* magic (branch) */
taruti@0 224
 		lputbe(textsize);		/* sizes */
taruti@0 225
 		lputbe(datsize);
taruti@0 226
 		lputbe(bsssize);
taruti@0 227
 		lputbe(symsize);		/* nsyms */
taruti@0 228
 		lputbe(entryvalue());		/* va of entry */
taruti@0 229
 		lputbe(0L);
taruti@0 230
 		lputbe(lcsize);
taruti@0 231
 		break;
taruti@0 232
 	}
taruti@0 233
 	cflush();
taruti@0 234
 }
taruti@0 235
 
taruti@0 236
 void
taruti@0 237
 lput(long l)
taruti@0 238
 {
taruti@0 239
 	LPUT(l);
taruti@0 240
 }
taruti@0 241
 
taruti@0 242
 void
taruti@0 243
 lputbe(long l)
taruti@0 244
 {
taruti@0 245
 	LPUTBE(l);
taruti@0 246
 }
taruti@0 247
 
taruti@0 248
 void
taruti@0 249
 vlput(vlong l)
taruti@0 250
 {
taruti@0 251
 	VLPUT(l);
taruti@0 252
 }
taruti@0 253
 
taruti@0 254
 void
taruti@0 255
 cflush(void)
taruti@0 256
 {
taruti@0 257
 	int n;
taruti@0 258
 
taruti@0 259
 	n = sizeof(buf.cbuf) - cbc;
taruti@0 260
 	if(n)
taruti@0 261
 		write(cout, buf.cbuf, n);
taruti@0 262
 	cbp = buf.cbuf;
taruti@0 263
 	cbc = sizeof(buf.cbuf);
taruti@0 264
 }
taruti@0 265
 
taruti@0 266
 void
taruti@0 267
 asmsym(void)
taruti@0 268
 {
taruti@0 269
 	Prog *p;
taruti@0 270
 	Auto *a;
taruti@0 271
 	Sym *s;
taruti@0 272
 	int h;
taruti@0 273
 
taruti@0 274
 	s = lookup("etext", 0);
taruti@0 275
 	if(s->type == STEXT)
taruti@0 276
 		putsymb(s->name, 'T', s->value, s->version);
taruti@0 277
 
taruti@0 278
 	for(h=0; h<NHASH; h++)
taruti@0 279
 		for(s=hash[h]; s!=S; s=s->link)
taruti@0 280
 			switch(s->type) {
taruti@0 281
 			case SCONST:
taruti@0 282
 				putsymb(s->name, 'D', s->value, s->version);
taruti@0 283
 				continue;
taruti@0 284
 
taruti@0 285
 			case SDATA:
taruti@0 286
 				putsymb(s->name, 'D', s->value+INITDAT, s->version);
taruti@0 287
 				continue;
taruti@0 288
 
taruti@0 289
 			case SBSS:
taruti@0 290
 				putsymb(s->name, 'B', s->value+INITDAT, s->version);
taruti@0 291
 				continue;
taruti@0 292
 
taruti@0 293
 			case SFILE:
taruti@0 294
 				putsymb(s->name, 'f', s->value, s->version);
taruti@0 295
 				continue;
taruti@0 296
 			}
taruti@0 297
 
taruti@0 298
 	for(p=textp; p!=P; p=p->cond) {
taruti@0 299
 		s = p->from.sym;
taruti@0 300
 		if(s->type != STEXT && s->type != SLEAF)
taruti@0 301
 			continue;
taruti@0 302
 
taruti@0 303
 		/* filenames first */
taruti@0 304
 		for(a=p->to.autom; a; a=a->link)
taruti@0 305
 			if(a->type == D_FILE)
taruti@0 306
 				putsymb(a->sym->name, 'z', a->offset, 0);
taruti@0 307
 			else
taruti@0 308
 			if(a->type == D_FILE1)
taruti@0 309
 				putsymb(a->sym->name, 'Z', a->offset, 0);
taruti@0 310
 
taruti@0 311
 		if(s->type == STEXT)
taruti@0 312
 			putsymb(s->name, 'T', s->value, s->version);
taruti@0 313
 		else
taruti@0 314
 			putsymb(s->name, 'L', s->value, s->version);
taruti@0 315
 
taruti@0 316
 		/* frame, auto and param after */
taruti@0 317
 		putsymb(".frame", 'm', p->to.offset+8, 0);
taruti@0 318
 		for(a=p->to.autom; a; a=a->link)
taruti@0 319
 			if(a->type == D_AUTO)
taruti@0 320
 				putsymb(a->sym->name, 'a', -a->offset, 0);
taruti@0 321
 			else
taruti@0 322
 			if(a->type == D_PARAM)
taruti@0 323
 				putsymb(a->sym->name, 'p', a->offset, 0);
taruti@0 324
 	}
taruti@0 325
 	if(debug['v'] || debug['n'])
taruti@0 326
 		Bprint(&bso, "symsize = %lud\n", symsize);
taruti@0 327
 	Bflush(&bso);
taruti@0 328
 }
taruti@0 329
 
taruti@0 330
 void
taruti@0 331
 putsymb(char *s, int t, long v, int ver)
taruti@0 332
 {
taruti@0 333
 	int i, f;
taruti@0 334
 
taruti@0 335
 	if(t == 'f')
taruti@0 336
 		s++;
taruti@0 337
 	LPUTBE(v);
taruti@0 338
 	if(ver)
taruti@0 339
 		t += 'a' - 'A';
taruti@0 340
 	CPUT(t+0x80);			/* 0x80 is variable length */
taruti@0 341
 
taruti@0 342
 	if(t == 'Z' || t == 'z') {
taruti@0 343
 		CPUT(s[0]);
taruti@0 344
 		for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
taruti@0 345
 			CPUT(s[i]);
taruti@0 346
 			CPUT(s[i+1]);
taruti@0 347
 		}
taruti@0 348
 		CPUT(0);
taruti@0 349
 		CPUT(0);
taruti@0 350
 		i++;
taruti@0 351
 	}
taruti@0 352
 	else {
taruti@0 353
 		for(i=0; s[i]; i++)
taruti@0 354
 			CPUT(s[i]);
taruti@0 355
 		CPUT(0);
taruti@0 356
 	}
taruti@0 357
 	symsize += 4 + 1 + i + 1;
taruti@0 358
 
taruti@0 359
 	if(debug['n']) {
taruti@0 360
 		if(t == 'z' || t == 'Z') {
taruti@0 361
 			Bprint(&bso, "%c %.8lux ", t, v);
taruti@0 362
 			for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
taruti@0 363
 				f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
taruti@0 364
 				Bprint(&bso, "/%x", f);
taruti@0 365
 			}
taruti@0 366
 			Bprint(&bso, "\n");
taruti@0 367
 			return;
taruti@0 368
 		}
taruti@0 369
 		if(ver)
taruti@0 370
 			Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
taruti@0 371
 		else
taruti@0 372
 			Bprint(&bso, "%c %.8lux %s\n", t, v, s);
taruti@0 373
 	}
taruti@0 374
 }
taruti@0 375
 
taruti@0 376
 #define	MINLC	4
taruti@0 377
 void
taruti@0 378
 asmlc(void)
taruti@0 379
 {
taruti@0 380
 	long oldpc, oldlc;
taruti@0 381
 	Prog *p;
taruti@0 382
 	long v, s;
taruti@0 383
 
taruti@0 384
 	oldpc = INITTEXT;
taruti@0 385
 	oldlc = 0;
taruti@0 386
 	for(p = firstp; p != P; p = p->link) {
taruti@0 387
 		if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
taruti@0 388
 			if(p->as == ATEXT)
taruti@0 389
 				curtext = p;
taruti@0 390
 			if(debug['L'])
taruti@0 391
 				Bprint(&bso, "%6lux %P\n",
taruti@0 392
 					p->pc, p);
taruti@0 393
 			continue;
taruti@0 394
 		}
taruti@0 395
 		if(debug['L'])
taruti@0 396
 			Bprint(&bso, "\t\t%6ld", lcsize);
taruti@0 397
 		v = (p->pc - oldpc) / MINLC;
taruti@0 398
 		while(v) {
taruti@0 399
 			s = 127;
taruti@0 400
 			if(v < 127)
taruti@0 401
 				s = v;
taruti@0 402
 			CPUT(s+128);	/* 129-255 +pc */
taruti@0 403
 			if(debug['L'])
taruti@0 404
 				Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
taruti@0 405
 			v -= s;
taruti@0 406
 			lcsize++;
taruti@0 407
 		}
taruti@0 408
 		s = p->line - oldlc;
taruti@0 409
 		oldlc = p->line;
taruti@0 410
 		oldpc = p->pc + MINLC;
taruti@0 411
 		if(s > 64 || s < -64) {
taruti@0 412
 			CPUT(0);	/* 0 vv +lc */
taruti@0 413
 			CPUT(s>>24);
taruti@0 414
 			CPUT(s>>16);
taruti@0 415
 			CPUT(s>>8);
taruti@0 416
 			CPUT(s);
taruti@0 417
 			if(debug['L']) {
taruti@0 418
 				if(s > 0)
taruti@0 419
 					Bprint(&bso, " lc+%ld(%d,%ld)\n",
taruti@0 420
 						s, 0, s);
taruti@0 421
 				else
taruti@0 422
 					Bprint(&bso, " lc%ld(%d,%ld)\n",
taruti@0 423
 						s, 0, s);
taruti@0 424
 				Bprint(&bso, "%6lux %P\n",
taruti@0 425
 					p->pc, p);
taruti@0 426
 			}
taruti@0 427
 			lcsize += 5;
taruti@0 428
 			continue;
taruti@0 429
 		}
taruti@0 430
 		if(s > 0) {
taruti@0 431
 			CPUT(0+s);	/* 1-64 +lc */
taruti@0 432
 			if(debug['L']) {
taruti@0 433
 				Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
taruti@0 434
 				Bprint(&bso, "%6lux %P\n",
taruti@0 435
 					p->pc, p);
taruti@0 436
 			}
taruti@0 437
 		} else {
taruti@0 438
 			CPUT(64-s);	/* 65-128 -lc */
taruti@0 439
 			if(debug['L']) {
taruti@0 440
 				Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
taruti@0 441
 				Bprint(&bso, "%6lux %P\n",
taruti@0 442
 					p->pc, p);
taruti@0 443
 			}
taruti@0 444
 		}
taruti@0 445
 		lcsize++;
taruti@0 446
 	}
taruti@0 447
 	while(lcsize & 1) {
taruti@0 448
 		s = 129;
taruti@0 449
 		CPUT(s);
taruti@0 450
 		lcsize++;
taruti@0 451
 	}
taruti@0 452
 	if(debug['v'] || debug['L'])
taruti@0 453
 		Bprint(&bso, "lcsize = %ld\n", lcsize);
taruti@0 454
 	Bflush(&bso);
taruti@0 455
 }
taruti@0 456
 
taruti@0 457
 void
taruti@0 458
 datblk(long s, long n)
taruti@0 459
 {
taruti@0 460
 	Prog *p;
taruti@0 461
 	char *cast;
taruti@0 462
 	long l, fl, j, d;
taruti@0 463
 	int i, c;
taruti@0 464
 
taruti@0 465
 	memset(buf.dbuf, 0, n+100);
taruti@0 466
 	for(p = datap; p != P; p = p->link) {
taruti@0 467
 		curp = p;
taruti@0 468
 		l = p->from.sym->value + p->from.offset - s;
taruti@0 469
 		c = p->reg;
taruti@0 470
 		i = 0;
taruti@0 471
 		if(l < 0) {
taruti@0 472
 			if(l+c <= 0)
taruti@0 473
 				continue;
taruti@0 474
 			while(l < 0) {
taruti@0 475
 				l++;
taruti@0 476
 				i++;
taruti@0 477
 			}
taruti@0 478
 		}
taruti@0 479
 		if(l >= n)
taruti@0 480
 			continue;
taruti@0 481
 		if(p->as != AINIT && p->as != ADYNT) {
taruti@0 482
 			for(j=l+(c-i)-1; j>=l; j--)
taruti@0 483
 				if(buf.dbuf[j]) {
taruti@0 484
 					print("%P\n", p);
taruti@0 485
 					diag("multiple initialization");
taruti@0 486
 					break;
taruti@0 487
 				}
taruti@0 488
 		}
taruti@0 489
 		switch(p->to.type) {
taruti@0 490
 		default:
taruti@0 491
 			diag("unknown mode in initialization\n%P", p);
taruti@0 492
 			break;
taruti@0 493
 
taruti@0 494
 		case D_FCONST:
taruti@0 495
 			switch(c) {
taruti@0 496
 			default:
taruti@0 497
 			case 4:
taruti@0 498
 				fl = ieeedtof(p->to.ieee);
taruti@0 499
 				cast = (char*)&fl;
taruti@0 500
 				for(; i<c; i++) {
taruti@0 501
 					buf.dbuf[l] = cast[fnuxi8[i]];
taruti@0 502
 					l++;
taruti@0 503
 				}
taruti@0 504
 				break;
taruti@0 505
 			case 8:
taruti@0 506
 				cast = (char*)p->to.ieee;
taruti@0 507
 				for(; i<c; i++) {
taruti@0 508
 					buf.dbuf[l] = cast[fnuxi8[i]];
taruti@0 509
 					l++;
taruti@0 510
 				}
taruti@0 511
 				break;
taruti@0 512
 			}
taruti@0 513
 			break;
taruti@0 514
 
taruti@0 515
 		case D_SCONST:
taruti@0 516
 			for(; i<c; i++) {
taruti@0 517
 				buf.dbuf[l] = p->to.sval[i];
taruti@0 518
 				l++;
taruti@0 519
 			}
taruti@0 520
 			break;
taruti@0 521
 
taruti@0 522
 		case D_CONST:
taruti@0 523
 			d = p->to.offset;
taruti@0 524
 			if(p->to.sym) {
taruti@0 525
 				if(p->to.sym->type == STEXT ||
taruti@0 526
 				   p->to.sym->type == SLEAF)
taruti@0 527
 					d += p->to.sym->value;
taruti@0 528
 				if(p->to.sym->type == SDATA)
taruti@0 529
 					d += p->to.sym->value + INITDAT;
taruti@0 530
 				if(p->to.sym->type == SBSS)
taruti@0 531
 					d += p->to.sym->value + INITDAT;
taruti@0 532
 			}
taruti@0 533
 			cast = (char*)&d;
taruti@0 534
 			switch(c) {
taruti@0 535
 			default:
taruti@0 536
 				diag("bad nuxi %d %d\n%P", c, i, curp);
taruti@0 537
 				break;
taruti@0 538
 			case 1:
taruti@0 539
 				for(; i<c; i++) {
taruti@0 540
 					buf.dbuf[l] = cast[inuxi1[i]];
taruti@0 541
 					l++;
taruti@0 542
 				}
taruti@0 543
 				break;
taruti@0 544
 			case 2:
taruti@0 545
 				for(; i<c; i++) {
taruti@0 546
 					buf.dbuf[l] = cast[inuxi2[i]];
taruti@0 547
 					l++;
taruti@0 548
 				}
taruti@0 549
 				break;
taruti@0 550
 			case 4:
taruti@0 551
 				for(; i<c; i++) {
taruti@0 552
 					buf.dbuf[l] = cast[inuxi4[i]];
taruti@0 553
 					l++;
taruti@0 554
 				}
taruti@0 555
 				break;
taruti@0 556
 			case 8:
taruti@0 557
 				for(; i<4; i++) {
taruti@0 558
 					buf.dbuf[l] = cast[inuxi4[i]];
taruti@0 559
 					l++;
taruti@0 560
 				}
taruti@0 561
 				d = p->to.offset >> 32;
taruti@0 562
 				for(; i<c; i++) {
taruti@0 563
 					buf.dbuf[l] = cast[inuxi4[i-4]];
taruti@0 564
 					l++;
taruti@0 565
 				}
taruti@0 566
 				break;
taruti@0 567
 			}
taruti@0 568
 			break;
taruti@0 569
 		}
taruti@0 570
 	}
taruti@0 571
 	write(cout, buf.dbuf, n);
taruti@0 572
 }
taruti@0 573
 
taruti@0 574
 #define	OP_RRR(op,r1,r2,r3)\
taruti@0 575
 	(op|(((r1)&31L)<<16)|(((r2)&31L)<<21)|((r3)&31L))
taruti@0 576
 #define	OP_IRR(op,i,r2,r3)\
taruti@0 577
 	(op|(((i)&255L)<<13)|0x1000|(((r2)&31L)<<21)|((r3)&31L))
taruti@0 578
 #define	OP_MEM(op,d,r1,r2)\
taruti@0 579
 	(op|(((r1)&31L)<<16)|(((r2)&31L)<<21)|((d)&0xffff))
taruti@0 580
 #define OP_BR(op,d,r1)\
taruti@0 581
 	(op|((d)&0x1fffff)|(((r1)&31L)<<21))
taruti@0 582
 
taruti@0 583
 int
taruti@0 584
 asmout(Prog *p, Optab *o)
taruti@0 585
 {
taruti@0 586
 	long o1, o2, o3, o4, o5, o6;
taruti@0 587
 	vlong v;
taruti@0 588
 	int r, a;
taruti@0 589
 
taruti@0 590
 	o1 = 0;
taruti@0 591
 	o2 = 0;
taruti@0 592
 	o3 = 0;
taruti@0 593
 	o4 = 0;
taruti@0 594
 	o5 = 0;
taruti@0 595
 	o6 = 0;
taruti@0 596
 	switch(o->type) {
taruti@0 597
 	default:
taruti@0 598
 		diag("unknown type %d", o->type);
taruti@0 599
 		if(!debug['a'])
taruti@0 600
 			prasm(p);
taruti@0 601
 		break;
taruti@0 602
 
taruti@0 603
 	case 0:		/* pseudo ops */
taruti@0 604
 		break;
taruti@0 605
 
taruti@0 606
 	case 1:		/* register-register moves */
taruti@0 607
 		if(p->as == AMOVB || p->as == AMOVW)		/* noop should rewrite */
taruti@0 608
 			diag("forbidden SEX: %P", p);
taruti@0 609
 		if(p->as == AMOVBU || p->as == AMOVWU) {
taruti@0 610
 			v = 1;
taruti@0 611
 			if (p->as == AMOVWU)
taruti@0 612
 				v = 3;
taruti@0 613
 			o1 = OP_IRR(opcode(AZAPNOT), v, p->from.reg, p->to.reg);
taruti@0 614
 		}
taruti@0 615
 		else {
taruti@0 616
 			a = AOR;
taruti@0 617
 			if(p->as == AMOVL)
taruti@0 618
 				a = AADDL;
taruti@0 619
 			if(p->as == AMOVLU)
taruti@0 620
 				a = AEXTLL;
taruti@0 621
 			o1 = OP_RRR(opcode(a), REGZERO, p->from.reg, p->to.reg);
taruti@0 622
 		}
taruti@0 623
 		break;
taruti@0 624
 
taruti@0 625
 	case 2:		/* <operate> r1,[r2],r3 */
taruti@0 626
 		r = p->reg;
taruti@0 627
 		if(r == NREG)
taruti@0 628
 			r = p->to.reg;
taruti@0 629
 		o1 = OP_RRR(opcode(p->as), p->from.reg, r, p->to.reg);
taruti@0 630
 		break;
taruti@0 631
 
taruti@0 632
 	case 3:		/* <operate> $n,[r2],r3 */
taruti@0 633
 		v = regoff(&p->from);
taruti@0 634
 		r = p->reg;
taruti@0 635
 		if(r == NREG)
taruti@0 636
 			r = p->to.reg;
taruti@0 637
 		o1 = OP_IRR(opcode(p->as), v, r, p->to.reg);
taruti@0 638
 		break;
taruti@0 639
 
taruti@0 640
 	case 4:		/* beq r1,sbra */
taruti@0 641
 		if(p->cond == P)
taruti@0 642
 			v = -4 >> 2;
taruti@0 643
 		else
taruti@0 644
 			v = (p->cond->pc - pc-4) >> 2;
taruti@0 645
 		o1 = OP_BR(opcode(p->as), v, p->from.reg);
taruti@0 646
 		break;
taruti@0 647
 
taruti@0 648
 	case 5:		/* jmp [r1],0(r2) */
taruti@0 649
 		r = p->reg;
taruti@0 650
 		a = p->as;
taruti@0 651
 		if(r == NREG) {
taruti@0 652
 			r = o->param;
taruti@0 653
 /*			if(a == AJMP && p->to.reg == REGLINK)
taruti@0 654
 				a = ARET; /* this breaks the kernel -- maybe we need to clear prediction stack on each context switch... */
taruti@0 655
 		}
taruti@0 656
 		o1 = OP_MEM(opcode(a), 0, p->to.reg, r);
taruti@0 657
 		break;
taruti@0 658
 
taruti@0 659
 	case 6:		/* movq $n,r1 and movq $soreg,r1 */
taruti@0 660
 		r = p->from.reg;
taruti@0 661
 		if(r == NREG)
taruti@0 662
 			r = o->param;
taruti@0 663
 		v = regoff(&p->from);
taruti@0 664
 		o1 = OP_MEM(opcode(AMOVA), v, r, p->to.reg);
taruti@0 665
 		break;
taruti@0 666
 
taruti@0 667
 	case 7:		/* movbu r1, r2 */
taruti@0 668
 		v = 1;
taruti@0 669
 		if (p->as == AMOVWU)
taruti@0 670
 			v = 3;
taruti@0 671
 		o1 = OP_IRR(opcode(AZAPNOT), v, p->from.reg, p->to.reg);
taruti@0 672
 		break;
taruti@0 673
 
taruti@0 674
 	case 8:		/* mov r, soreg ==> stq o(r) */
taruti@0 675
 		r = p->to.reg;
taruti@0 676
 		if(r == NREG)
taruti@0 677
 			r = o->param;
taruti@0 678
 		v = regoff(&p->to);
taruti@0 679
 		if (p->as == AMOVQ || p->as == AMOVT)
taruti@0 680
 			if ((r == REGSP || r == REGSB) && (v&7) != 0)
taruti@0 681
 				diag("bad alignment: %P", p);
taruti@0 682
 		o1 = OP_MEM(opcode(p->as+AEND), v, r, p->from.reg);
taruti@0 683
 		break;
taruti@0 684
 
taruti@0 685
 	case 9:		/* mov soreg, r ==> ldq o(r) */
taruti@0 686
 		r = p->from.reg;
taruti@0 687
 		if(r == NREG)
taruti@0 688
 			r = o->param;
taruti@0 689
 		v = regoff(&p->from);
taruti@0 690
 		if (p->as == AMOVQ || p->as == AMOVT)
taruti@0 691
 			if ((r == REGSP || r == REGSB) && (v&7) != 0)
taruti@0 692
 				diag("bad alignment: %P", p);
taruti@0 693
 		o1 = OP_MEM(opcode(p->as), v, r, p->to.reg);
taruti@0 694
 		break;
taruti@0 695
 
taruti@0 696
 	case 10:	/* movb r1,r2 */
taruti@0 697
 		v = 64 - 8;
taruti@0 698
 		if (p->as == AMOVW)
taruti@0 699
 			v = 64 - 16;
taruti@0 700
 		o1 = OP_IRR(opcode(ASLLQ), v, p->from.reg, p->to.reg);
taruti@0 701
 		o2 = OP_IRR(opcode(ASRAQ), v, p->to.reg, p->to.reg);
taruti@0 702
 		break;
taruti@0 703
 
taruti@0 704
 	case 11:	/* jmp lbra */
taruti@0 705
 		if(p->cond == P)
taruti@0 706
 			v = -4 >> 2;
taruti@0 707
 		else
taruti@0 708
 			v = (p->cond->pc - pc-4) >> 2;
taruti@0 709
 		a = ABR;
taruti@0 710
 		r = REGZERO;
taruti@0 711
 		if (p->as == AJSR) {
taruti@0 712
 			a = ABSR;
taruti@0 713
 			r = REGLINK;
taruti@0 714
 		}
taruti@0 715
 		o1 = OP_BR(opcode(a), v, r);
taruti@0 716
 		break;
taruti@0 717
 
taruti@0 718
 	case 12:	/* addq $n,[r2],r3 ==> lda */
taruti@0 719
 		v = regoff(&p->from);
taruti@0 720
 		if (p->as == ASUBQ)
taruti@0 721
 			v = -v;
taruti@0 722
 		r = p->reg;
taruti@0 723
 		if(r == NREG)
taruti@0 724
 			r = p->to.reg;
taruti@0 725
 		o1 = OP_MEM(opcode(AMOVA), v, r, p->to.reg);
taruti@0 726
 		break;
taruti@0 727
 
taruti@0 728
 	case 13:	/* <op> $scon,[r2],r3 */
taruti@0 729
 		v = regoff(&p->from);
taruti@0 730
 		if(p->to.reg == REGTMP || p->reg == REGTMP)
taruti@0 731
 			diag("cant synthesize large constant\n%P", p);
taruti@0 732
 		r = p->reg;
taruti@0 733
 		if(r == NREG)
taruti@0 734
 			r = p->to.reg;
taruti@0 735
 		o1 = OP_MEM(opcode(AMOVA), v, REGZERO, REGTMP);
taruti@0 736
 		o2 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg);
taruti@0 737
 		break;
taruti@0 738
 
taruti@0 739
 	case 14:	/* <op> $lcon,[r2],r3 */
taruti@0 740
 		v = regoff(&p->from);
taruti@0 741
 		if(v & 0x8000)
taruti@0 742
 			v += 0x10000;
taruti@0 743
 		if(p->to.reg == REGTMP || p->reg == REGTMP)
taruti@0 744
 			diag("cant synthesize large constant\n%P", p);
taruti@0 745
 		r = p->reg;
taruti@0 746
 		if(r == NREG)
taruti@0 747
 			r = p->to.reg;
taruti@0 748
 		o1 = OP_MEM(opcode(AMOVA), v, REGZERO, REGTMP);
taruti@0 749
 		o2 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP);
taruti@0 750
 		o3 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg);
taruti@0 751
 		break;
taruti@0 752
 
taruti@0 753
 	case 15:	/* mov $lcon,r1 */
taruti@0 754
 		v = regoff(&p->from);
taruti@0 755
 		if(v & 0x8000)
taruti@0 756
 			v += 0x10000;
taruti@0 757
 		o1 = OP_MEM(opcode(AMOVA), v, o->param, REGTMP);
taruti@0 758
 		o2 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, p->to.reg);
taruti@0 759
 		break;
taruti@0 760
 
taruti@0 761
 	case 16:	/* mov $qcon,r1 */
taruti@0 762
 		v = regoff(&p->from);
taruti@0 763
 		if(v & 0x8000)
taruti@0 764
 			v += 0x10000;
taruti@0 765
 		if((v>>31)&1)
taruti@0 766
 			v += (1LL<<32);
taruti@0 767
 		if((v>>47)&1)
taruti@0 768
 			v += (1LL<<48);
taruti@0 769
 		o1 = OP_MEM(opcode(AMOVA), v>>32, o->param, REGTMP);
taruti@0 770
 		o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP);
taruti@0 771
 		o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP);
taruti@0 772
 		o4 = OP_MEM(opcode(AMOVA), v, REGTMP, REGTMP);
taruti@0 773
 		o5 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, p->to.reg);
taruti@0 774
 		break;
taruti@0 775
 
taruti@0 776
 	case 17:	/* mov f1,f2 ==> fcpys f1,f1,f2 */
taruti@0 777
 		o1 = OP_RRR(opcode(ACPYS), p->from.reg, p->from.reg, p->to.reg);
taruti@0 778
 		break;
taruti@0 779
 
taruti@0 780
 	case 18:	/* call_pal imm */
taruti@0 781
 		v = regoff(&p->from);
taruti@0 782
 		o1 = OP_MEM(opcode(ACALL_PAL), v, 0, 0);
taruti@0 783
 		break;
taruti@0 784
 
taruti@0 785
 	case 19:	/* mov r, loreg ==> ldah,stq */
taruti@0 786
 		r = p->to.reg;
taruti@0 787
 		if(r == NREG)
taruti@0 788
 			r = o->param;
taruti@0 789
 		v = regoff(&p->to);
taruti@0 790
 		if (p->as == AMOVQ || p->as == AMOVT)
taruti@0 791
 			if ((r == REGSP || r == REGSB) && (v&7) != 0)
taruti@0 792
 				diag("bad alignment: %P", p);
taruti@0 793
 		if(v & 0x8000)
taruti@0 794
 			v += 0x10000;
taruti@0 795
 		o1 = OP_MEM(opcode(AMOVAH), v>>16, r, REGTMP);
taruti@0 796
 		o2 = OP_MEM(opcode(p->as+AEND), v, REGTMP, p->from.reg);
taruti@0 797
 		break;
taruti@0 798
 
taruti@0 799
 	case 20:	/* mov loreg, r ==> ldah,ldq */
taruti@0 800
 		r = p->from.reg;
taruti@0 801
 		if(r == NREG)
taruti@0 802
 			r = o->param;
taruti@0 803
 		v = regoff(&p->from);
taruti@0 804
 		if (p->as == AMOVQ || p->as == AMOVT)
taruti@0 805
 			if ((r == REGSP || r == REGSB) && (v&7) != 0)
taruti@0 806
 				diag("bad alignment: %P", p);
taruti@0 807
 		if(v & 0x8000)
taruti@0 808
 			v += 0x10000;
taruti@0 809
 		o1 = OP_MEM(opcode(AMOVAH), v>>16, r, REGTMP);
taruti@0 810
 		o2 = OP_MEM(opcode(p->as), v, REGTMP, p->to.reg);
taruti@0 811
 		break;
taruti@0 812
 
taruti@0 813
 #ifdef	NEVER
taruti@0 814
 	case 21:	/* mov r1,$qoreg */
taruti@0 815
 		r = p->to.reg;
taruti@0 816
 		if(r == NREG)
taruti@0 817
 			r = o->param;
taruti@0 818
 		v = regoff(&p->to);
taruti@0 819
 		if(v & 0x8000)
taruti@0 820
 			v += 0x10000;
taruti@0 821
 		if((v>>31)&1)
taruti@0 822
 			v += (1LL<<32);
taruti@0 823
 		if((v>>47)&1)
taruti@0 824
 			v += (1LL<<48);
taruti@0 825
 		o1 = OP_MEM(opcode(AMOVA), v>>32, r, REGTMP);
taruti@0 826
 		o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP);
taruti@0 827
 		o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP);
taruti@0 828
 		o4 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP);
taruti@0 829
 		o5 = OP_MEM(opcode(p->as+AEND), v, REGTMP, p->from.reg);
taruti@0 830
 		break;
taruti@0 831
 
taruti@0 832
 	case 22:	/* mov $qoreg,r1 */
taruti@0 833
 		r = p->from.reg;
taruti@0 834
 		if(r == NREG)
taruti@0 835
 			r = o->param;
taruti@0 836
 		v = regoff(&p->from);
taruti@0 837
 		if(v & 0x8000)
taruti@0 838
 			v += 0x10000;
taruti@0 839
 		if((v>>31)&1)
taruti@0 840
 			v += (1LL<<32);
taruti@0 841
 		if((v>>47)&1)
taruti@0 842
 			v += (1LL<<48);
taruti@0 843
 		o1 = OP_MEM(opcode(AMOVA), v>>32, r, REGTMP);
taruti@0 844
 		o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP);
taruti@0 845
 		o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP);
taruti@0 846
 		o4 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP);
taruti@0 847
 		o5 = OP_MEM(opcode(p->as), v, REGTMP, p->to.reg);
taruti@0 848
 		break;
taruti@0 849
 #endif
taruti@0 850
 
taruti@0 851
 	case 23:	/* <op> $qcon,r1 */
taruti@0 852
 		if(p->to.reg == REGTMP || p->reg == REGTMP)
taruti@0 853
 			diag("cant synthesize large constant\n%P", p);
taruti@0 854
 		v = regoff(&p->from);
taruti@0 855
 		r = p->reg;
taruti@0 856
 		if(r == NREG)
taruti@0 857
 			r = p->to.reg;
taruti@0 858
 		if(v & 0x8000)
taruti@0 859
 			v += 0x10000;
taruti@0 860
 		if((v>>31)&1)
taruti@0 861
 			v += (1LL<<32);
taruti@0 862
 		if((v>>47)&1)
taruti@0 863
 			v += (1LL<<48);
taruti@0 864
 		o1 = OP_MEM(opcode(AMOVA), v>>32, REGZERO, REGTMP);
taruti@0 865
 		o2 = OP_MEM(opcode(AMOVAH), v>>48, REGTMP, REGTMP);
taruti@0 866
 		o3 = OP_IRR(opcode(ASLLQ), 32, REGTMP, REGTMP);
taruti@0 867
 		o4 = OP_MEM(opcode(AMOVA), v, REGTMP, REGTMP);
taruti@0 868
 		o5 = OP_MEM(opcode(AMOVAH), v>>16, REGTMP, REGTMP);
taruti@0 869
 		o6 = OP_RRR(opcode(p->as), REGTMP, r, p->to.reg);
taruti@0 870
 		break;
taruti@0 871
 
taruti@0 872
 	case 24:	/* movq Fn, FPCR */
taruti@0 873
 		r = p->from.reg;
taruti@0 874
 		o1 = OP_RRR(opcode(AADDT+AEND), r, r, r);
taruti@0 875
 		break;
taruti@0 876
 
taruti@0 877
 	case 25:	/* movq FPCR, Fn */
taruti@0 878
 		r = p->to.reg;
taruti@0 879
 		o1 = OP_RRR(opcode(AADDS+AEND), r, r, r);
taruti@0 880
 		break;
taruti@0 881
 
taruti@0 882
 	case 26:	/* movq Rn, C_PREG */
taruti@0 883
 		r = p->from.reg;
taruti@0 884
 		o1 = OP_RRR(opcode(ASUBQ+AEND), r, r, 0) | p->to.reg & 255;
taruti@0 885
 		break;
taruti@0 886
 
taruti@0 887
 	case 27:	/* movq C_PREG, Rn */
taruti@0 888
 		r = p->to.reg;
taruti@0 889
 		o1 = OP_RRR(opcode(AADDQ+AEND), r, r, 0) | p->from.reg & 255;
taruti@0 890
 		break;
taruti@0 891
 
taruti@0 892
 	case 28:	/* cvttq r1,r3 */
taruti@0 893
 		r = p->from.reg;
taruti@0 894
 		o1 = OP_RRR(opcode(p->as), r, REGZERO, p->to.reg);
taruti@0 895
 		break;
taruti@0 896
 
taruti@0 897
 	case 29:	/* movq pcc, rpcc -> Rn */
taruti@0 898
 		o1 = OP_MEM(opcode(ARPCC), 0, REGZERO, p->to.reg);
taruti@0 899
 		break;
taruti@0 900
 
taruti@0 901
 	case 30:	/* rei/mb/trapb */
taruti@0 902
 		o1 = OP_MEM(opcode(p->as), 0, REGZERO, REGZERO);
taruti@0 903
 		break;
taruti@0 904
 
taruti@0 905
 	case 31:	/* fetch (Rn) */
taruti@0 906
 		o1 = OP_MEM(opcode(p->as), 0, REGZERO, p->from.reg);
taruti@0 907
 		break;
taruti@0 908
 
taruti@0 909
 	case 32:	/* movqp r, soreg ==> stqp o(r) */
taruti@0 910
 		r = p->to.reg;
taruti@0 911
 		if(r == NREG)
taruti@0 912
 			r = o->param;
taruti@0 913
 		v = regoff(&p->to);
taruti@0 914
 		if (v < -0x800 || v >= 0x800)
taruti@0 915
 			diag("physical store out of range\n%P", p);
taruti@0 916
 		v &= 0xfff;
taruti@0 917
 		o1 = OP_MEM(opcode(p->as+AEND), v, r, p->from.reg);
taruti@0 918
 		break;
taruti@0 919
 
taruti@0 920
 	case 33:	/* movqp soreg, r ==> ldqp o(r) */
taruti@0 921
 		r = p->from.reg;
taruti@0 922
 		if(r == NREG)
taruti@0 923
 			r = o->param;
taruti@0 924
 		v = regoff(&p->from);
taruti@0 925
 		if (v < -0x800 || v >= 0x800)
taruti@0 926
 			diag("physical load out of range\n%P", p);
taruti@0 927
 		v &= 0xfff;
taruti@0 928
 		o1 = OP_MEM(opcode(p->as), v, r, p->to.reg);
taruti@0 929
 		break;
taruti@0 930
 
taruti@0 931
 	case 34:	/* <operate> $-n,[r2],r3 */
taruti@0 932
 		v = regoff(&p->from);
taruti@0 933
 		r = p->reg;
taruti@0 934
 		if(r == NREG)
taruti@0 935
 			r = p->to.reg;
taruti@0 936
 		switch (a = p->as) {
taruti@0 937
 		case AAND:
taruti@0 938
 			a = AANDNOT;
taruti@0 939
 			break;
taruti@0 940
 		case AANDNOT:
taruti@0 941
 			a = AAND;
taruti@0 942
 			break;
taruti@0 943
 		case AOR:
taruti@0 944
 			a = AORNOT;
taruti@0 945
 			break;
taruti@0 946
 		case AORNOT:
taruti@0 947
 			a = AOR;
taruti@0 948
 			break;
taruti@0 949
 		case AXOR:
taruti@0 950
 			a = AXORNOT;
taruti@0 951
 			break;
taruti@0 952
 		case AXORNOT:
taruti@0 953
 			a = AXOR;
taruti@0 954
 			break;
taruti@0 955
 		default:
taruti@0 956
 			diag("bad in NCON case: %P", p);
taruti@0 957
 		}
taruti@0 958
 		v = ~v;
taruti@0 959
 		o1 = OP_IRR(opcode(a), v, r, p->to.reg);
taruti@0 960
 		break;
taruti@0 961
 
taruti@0 962
 	case 40:	/* word */
taruti@0 963
 		o1 = regoff(&p->to);
taruti@0 964
 		break;
taruti@0 965
 
taruti@0 966
 	}
taruti@0 967
 	switch(o->size) {
taruti@0 968
 	default:
taruti@0 969
 		if(debug['a'])
taruti@0 970
 			Bprint(&bso, " %.8lux:\t\t%P\n", p->pc, p);
taruti@0 971
 		break;
taruti@0 972
 	case 4:
taruti@0 973
 		if(debug['a'])
taruti@0 974
 			Bprint(&bso, " %.8lux: %.8lux\t%P\n", p->pc, o1, p);
taruti@0 975
 		LPUT(o1);
taruti@0 976
 		break;
taruti@0 977
 	case 8:
taruti@0 978
 		if(debug['a'])
taruti@0 979
 			Bprint(&bso, " %.8lux: %.8lux %.8lux %P\n", p->pc, o1, o2, p);
taruti@0 980
 		LPUT(o1);
taruti@0 981
 		LPUT(o2);
taruti@0 982
 		break;
taruti@0 983
 	case 12:
taruti@0 984
 		if(debug['a'])
taruti@0 985
 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %P\n", p->pc, o1, o2, o3, p);
taruti@0 986
 		LPUT(o1);
taruti@0 987
 		LPUT(o2);
taruti@0 988
 		LPUT(o3);
taruti@0 989
 		break;
taruti@0 990
 	case 16:
taruti@0 991
 		if(debug['a'])
taruti@0 992
 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %P\n",
taruti@0 993
 				p->pc, o1, o2, o3, o4, p);
taruti@0 994
 		LPUT(o1);
taruti@0 995
 		LPUT(o2);
taruti@0 996
 		LPUT(o3);
taruti@0 997
 		LPUT(o4);
taruti@0 998
 		break;
taruti@0 999
 	case 20:
taruti@0 1000
 		if(debug['a'])
taruti@0 1001
 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %P\n",
taruti@0 1002
 				p->pc, o1, o2, o3, o4, o5, p);
taruti@0 1003
 		LPUT(o1);
taruti@0 1004
 		LPUT(o2);
taruti@0 1005
 		LPUT(o3);
taruti@0 1006
 		LPUT(o4);
taruti@0 1007
 		LPUT(o5);
taruti@0 1008
 		break;
taruti@0 1009
 	case 24:
taruti@0 1010
 		if(debug['a'])
taruti@0 1011
 			Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %P\n",
taruti@0 1012
 				p->pc, o1, o2, o3, o4, o5, o6, p);
taruti@0 1013
 		LPUT(o1);
taruti@0 1014
 		LPUT(o2);
taruti@0 1015
 		LPUT(o3);
taruti@0 1016
 		LPUT(o4);
taruti@0 1017
 		LPUT(o5);
taruti@0 1018
 		LPUT(o6);
taruti@0 1019
 		break;
taruti@0 1020
 	}
taruti@0 1021
 	return 0;
taruti@0 1022
 }
taruti@0 1023
 
taruti@0 1024
 #define	OP(x,y)	(((x)<<26)|((y)<<5))
taruti@0 1025
 #define	FP(x)	OP(22, (x)|0xc0)	/* note: this sets round/trap modes (dynamic, software?). not used for cvtxx? */
taruti@0 1026
 #define	FP2(x)	OP(22, (x) /*|0x080*/)	/* note: this sets round/trap modes (chopped, software?). used for cvtxx? */
taruti@0 1027
 #define	FP3(x)	OP(22, (x)|0x080)	/* note: this sets round/trap modes (dynamic, software?). not used for cvtxx? */
taruti@0 1028
 
taruti@0 1029
 long
taruti@0 1030
 opcode(int a)
taruti@0 1031
 {
taruti@0 1032
 	switch (a) {
taruti@0 1033
 	/* loads */
taruti@0 1034
 	case AMOVB:		/* misnomer; pretend it's ok for now */
taruti@0 1035
 diag("opcode(AMOVB)");
taruti@0 1036
 	case AMOVBU:		return OP(10, 0);	/* v 3 */
taruti@0 1037
 	case AMOVW:		/* misnomer; pretend it's ok for now */
taruti@0 1038
 diag("opcode(AMOVW)");
taruti@0 1039
 	case AMOVWU:		return OP(12, 0);	/* v 3 */
taruti@0 1040
 	case AMOVL:		return OP(40, 0);
taruti@0 1041
 	case AMOVQ:		return OP(41, 0);
taruti@0 1042
 	case AMOVQU:		return OP(11, 0);
taruti@0 1043
 	case AMOVS:		return OP(34, 0);
taruti@0 1044
 	case AMOVT:		return OP(35, 0);
taruti@0 1045
 
taruti@0 1046
 	/* stores */
taruti@0 1047
 	case AMOVB+AEND:		/* misnomer; pretend it's ok for now */
taruti@0 1048
 	case AMOVBU+AEND:	return OP(14, 0);	/* v 3 */
taruti@0 1049
 	case AMOVW+AEND:	/* misnomer; pretend it's ok for now */
taruti@0 1050
 	case AMOVWU+AEND:	return OP(13, 0);	/* v 3 */
taruti@0 1051
 	case AMOVL+AEND:	return OP(44, 0);
taruti@0 1052
 	case AMOVQ+AEND:	return OP(45, 0);
taruti@0 1053
 	case AMOVQU+AEND:	return OP(15, 0);
taruti@0 1054
 	case AMOVS+AEND:	return OP(38, 0);
taruti@0 1055
 	case AMOVT+AEND:	return OP(39, 0);
taruti@0 1056
 
taruti@0 1057
 	/* physical */
taruti@0 1058
 	case AMOVLP+AEND:	return OP(31, 0)|0x8000;
taruti@0 1059
 	case AMOVQP+AEND:	return OP(31, 0)|0x9000;
taruti@0 1060
 	case AMOVLP:		return OP(27, 0)|0x8000;
taruti@0 1061
 	case AMOVQP:		return OP(27, 0)|0x9000;
taruti@0 1062
 
taruti@0 1063
 	/* load address */
taruti@0 1064
 	case AMOVA:		return OP(8, 0);
taruti@0 1065
 	case AMOVAH:		return OP(9, 0);
taruti@0 1066
 
taruti@0 1067
 	/* locking */
taruti@0 1068
 	case AMOVLL:		return OP(42, 0);	/* load locked */
taruti@0 1069
 	case AMOVQL:		return OP(43, 0);	/* load locked */
taruti@0 1070
 	case AMOVLC+AEND:	return OP(46, 0);	/* store cond */
taruti@0 1071
 	case AMOVQC+AEND:	return OP(47, 0);	/* store cond */
taruti@0 1072
 
taruti@0 1073
 	case AADDL:		return OP(16, 0);
taruti@0 1074
 	case AADDLV:		return OP(16, 64);
taruti@0 1075
 	case AADDQ:		return OP(16, 32);
taruti@0 1076
 	case AADDQV:		return OP(16, 96);
taruti@0 1077
 	case AS4ADDL:		return OP(16, 2);
taruti@0 1078
 	case AS4ADDQ:		return OP(16, 34);
taruti@0 1079
 	case AS8ADDL:		return OP(16, 18);
taruti@0 1080
 	case AS8ADDQ:		return OP(16, 50);
taruti@0 1081
 	case AS4SUBL:		return OP(16, 11);
taruti@0 1082
 	case AS4SUBQ:		return OP(16, 43);
taruti@0 1083
 	case AS8SUBL:		return OP(16, 27);
taruti@0 1084
 	case AS8SUBQ:		return OP(16, 59);
taruti@0 1085
 	case ASUBL:		return OP(16, 9);
taruti@0 1086
 	case ASUBLV:		return OP(16, 73);
taruti@0 1087
 	case ASUBQ:		return OP(16, 41);
taruti@0 1088
 	case ASUBQV:		return OP(16, 105);
taruti@0 1089
 	case ACMPEQ:		return OP(16, 45);
taruti@0 1090
 	case ACMPGT:		return OP(16, 77);
taruti@0 1091
 	case ACMPGE:		return OP(16, 109);
taruti@0 1092
 	case ACMPUGT:		return OP(16, 29);
taruti@0 1093
 	case ACMPUGE:		return OP(16, 61);
taruti@0 1094
 	case ACMPBLE:		return OP(16, 15);
taruti@0 1095
 
taruti@0 1096
 	case AAND:		return OP(17, 0);
taruti@0 1097
 	case AANDNOT:		return OP(17, 8);
taruti@0 1098
 	case AOR:		return OP(17, 32);
taruti@0 1099
 	case AORNOT:		return OP(17, 40);
taruti@0 1100
 	case AXOR:		return OP(17, 64);
taruti@0 1101
 	case AXORNOT:		return OP(17, 72);
taruti@0 1102
 
taruti@0 1103
 	case ACMOVEQ:		return OP(17, 36);
taruti@0 1104
 	case ACMOVNE:		return OP(17, 38);
taruti@0 1105
 	case ACMOVLT:		return OP(17, 68);
taruti@0 1106
 	case ACMOVGE:		return OP(17, 70);
taruti@0 1107
 	case ACMOVLE:		return OP(17, 100);
taruti@0 1108
 	case ACMOVGT:		return OP(17, 102);
taruti@0 1109
 	case ACMOVLBS:		return OP(17, 20);
taruti@0 1110
 	case ACMOVLBC:		return OP(17, 22);
taruti@0 1111
 
taruti@0 1112
 	case AMULL:		return OP(19, 0);
taruti@0 1113
 	case AMULQ:		return OP(19, 32);
taruti@0 1114
 	case AMULLV:		return OP(19, 64);
taruti@0 1115
 	case AMULQV:		return OP(19, 96);
taruti@0 1116
 	case AUMULH:		return OP(19, 48);
taruti@0 1117
 
taruti@0 1118
 	case ASLLQ:		return OP(18, 57);
taruti@0 1119
 	case ASRLQ:		return OP(18, 52);
taruti@0 1120
 	case ASRAQ:		return OP(18, 60);
taruti@0 1121
 
taruti@0 1122
 	case AEXTBL:		return OP(18, 6);
taruti@0 1123
 	case AEXTWL:		return OP(18, 22);
taruti@0 1124
 	case AEXTLL:		return OP(18, 38);
taruti@0 1125
 	case AEXTQL:		return OP(18, 54);
taruti@0 1126
 	case AEXTWH:		return OP(18, 90);
taruti@0 1127
 	case AEXTLH:		return OP(18, 106);
taruti@0 1128
 	case AEXTQH:		return OP(18, 122);
taruti@0 1129
 
taruti@0 1130
 	case AINSBL:		return OP(18, 11);
taruti@0 1131
 	case AINSWL:		return OP(18, 27);
taruti@0 1132
 	case AINSLL:		return OP(18, 43);
taruti@0 1133
 	case AINSQL:		return OP(18, 59);
taruti@0 1134
 	case AINSWH:		return OP(18, 87);
taruti@0 1135
 	case AINSLH:		return OP(18, 103);
taruti@0 1136
 	case AINSQH:		return OP(18, 119);
taruti@0 1137
 
taruti@0 1138
 	case AMSKBL:		return OP(18, 2);
taruti@0 1139
 	case AMSKWL:		return OP(18, 18);
taruti@0 1140
 	case AMSKLL:		return OP(18, 34);
taruti@0 1141
 	case AMSKQL:		return OP(18, 50);
taruti@0 1142
 	case AMSKWH:		return OP(18, 82);
taruti@0 1143
 	case AMSKLH:		return OP(18, 98);
taruti@0 1144
 	case AMSKQH:		return OP(18, 114);
taruti@0 1145
 
taruti@0 1146
 	case AZAP:		return OP(18, 48);
taruti@0 1147
 	case AZAPNOT:		return OP(18, 49);
taruti@0 1148
 
taruti@0 1149
 	case AJMP:		return OP(26, 0);
taruti@0 1150
 	case AJSR:		return OP(26, 512);
taruti@0 1151
 	case ARET:		return OP(26, 1024);
taruti@0 1152
 
taruti@0 1153
 	case ABR:		return OP(48, 0);
taruti@0 1154
 	case ABSR:		return OP(52, 0);
taruti@0 1155
 
taruti@0 1156
 	case ABEQ:		return OP(57, 0);
taruti@0 1157
 	case ABNE:		return OP(61, 0);
taruti@0 1158
 	case ABLT:		return OP(58, 0);
taruti@0 1159
 	case ABGE:		return OP(62, 0);
taruti@0 1160
 	case ABLE:		return OP(59, 0);
taruti@0 1161
 	case ABGT:		return OP(63, 0);
taruti@0 1162
 	case ABLBC:		return OP(56, 0);
taruti@0 1163
 	case ABLBS:		return OP(60, 0);
taruti@0 1164
 
taruti@0 1165
 	case AFBEQ:		return OP(49, 0);
taruti@0 1166
 	case AFBNE:		return OP(53, 0);
taruti@0 1167
 	case AFBLT:		return OP(50, 0);
taruti@0 1168
 	case AFBGE:		return OP(54, 0);
taruti@0 1169
 	case AFBLE:		return OP(51, 0);
taruti@0 1170
 	case AFBGT:		return OP(55, 0);
taruti@0 1171
 
taruti@0 1172
 	case ATRAPB:		return OP(24, 0);
taruti@0 1173
 	case AMB:		return OP(24, 0x200);
taruti@0 1174
 	case AFETCH:		return OP(24, 0x400);
taruti@0 1175
 	case AFETCHM:		return OP(24, 0x500);
taruti@0 1176
 	case ARPCC:		return OP(24, 0x600);
taruti@0 1177
 
taruti@0 1178
 	case ACPYS:		return OP(23, 32);
taruti@0 1179
 	case ACPYSN:		return OP(23, 33);
taruti@0 1180
 	case ACPYSE:		return OP(23, 34);
taruti@0 1181
 	case AADDS+AEND:	return OP(23, 37);	/* MF_FPCR */
taruti@0 1182
 	case AADDT+AEND:	return OP(23, 36);	/* MT_FPCR */
taruti@0 1183
 	case ACVTLQ:		return OP(23, 16);
taruti@0 1184
 	case ACVTQL:		return OP(23, 48);	/* XXX trap mode */
taruti@0 1185
 	case AFCMOVEQ:		return OP(23, 42);
taruti@0 1186
 	case AFCMOVNE:		return OP(23, 43);
taruti@0 1187
 	case AFCMOVLT:		return OP(23, 44);
taruti@0 1188
 	case AFCMOVGE:		return OP(23, 45);
taruti@0 1189
 	case AFCMOVLE:		return OP(23, 46);
taruti@0 1190
 	case AFCMOVGT:		return OP(23, 47);
taruti@0 1191
 
taruti@0 1192
 	case AADDS:		return FP(0);
taruti@0 1193
 	case AADDT:		return FP(32);
taruti@0 1194
 	case ACMPTEQ:		return FP3(37);
taruti@0 1195
 	case ACMPTGT:		return FP3(38);
taruti@0 1196
 	case ACMPTGE:		return FP3(39);
taruti@0 1197
 	case ACMPTUN:		return FP3(36);
taruti@0 1198
 
taruti@0 1199
 	case ACVTQS:		return FP2(60);
taruti@0 1200
 	case ACVTQT:		return FP2(62);
taruti@0 1201
 	case ACVTTS:		return FP2(44);
taruti@0 1202
 	case ACVTTQ:		return FP2(47);
taruti@0 1203
 
taruti@0 1204
 	case ADIVS:		return FP(3);
taruti@0 1205
 	case ADIVT:		return FP(35);
taruti@0 1206
 	case AMULS:		return FP(2);
taruti@0 1207
 	case AMULT:		return FP(34);
taruti@0 1208
 	case ASUBS:		return FP(1);
taruti@0 1209
 	case ASUBT:		return FP(33);
taruti@0 1210
 
taruti@0 1211
 	case ACALL_PAL:		return 0;
taruti@0 1212
 	case AREI:		return OP(30, 0x400);	/* HW_REI */
taruti@0 1213
 
taruti@0 1214
 	case AADDQ+AEND:	return OP(25,0);	/* HW_MFPR */
taruti@0 1215
 	case ASUBQ+AEND:	return OP(29,0);	/* HW_MTPR */
taruti@0 1216
 	}
taruti@0 1217
 	diag("bad op %A(%d)", a, a);
taruti@0 1218
 	return 0;
taruti@0 1219
 }
taruti@0 1220