xref: /netbsd/external/bsd/pcc/dist/pcc/arch/pdp10/local.c (revision 6550d01e)
1 /*	Id: local.c,v 1.71 2009/05/07 02:34:11 gmcgarry Exp 	*/
2 /*	$NetBSD: local.c,v 1.1.1.3 2010/06/03 18:57:22 plunky Exp $	*/
3 /*
4  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 
31 # include "pass1.h"
32 
33 /*	this file contains code which is dependent on the target machine */
34 
35 static int pointp(TWORD t);
36 static struct symtab *newfun(char *name, TWORD type);
37 
38 #define	PTRNORMAL	1
39 #define	PTRCHAR		2
40 #define	PTRSHORT	3
41 static int xptype(TWORD t);
42 
43 NODE *
44 clocal(NODE *p)
45 {
46 	/* this is called to do local transformations on
47 	   an expression tree preparitory to its being
48 	   written out in intermediate code.
49 	*/
50 
51 	/* the major essential job is rewriting the
52 	   automatic variables and arguments in terms of
53 	   REG and OREG nodes */
54 	/* conversion ops which are not necessary are also clobbered here */
55 	/* in addition, any special features (such as rewriting
56 	   exclusive or) are easily handled here as well */
57 
58 	register struct symtab *q;
59 	register NODE *r, *l, *oop;
60 	register int o;
61 	register int m, ml;
62 	int siz;
63 
64 #ifdef PCC_DEBUG
65 	if (xdebug) {
66 		printf("clocal: %p\n", p);
67 		fwalk(p, eprint, 0);
68 	}
69 #endif
70 
71 	switch( o = p->n_op ){
72 
73 	case NAME:
74 		if ((q = p->n_sp) == NULL)
75 			return p; /* Nothing to care about */
76 
77 		switch (q->sclass) {
78 
79 		case PARAM:
80 			/* First 7 parameters are in registers */
81 			/* XXX last may be double */
82 			if (q->soffset/SZINT < 7) {
83 				p->n_op = REG;
84 				p->n_rval = q->soffset/SZINT;
85 				break;
86 			} else
87 				q->soffset -= 7*SZINT;
88 
89 		case AUTO:
90 			/* fake up a structure reference */
91 			if (q->stype == CHAR || q->stype == UCHAR ||
92 			    q->stype == SHORT || q->stype == USHORT)
93 				r = block(REG, NIL, NIL, PTR+q->stype, 0, 0);
94 			else
95 				r = block(REG, NIL, NIL, PTR+STRTY, 0, 0);
96 			r->n_lval = 0;
97 			r->n_rval = FPREG;
98 			p = stref(block(STREF, r, p, 0, 0, 0));
99 			break;
100 
101 		case STATIC:
102 			if (q->slevel == 0)
103 				break;
104 			p->n_lval = 0;
105 			break;
106 
107 		case REGISTER:
108 			p->n_op = REG;
109 			p->n_lval = 0;
110 			p->n_rval = q->soffset;
111 			break;
112 
113 			}
114 		break;
115 
116 	case CALL:
117 		/* avoid recursive calls */
118 		r = tempnode(0, p->n_type, p->n_df, p->n_sue);
119 		l = tempnode(regno(r), p->n_type, p->n_df, p->n_sue);
120 		ecomp(buildtree(ASSIGN, r, p));
121 		p = l;
122 		break;
123 
124 	case PCONV:
125 		l = p->n_left;
126 		/*
127 		 * Handle frame pointer directly without conversion,
128 		 * for efficiency.
129 		 */
130 		if (l->n_op == REG && l->n_rval == 0) {
131 rmpc:			l->n_type = p->n_type;
132 			l->n_df = p->n_df;
133 			l->n_sue = p->n_sue;
134 			nfree(p);
135 			return l;
136 		}
137 		/* Convert ICON with name to new type */
138 		if (l->n_op == ICON && l->n_sp != NULL &&
139 		    l->n_type == INCREF(STRTY) &&
140 		    (p->n_type == INCREF(CHAR) ||
141 		    p->n_type == INCREF(UCHAR) ||
142 		    p->n_type == INCREF(SHORT) ||
143 		    p->n_type == INCREF(USHORT))) {
144 			l->n_lval *= (BTYPE(p->n_type) == CHAR ||
145 			    BTYPE(p->n_type) == UCHAR ? 4 : 2);
146 			goto rmpc;
147 		}
148 		/* Convert only address constants, never convert other */
149 		if (l->n_op == ICON) {
150 			if (l->n_sp == NULL)
151 				goto rmpc;
152 			if (p->n_type == INCREF(CHAR) ||
153 			    p->n_type == INCREF(UCHAR) ||
154 			    p->n_type == INCREF(VOID))
155 				l->n_lval = (l->n_lval & 07777777777) |
156 				    0700000000000LL;
157 			else if (p->n_type == INCREF(SHORT) ||
158 			    p->n_type == INCREF(USHORT))
159 				l->n_lval = (l->n_lval & 07777777777) |
160 				    0750000000000LL;
161 			else
162 				l->n_lval = l->n_lval & 07777777777;
163 			goto rmpc;
164 		}
165 
166 		/* Remove more conversions of identical pointers */
167 		/* Be careful! optim() may do bad things */
168 		if (ISPTR(DECREF(p->n_type))) {
169 			if (ISPTR(DECREF(l->n_type))) {
170 				if ((coptype(l->n_op) == UTYPE ||
171 				    coptype(l->n_op) == BITYPE) &&
172 				    (l->n_left->n_op == REG))
173 					l->n_left->n_type = p->n_type;
174 				goto rmpc;
175 			}
176 		}
177 
178 		/* Change PCONV from int to double pointer to right shift */
179 		if (ISPTR(p->n_type) && ISPTR(DECREF(p->n_type)) &&
180 		    (l->n_type == INT || l->n_type == UNSIGNED)) {
181 			p->n_op = RS;
182 			p->n_right = bcon(2);
183 			break;
184 		}
185 
186 		/* Check for cast integral -> pointer */
187 		if (BTYPE(l->n_type) == l->n_type)
188 			break;
189 
190 		/* Remove conversions to identical pointers */
191 		switch (xptype(p->n_type)) {
192 		case PTRNORMAL:
193 			if (xptype(l->n_type) == PTRNORMAL)
194 				goto rmpc;
195 			break;
196 
197 		case PTRSHORT:
198 			if (xptype(l->n_type) == PTRSHORT)
199 				goto rmpc;
200 			break;
201 
202 		case PTRCHAR:
203 			if (xptype(l->n_type) == PTRCHAR)
204 				goto rmpc;
205 			break;
206 		}
207 
208 		break;
209 
210 	case SCONV:
211 		l = p->n_left;
212 
213 		if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
214 		    btdims[p->n_type].suesize == btdims[l->n_type].suesize) {
215 			if (p->n_type != FLOAT && p->n_type != DOUBLE &&
216 			     l->n_type != FLOAT && l->n_type != DOUBLE) {
217 				nfree(p);
218 				return l;
219 			}
220 		}
221 		/* cast to (void) XXX should be removed in MI code */
222 		if (p->n_type == VOID) {
223 			nfree(p);
224 			return l;
225 		}
226 		m = p->n_type;
227 		ml = l->n_type;
228 		if (m == ml) {
229 			nfree(p);
230 			return l;
231 		}
232 		o = l->n_op;
233 		if (ml == FLOAT || ml == DOUBLE) {
234 			if (o != FCON)
235 				break;
236 			ml = ISUNSIGNED(m) ? UNSIGNED : INT; /* LONG? */
237 			r = xbcon(ml == INT ? (int)p->n_left->n_dcon :
238 			                      (unsigned)p->n_left->n_dcon,
239 			          NULL, ml);
240 			nfree(p->n_left);
241 			p->n_left = r;
242 			o = ICON;
243 			if (m == ml) {
244 				r = p->n_left;
245 				nfree(p);
246 				return r;
247 			}
248 		}
249 		if (o == ICON) {
250 			CONSZ val = l->n_lval;
251 
252 			switch (m) {
253 			case CHAR:
254 				l->n_lval = val & 0777;
255 				if (val & 0400)
256 					l->n_lval |= ~((CONSZ)0777);
257 				break;
258 			case UCHAR:
259 				l->n_lval = val & 0777;
260 				break;
261 			case USHORT:
262 				l->n_lval = val & 0777777;
263 				break;
264 			case SHORT:
265 				l->n_lval = val & 0777777;
266 				if (val & 0400000)
267 					l->n_lval |= ~((CONSZ)0777777);
268 				break;
269 			case UNSIGNED:
270 				l->n_lval = val & 0777777777777LL;
271 				break;
272 			case INT:
273 				l->n_lval = val & 0777777777777LL;
274 				if (val & 0400000000000LL)
275 					l->n_lval |= ~(0777777777777LL);
276 				break;
277 			case LONGLONG:	/* XXX */
278 			case ULONGLONG:
279 				l->n_lval = val;
280 				break;
281 			case VOID:
282 				break;
283 			case DOUBLE:
284 			case FLOAT:
285 				l->n_op = FCON;
286 				l->n_dcon = 0;
287 				break;
288 			default:
289 				cerror("unknown type %d", m);
290 			}
291 			l->n_type = m;
292 			l->n_sue = MKSUE(m);
293 			nfree(p);
294 			return l;
295 		}
296 		break;
297 
298 	case PMCONV:
299 	case PVCONV:
300 /*                if( p->n_right->n_op != ICON ) cerror( "bad conversion", 0); */
301                 nfree(p);
302                 return(buildtree(o==PMCONV?MUL:DIV, p->n_left, p->n_right));
303 
304 	case RS:
305 	case RSEQ:
306 		/* convert >> to << with negative shift count */
307 		/* Beware! constant shifts will be converted back in optim() */
308 
309 		if (p->n_right->n_op != UMINUS) {
310 			p->n_right = buildtree(UMINUS, p->n_right, NIL);
311 		} else {
312 			r = p->n_right;
313 			p->n_right = p->n_right->n_left;
314 			nfree(r);
315 		}
316 		if (p->n_op == RS)
317 			p->n_op = LS;
318 		else
319 			p->n_op = LSEQ;
320 		break;
321 
322 	case UMUL: /* Convert structure assignment to memcpy() */
323 		if (p->n_left->n_op == PLUS &&
324 		    p->n_left->n_left->n_op == PCONV &&
325 		    p->n_left->n_right->n_op == ICON &&
326 		    (p->n_type == CHAR || p->n_type == UCHAR ||
327 		    p->n_type == SHORT || p->n_type == USHORT)) {
328 			/* Can remove the left SCONV */
329 			l = p->n_left->n_left;
330 			p->n_left->n_left = l->n_left;
331 			nfree(l);
332 			break;
333 
334 		}
335 		if (p->n_left->n_op != STASG)
336 			break;
337 		oop = p;
338 		p = p->n_left;
339 		siz = p->n_sue->suesize/SZCHAR;
340 		l = p->n_left;
341 		r = p->n_right;
342 		if (l->n_type == STRTY || l->n_type == UNIONTY) {
343 			if (l->n_op == UMUL) {
344 				p->n_left = l->n_left;
345 				nfree(l);
346 				l = p->n_left;
347 			} else {
348 				l = block(ADDROF, l, NIL, INCREF(l->n_type),
349 				    0, MKSUE(INT));
350 			}
351 		}
352 		if ((l->n_type != (STRTY+PTR) && l->n_type != (UNIONTY+PTR)) ||
353 		    (r->n_type != (STRTY+PTR) && r->n_type != (UNIONTY+PTR)))
354 			cerror("bad stasg, l = %o, r = %o", l->n_type, r->n_type);
355 		q = newfun("__structcpy", p->n_type);
356 
357 		/* structure pointer block */
358 		l = block(CM, l, r, INT, 0, MKSUE(INT));
359 		/* Size block */
360 		r = block(CM, l, bcon(siz), INT, 0, MKSUE(INT));
361 
362 		l = xbcon(0, q, q->stype);
363 		p->n_left = l;
364 		p->n_right = r;
365 		p->n_op = CALL;
366 		oop->n_left = p;
367 		return oop;
368 
369 	case FORCE:
370 		p->n_op = ASSIGN;
371 		p->n_right = p->n_left;
372 		p->n_left = block(REG, NIL, NIL, p->n_type, 0, MKSUE(INT));
373 		p->n_left->n_rval = RETREG(p->n_type);
374 		break;
375 
376 	}
377 
378 	return(p);
379 }
380 
381 void
382 myp2tree(NODE *p)
383 {
384 	NODE *r;
385 
386 	switch (p->n_op) {
387 	case ULT: /* exor sign bit to avoid unsigned comparitions */
388 	case ULE:
389 	case UGT:
390 	case UGE:
391 		if (ISLONGLONG(p->n_left->n_type)) {
392 			/* XXX */
393 			r = xbcon(0x8000000000000000ULL, NULL, LONGLONG);
394 		} else
395 			r = xbcon(0400000000000LL, NULL, INT);
396 		p->n_left = buildtree(ER, p->n_left, r);
397 		if (ISUNSIGNED(p->n_left->n_type))
398 			p->n_left->n_type = DEUNSIGN(p->n_left->n_type);
399 
400 		if (ISLONGLONG(p->n_right->n_type)) {
401 			/* XXX */
402 			r = xbcon(0x8000000000000000ULL, NULL, LONGLONG);
403 		} else
404 			r = xbcon(0400000000000LL, NULL, INT);
405 		p->n_right = buildtree(ER, p->n_right, r);
406 		if (ISUNSIGNED(p->n_right->n_type))
407 			p->n_right->n_type = DEUNSIGN(p->n_right->n_type);
408 
409 		p->n_op -= (ULT-LT);
410 		break;
411 	case FCON:
412 		cerror("fix float constants");
413 	}
414 }
415 
416 
417 struct symtab *
418 newfun(char *name, TWORD type)
419 {
420 	struct symtab *sp;
421 
422 	sp = lookup(name, 0);
423 	if (sp->stype == VOID) {
424 		sp->stype = INCREF(type | FTN);
425 		sp->sclass = EXTERN;
426 		sp->soffset = 0;
427 	}
428 #ifdef notdef
429 	else if (!ISFTN(DECREF(sp->stype)))
430 		uerror("reserved name '%s' used illegally", name);
431 #endif
432 	return sp;
433 }
434 
435 /*ARGSUSED*/
436 int
437 andable(NODE *p)
438 {
439 	return(1);  /* all names can have & taken on them */
440 }
441 
442 /*
443  * at the end of the arguments of a ftn, set the automatic offset
444  */
445 void
446 cendarg()
447 {
448 	autooff = AUTOINIT;
449 }
450 
451 /*
452  * is an automatic variable of type t OK for a register variable
453  * Everything is trusted to be in register here.
454  */
455 int
456 cisreg(TWORD t)
457 {
458 	return(1);
459 }
460 
461 int
462 xptype(TWORD t)
463 {
464 	int tt = BTYPE(t);
465 	int e, rv;
466 
467 	if (!ISPTR(t))
468 		cerror("not a pointer");
469 
470 	e = t & ~BTMASK;
471 	rv = e;
472 	while (e) {
473 		rv = e;
474 		if (DECREF(e) == 0)
475 			break;
476 		e = DECREF(e);
477 	}
478 	if (ISFTN(rv))
479 		return PTRNORMAL;
480 
481 	switch (tt) {
482 	case INT:
483 	case LONG:
484 	case LONGLONG:
485 	case FLOAT:
486 	case DOUBLE:
487 	case STRTY:
488 	case UNIONTY:
489 	case UNSIGNED:
490 	case ULONG:
491 	case ULONGLONG:
492 		return PTRNORMAL;
493 	case VOID:
494 	case CHAR:
495 	case UCHAR:
496 		if (DECREF(t) == tt || ISARY(rv))
497 			return PTRCHAR;
498 		return PTRNORMAL;
499 	case SHORT:
500 	case USHORT:
501 		if (DECREF(t) == tt || ISARY(rv))
502 			return PTRSHORT;
503 		return PTRNORMAL;
504 	default:
505 		break;
506 	}
507 	cerror("unknown type");
508 	return PTRNORMAL; /* XXX */
509 }
510 
511 /*
512  * Help routine to the one below; return true if it's not a word pointer.
513  */
514 static int
515 pointp(TWORD t)
516 {
517 	int rv = 0;
518 
519 	if (ISPTR(t) && ((t & TMASK1) == 0))
520 		return 1;
521 
522 	t &= ~BTMASK;
523 	while (t) {
524 		rv = ISARY(t);
525 		t = DECREF(t);
526 	}
527 	return rv;
528 }
529 
530 /*
531  * return a node, for structure references, which is suitable for
532  * being added to a pointer of type t, in order to be off bits offset
533  * into a structure
534  * t, d, and s are the type, dimension offset, and sizeoffset
535  * For pdp10, return the type-specific index number which calculation
536  * is based on its size. For example, short a[3] would return 3.
537  * Be careful about only handling first-level pointers, the following
538  * indirections must be fullword.
539  */
540 NODE *
541 offcon(OFFSZ off, TWORD t, union dimfun *d, struct suedef *sue)
542 {
543 	register NODE *p;
544 
545 	if (xdebug)
546 		printf("offcon: OFFSZ %lld type %x dim %p siz %d\n",
547 		    off, t, d, sue->suesize);
548 
549 	p = bcon(0);
550 	p->n_lval = off/SZINT;	/* Default */
551 	if (ISPTR(DECREF(t)))
552 		return p;	/* Pointer/pointer reference */
553 	switch (BTMASK & t) {
554 	case INT:
555 	case UNSIGNED:
556 	case LONG:
557 	case ULONG:
558 	case STRTY:
559 	case UNIONTY:
560 	case LONGLONG:
561 	case ULONGLONG:
562 	case FLOAT:
563 	case DOUBLE:
564 		break;
565 
566 	case SHORT:
567 	case USHORT:
568 		if (pointp(t))
569 			p->n_lval = off/SZSHORT;
570 		break;
571 
572 	case VOID: /* void pointers */
573 	case CHAR:
574 	case UCHAR:
575 		if (pointp(t))
576 			p->n_lval = off/SZCHAR;
577 		break;
578 
579 	default:
580 		cerror("offcon, off %llo size %d type %x", off, sue->suesize, t);
581 	}
582 	if (xdebug)
583 		printf("offcon return 0%llo\n", p->n_lval);
584 	return(p);
585 }
586 
587 /*
588  * Allocate off bits on the stack.  p is a tree that when evaluated
589  * is the multiply count for off, t is a NAME node where to write
590  * the allocated address.
591  * Be aware that a pointer conversion may be needed when saving
592  * to node t!
593  */
594 void
595 spalloc(NODE *t, NODE *p, OFFSZ off)
596 {
597 	NODE *sp;
598 
599 	if ((off % SZINT) == 0)
600 		p =  buildtree(MUL, p, bcon(off/SZINT));
601 	else if ((off % SZSHORT) == 0) {
602 		p = buildtree(MUL, p, bcon(off/SZSHORT));
603 		p = buildtree(PLUS, p, bcon(1));
604 		p = buildtree(RS, p, bcon(1));
605 	} else if ((off % SZCHAR) == 0) {
606 		p = buildtree(MUL, p, bcon(off/SZCHAR));
607 		p = buildtree(PLUS, p, bcon(3));
608 		p = buildtree(RS, p, bcon(2));
609 	} else
610 		cerror("roundsp");
611 
612 	/* save the address of sp */
613 	sp = block(REG, NIL, NIL, PTR+INT, t->n_df, t->n_sue);
614 	sp->n_lval = 0;
615 	sp->n_rval = STKREG;
616 	/* Cast sp to destination type (may be redundant) */
617 	sp = buildtree(CAST,
618 	    block(NAME, NIL, NIL, t->n_type, t->n_df, t->n_sue), sp);
619 	nfree(sp->n_left);
620 	nfree(sp);
621 	sp = sp->n_right;
622 	ecomp(buildtree(ASSIGN, t, sp)); /* Emit! */
623 
624 	/* add the size to sp */
625 	sp = block(REG, NIL, NIL, p->n_type, 0, 0);
626 	sp->n_lval = 0;
627 	sp->n_rval = STKREG;
628 	ecomp(buildtree(PLUSEQ, sp, p));
629 }
630 
631 #if 0
632 static int inwd;	/* current bit offsed in word */
633 static CONSZ word;	/* word being built from fields */
634 
635 /*
636  * Generate initialization code for assigning a constant c
637  * to a field of width sz
638  * we assume that the proper alignment has been obtained
639  * inoff is updated to have the proper final value
640  * we also assume sz  < SZINT
641  */
642 void
643 incode(NODE *p, int sz)
644 {
645 	char *s;
646 
647 	inoff += sz;
648 	if ((sz + inwd) > SZINT)
649 		cerror("incode: field > int");
650 
651 	word |= ((p->n_lval & ((1 << sz) - 1)) << (36 - inwd - sz));
652 
653 	inwd += sz;
654 	if (inoff % SZINT == 0) {
655 		s = isinlining ? permalloc(30) : tmpalloc(30);
656 		sprintf(s, "	.long 0%llo", word);
657 		send_passt(IP_ASM, s);
658 		word = inwd = 0;
659 	}
660 	tfree(p);
661 }
662 
663 /* output code to initialize space of size sz to the value d */
664 /* the proper alignment has been obtained */
665 /* inoff is updated to have the proper final value */
666 /* on the target machine, write it out in octal! */
667 void
668 fincode(NODE *p, int sz)
669 {
670 	double d = p->n_dcon;
671 
672 	if(!nerrors)
673 		printf("	%s	0%c%.20e\n",
674 		    sz == SZDOUBLE ? ".double" : ".float",
675 		sz == SZDOUBLE ? 'd' : 'f', d);
676 	inoff += sz;
677 }
678 
679 void
680 cinit(NODE *p, int sz)
681 {
682 	NODE *l;
683 
684 	/*
685 	 * as a favor (?) to people who want to write
686 	 *     int i = 9600/134.5;
687 	 * we will, under the proper circumstances, do
688 	 * a coercion here.
689 	 */
690 	switch (p->n_type) {
691 	case INT:
692 	case UNSIGNED:
693 		l = p->n_left;
694 		if (l->n_op != SCONV || l->n_left->n_op != FCON)
695 			break;
696 		nfree(l);
697 		l = l->n_left;
698 		l->n_lval = (long)(l->n_dcon);
699 		l->n_sp = NULL;
700 		l->n_op = ICON;
701 		l->n_type = INT;
702 		p->n_left = l;
703 		break;
704 	}
705 	/* arrange for the initialization of p into a space of size sz */
706 	/* the proper alignment has been opbtained */
707 	/* inoff is updated to have the proper final value */
708 	ecode( p );
709 	inoff += sz;
710 }
711 
712 /*
713  * define n bits of zeros in a vfd
714  */
715 void
716 vfdzero(int n)
717 {
718 	char *s;
719 
720 	inoff += n;
721 	inwd += n;
722 	if (inoff%ALINT ==0) {
723 		s = isinlining ? permalloc(30) : tmpalloc(30);
724 		sprintf(s, "	.long 0%llo", word);
725 		send_passt(IP_ASM, s);
726 		word = inwd = 0;
727 	}
728 }
729 #endif
730 
731 /* make a name look like an external name in the local machine */
732 char *
733 exname(char *p)
734 {
735 	if (p == NULL)
736 		return "";
737 	return p;
738 }
739 
740 /*
741  * map types which are not defined on the local machine
742  */
743 TWORD
744 ctype(TWORD type)
745 {
746 	switch (BTYPE(type)) {
747 	case LONG:
748 		MODTYPE(type,INT);
749 		break;
750 	case ULONG:
751 		MODTYPE(type,UNSIGNED);
752 		break;
753 	case LDOUBLE:
754 		MODTYPE(type,DOUBLE);
755 		break;
756 	}
757 	return (type);
758 }
759 
760 /*
761  * Print out a string of characters.
762  * Assume that the assembler understands C-style escape
763  * sequences.
764  */
765 void
766 instring(struct symtab *sp)
767 {
768 	char *s, *str;
769 
770 	defloc(sp);
771 	str = sp->sname;
772 
773 	/* be kind to assemblers and avoid long strings */
774 	printf("\t.ascii \"");
775 	for (s = str; *s != 0; ) {
776 		if (*s++ == '\\') {
777 			(void)esccon(&s);
778 		}
779 		if (s - str > 60) {
780 			fwrite(str, 1, s - str, stdout);
781 			printf("\"\n\t.ascii \"");
782 			str = s;
783 		}
784 	}
785 	fwrite(str, 1, s - str, stdout);
786 	printf("\\0\"\n");
787 }
788 
789 /* curid is a variable which is defined but
790  * is not initialized (and not a function );
791  * This routine returns the stroage class for an uninitialized declaration
792  */
793 int
794 noinit()
795 {
796 	return(EXTERN);
797 }
798 
799 void
800 calldec(NODE *p, NODE *q)
801 {
802 }
803 
804 void
805 extdec(struct symtab *q)
806 {
807 }
808 
809 /* make a common declaration for id, if reasonable */
810 void
811 defzero(struct symtab *sp)
812 {
813 	int off;
814 
815 	off = tsize(sp->stype, sp->sdf, sp->ssue);
816 	off = (off+(SZINT-1))/SZINT;
817 	printf("        .%scomm ", sp->sclass == STATIC ? "l" : "");
818 	if (sp->slevel == 0)
819 		printf("%s,0%o\n", exname(sp->soname), off);
820 	else
821 		printf(LABFMT ",0%o\n", sp->soffset, off);
822 }
823 
824 /*
825  * set fsz bits in sequence to zero.
826  */
827 void
828 zbits(OFFSZ off, int fsz)
829 {
830 	cerror("zbits");
831 }
832 
833 /*
834  * Initialize a bitfield.
835  */
836 void
837 infld(CONSZ off, int fsz, CONSZ val)
838 {
839 //	if (idebug)
840 //		printf("infld off %lld, fsz %d, val %lld inbits %d\n",
841 //		    off, fsz, val, inbits);
842 	cerror("infld");
843 }
844 
845 /*
846  * print out a constant node, may be associated with a label.
847  * Do not free the node after use.
848  * off is bit offset from the beginning of the aggregate
849  * fsz is the number of bits this is referring to
850  */
851 void
852 ninval(CONSZ off, int fsz, NODE *p)
853 {
854 	cerror("ninval");
855 }
856 
857 
858 /*
859  * Give target the opportunity of handling pragmas.
860  */
861 int
862 mypragma(char **ary)
863 {
864 	return 0; }
865 
866 /*
867  * Called when a identifier has been declared, to give target last word.
868  */
869 void
870 fixdef(struct symtab *sp)
871 {
872 }
873 
874 void
875 pass1_lastchance(struct interpass *ip)
876 {
877 }
878 
879