1 /*
2  * Copyright (c) 2005 - 2010, Nils R. Weller
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 #include "icode.h"
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <assert.h>
31 #include <stdarg.h>
32 #include <string.h>
33 #include <ctype.h>
34 #include <sys/mman.h>
35 #include <unistd.h>
36 #include "misc.h"
37 #include "token.h"
38 #include "control.h"
39 #include "decl.h"
40 #include "type.h"
41 #include "debug.h"
42 #include "defs.h"
43 #include "expr.h"
44 #include "error.h"
45 #include "subexpr.h"
46 #include "icode.h"
47 #include "symlist.h"
48 #include "typemap.h"
49 #include "reg.h"
50 #include "functions.h"
51 #include "backend.h" /* for get_sizeof() */
52 #include "scope.h"
53 #include "zalloc.h"
54 #include "cc1_main.h" /* flags */
55 #include "inlineasm.h"
56 #include "n_libc.h"
57 
58 struct icode_instr *
alloc_icode_instr(void)59 alloc_icode_instr(void) {
60 	static unsigned long seq;
61 
62 #if USE_ZONE_ALLOCATOR
63 	struct icode_instr	*ret = zalloc_buf(Z_ICODE_INSTR);
64 
65 	ret->seqno = ++seq;
66 
67 	return ret;
68 #else
69 	struct icode_instr	*ret = n_xmalloc(sizeof *ret);
70 	static struct icode_instr	nullinstr;
71 
72 	*ret = nullinstr;
73 	ret->seqno = ++seq;
74 	return ret;
75 #endif
76 }
77 
78 struct icode_list *
alloc_icode_list(void)79 alloc_icode_list(void) {
80 #if USE_ZONE_ALLOCATOR
81 	return zalloc_buf(Z_ICODE_LIST);
82 #else
83 	struct icode_list	*ret = n_xmalloc(sizeof *ret);
84 	static struct icode_list	nullil;
85 	*ret = nullil;
86 	return ret;
87 #endif
88 }
89 
90 struct icode_instr *
copy_icode_instr(struct icode_instr * ii)91 copy_icode_instr(struct icode_instr *ii) {
92 	struct icode_instr	*ret = alloc_icode_instr();
93 	*ret = *ii;
94 	return ret;
95 }
96 
97 void
append_icode_list(struct icode_list * list,struct icode_instr * instr)98 append_icode_list(struct icode_list *list, struct icode_instr *instr) {
99 	static unsigned long	append_seqno;
100 
101 	instr->append_seqno = ++append_seqno;
102 	if (list->tail == NULL) {
103 		list->head = list->tail = instr;
104 	} else {
105 		list->tail->next = instr;
106 		list->tail = instr;
107 	}
108 
109 	/*
110 	 * XXX stuff below is a kludge to ensure that pointer pregs are
111 	 * always recorded properly
112 	 */
113 	if (instr->src_vreg && instr->src_ptr_preg == NULL) {
114 		if (instr->src_vreg->from_ptr) {
115 			instr->src_ptr_preg
116 				= instr->src_vreg->from_ptr->pregs[0];
117 		} else if (instr->src_vreg->parent) {
118 			struct vreg	*vr2 =
119 				get_parent_struct(instr->src_vreg);
120 
121 			/*
122 			 * 25/12/07: Always save parent struct, not
123 			 * just for pointers. Hmm, that raises the
124 			 * question of how reliable vr->parent is
125 			 * guaranteed to be in the backend anyway?
126 			 */
127 			instr->src_parent_struct = vr2;
128 			if (vr2->from_ptr) {
129 				instr->src_ptr_preg
130 					= vr2->from_ptr->pregs[0];
131 			}
132 		}
133 	}
134 	if (instr->dest_vreg && instr->dest_ptr_preg == NULL) {
135 		if (instr->dest_vreg->from_ptr) {
136 			instr->dest_ptr_preg
137 				= instr->dest_vreg->from_ptr->pregs[0];
138 		} else if (instr->dest_vreg->parent) {
139 			struct vreg	*vr2 =
140 				get_parent_struct(instr->dest_vreg);
141 			if (vr2->from_ptr) {
142 				instr->dest_parent_struct = vr2;
143 				instr->dest_ptr_preg
144 					= vr2->from_ptr->pregs[0];
145 			}
146 		}
147 	}
148 	if (instr->type == INSTR_COPYSTRUCT) {
149 		struct copystruct	*cs = instr->dat;
150 		struct vreg		*structtop;
151 
152 		if (cs->src_vreg && cs->src_vreg->parent) {
153 			structtop = get_parent_struct(cs->src_vreg);
154 
155 			/* 12/25/07: Always save, not just for pointers */
156 			instr->src_parent_struct = structtop;
157 			if (structtop->from_ptr) {
158 				instr->src_ptr_preg =
159 					structtop->from_ptr->pregs[0];
160 			}
161 		}
162 		if (cs->dest_vreg && cs->dest_vreg->parent) {
163 			structtop = get_parent_struct(cs->dest_vreg);
164 			if (structtop->from_ptr) {
165 				instr->dest_parent_struct = structtop;
166 				instr->dest_ptr_preg =
167 					structtop->from_ptr->pregs[0];
168 			}
169 		}
170 	}
171 }
172 
173 void
merge_icode_lists(struct icode_list * dest,struct icode_list * src)174 merge_icode_lists(struct icode_list *dest, struct icode_list *src) {
175 	if (src->head == NULL) {
176 		/* XXX ??? */
177 		dest->res = src->res;
178 		return;
179 	}
180 	if (dest->head == NULL) {
181 		if (dest->tail != NULL) {
182 			puts("icode list corruption detected");
183 			exit(EXIT_FAILURE);
184 		}
185 		dest->head = src->head;
186 		dest->tail = src->tail;
187 	} else {
188 		dest->tail->next = src->head;
189 		if (src->tail != NULL) {
190 			dest->tail = src->tail;
191 		}
192 	}
193 	dest->res = src->res;
194 }
195 
196 struct reg **
make_icode_pregs(struct vreg * vr,struct reg * r)197 make_icode_pregs(struct vreg *vr, struct reg *r) {
198 	struct reg	**ret;
199 
200 	if (vr == NULL || !vr->is_multi_reg_obj) {
201 		ret = n_xmalloc(2 * sizeof *ret);
202 		ret[0] = vr? vr->pregs[0]: r;
203 		ret[1] = NULL;
204 	} else {
205 		ret = n_xmalloc(vr->is_multi_reg_obj * sizeof *ret);
206 		if (vr->is_multi_reg_obj != 2) abort();
207 		/* XXX hardcoded x86 */
208 		ret[0] = vr->pregs[0];
209 		ret[1] = vr->pregs[1];
210 	}
211 
212 	return ret;
213 }
214 
215 struct icode_instr *
generic_icode_make_instr(struct vreg * dest,struct vreg * src,int type)216 generic_icode_make_instr(struct vreg *dest, struct vreg *src, int type) {
217 	struct icode_instr	*ret = alloc_icode_instr();
218 	ret->type = type;
219 	ret->dest_vreg = dest;
220 	if (dest != NULL) {
221 		ret->dest_pregs = make_icode_pregs(dest, NULL);
222 	}
223 	ret->src_vreg = src;
224 	if (src != NULL) {
225 		ret->src_pregs = make_icode_pregs(src, NULL);
226 	}
227 	return ret;
228 }
229 
230 static unsigned long	lnum = 0;
231 
232 unsigned long
get_label_count(void)233 get_label_count(void) {
234 	return lnum;
235 }
236 
237 struct icode_instr *
icode_make_label(const char * name)238 icode_make_label(const char *name) {
239 	struct icode_instr	*ret;
240 	char			buf[1024];
241 
242 	ret = alloc_icode_instr();
243 	ret->type = INSTR_LABEL;
244 
245 	if (name == NULL) {
246 		sprintf(buf, "L%lu", lnum++);
247 		ret->dat = n_xstrdup(buf);
248 	} else {
249 		ret->dat = n_xstrdup(name);
250 	}
251 
252 	return ret;
253 }
254 
255 struct icode_instr *
icode_make_adj_allocated(int bytes)256 icode_make_adj_allocated(int bytes) {
257 	struct icode_instr	*ii = alloc_icode_instr();
258 
259 	ii->dat = n_xmemdup(&bytes, sizeof bytes);
260 	ii->type = INSTR_ADJ_ALLOCATED;
261 	return ii;
262 }
263 
264 struct icode_instr *
icode_make_setreg(struct reg * r,int value)265 icode_make_setreg(struct reg *r, int value) {
266 	struct icode_instr	*ret = alloc_icode_instr();
267 
268 	ret->type = INSTR_SETREG;
269 	ret->src_pregs = make_icode_pregs(NULL, r);
270 	ret->dat = n_xmemdup(&value, sizeof value); /* XXX :-( */
271 	return ret;
272 }
273 
274 struct icode_instr *
icode_make_freestack(size_t bytes)275 icode_make_freestack(size_t bytes) {
276 	struct icode_instr	*ret = alloc_icode_instr();
277 	ret->type = INSTR_FREESTACK;
278 	ret->dat = n_xmemdup(&bytes, sizeof bytes);
279 	return ret;
280 }
281 
282 
283 struct icode_instr *
icode_make_branch(struct icode_instr * dest,int btype,struct vreg * vr)284 icode_make_branch(struct icode_instr *dest, int btype, struct vreg *vr) {
285 	struct icode_instr	*ret = alloc_icode_instr();
286 	ret->type = btype;
287 	ret->dat = dest;
288 	ret->dest_vreg = vr;
289 	return ret;
290 }
291 
292 struct icode_instr *
icode_make_call(const char * name)293 icode_make_call(const char *name) {
294 	struct icode_instr	*ret = alloc_icode_instr();
295 	ret->type = INSTR_CALL;
296 	ret->dat = (char *)name;
297 	return ret;
298 }
299 
300 struct icode_instr *
icode_make_call_indir(struct reg * r)301 icode_make_call_indir(struct reg *r) {
302 	struct icode_instr	*ret = alloc_icode_instr();
303 	ret->type = INSTR_CALLINDIR;
304 	ret->dat = r;
305 	return ret;
306 }
307 
308 void
icode_make_xchg(struct reg * r1,struct reg * r2,struct icode_list * il)309 icode_make_xchg(struct reg *r1, struct reg *r2, struct icode_list *il) {
310 	struct icode_instr	*ret = alloc_icode_instr();
311 
312 	ret->type = INSTR_XCHG;
313 	ret->src_pregs = make_icode_pregs(NULL, r1);
314 	ret->dest_pregs = make_icode_pregs(NULL, r2);
315 	append_icode_list(il, ret);
316 }
317 
318 void
icode_make_initialize_pic(struct function * f,struct icode_list * il)319 icode_make_initialize_pic(struct function *f, struct icode_list *il) {
320 	struct icode_instr	*ret = alloc_icode_instr();
321 
322 	ret->type = INSTR_INITIALIZE_PIC;
323 	ret->dat = f;
324 	append_icode_list(il, ret);
325 }
326 
327 static struct icode_instr *
icode_make_load_vla(struct reg * r,struct type * ty)328 icode_make_load_vla(struct reg *r, struct type *ty) {
329 	struct icode_instr	*ii = alloc_icode_instr();
330 
331 	ii->type = INSTR_LOAD_VLA;
332 	ii->dest_pregs = make_icode_pregs(NULL, r);
333 	ii->dat = ty;
334 	return ii;
335 }
336 
337 
338 
339 static struct reg *
icode_prepare_loadstore(int is_load,struct reg * r,struct vreg * vr,struct vreg * parent_struct,struct vreg * protectme,struct icode_list * il,int * is_stack0)340 icode_prepare_loadstore(int is_load,
341 	struct reg *r,
342 	struct vreg *vr,
343 	struct vreg *parent_struct,
344 	struct vreg *protectme,
345 	struct icode_list *il,
346 	int *is_stack0) {
347 
348 	struct reg		*ret = NULL;
349 	int			is_stack = 0;
350 
351 	/*
352 	 * Before any preparations are done, mark all other needed
353 	 * source/target registers unallocatable so they do not get
354 	 * trashed
355 	 *
356 	 * NOTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
357 	 * If we load a multi-GPR item, that is done by calling
358 	 * icode_make_load() multiple times! The caller must therefore
359 	 * mark subsequent registers unallocatable himself! Otherwise
360 	 * the first load will only protect the first register but
361 	 * may trash subsequent ones
362 	 */
363 	if (is_load) {
364 		reg_set_unallocatable(r);
365 	} else {
366 		reg_set_unallocatable(protectme->pregs[0]);
367 		if (protectme->is_multi_reg_obj) {
368 			reg_set_unallocatable(protectme->pregs[1]);
369 		}
370 	}
371 
372 	if (IS_THREAD(vr->type->flags)) {
373 		ret = ALLOC_GPR(curfunc, backend->get_ptr_size(),
374 			il, NULL);
375 	} else if (picflag && vreg_needs_pic_reloc(vr)) {
376 		if (backend->need_pic_init) {
377 			backend->icode_initialize_pic(curfunc, il);
378 			curfunc->pic_initialized = 1;
379 		}
380 		ret = ALLOC_GPR(curfunc, backend->get_ptr_size(),
381 			il, NULL);
382 	} else {
383 
384 		/*
385 	  	 * This is not a TLS- or PIC-load, so we should need
386 		 * no register at all, unless the offset is too large!
387 		 */
388 		if (arch_without_offset_limit()) {
389 			goto out;
390 		}
391 
392 		/*
393 		 * OK, we're on an arch with limited offsets. What we have
394 		 * to handle:
395 		 *
396 		 *    - Stack variables. This is terrible because currently
397 		 * the final offsets are computed when it's too late. Therefore
398 		 * we always have to ensure that one register is allocated when
399 		 * we load/store a stack variable. This SUCKS and must be
400 		 * fixed!
401 		 *
402 		 *    - Anonymous stack items (usually registers) - like for
403 		 * stack variables
404 		 *
405 		 *    - Static struct members. Here we can check whether the
406 		 * offset is too large and, if necessary, compute the address
407 		 * in a register
408 		 *
409 		 *    - Indirect struct members. Here we can check the offset
410 		 * and, if necessary, add it to the pointer register (which
411 		 * must already be resident)
412 		 */
413 		if (vr->var_backed != NULL) {
414 			if (vr->var_backed->dtype->storage == TOK_KEY_AUTO
415 				|| vr->var_backed->dtype->storage == 0) {
416 				is_stack = 1;
417 			} else if (vr->var_backed->dtype->storage !=
418 				TOK_KEY_REGISTER) {
419 				/*
420 				 * 12/24/07: Static variable! On some archs
421 				 * this always requires an extra register
422 				 */
423 				if (backend->arch == ARCH_SPARC) {
424 					if (is_load) {
425 						/*
426 						 * The target load register can
427 						 * be used to hold the address,
428 						 * UNLESS it is an FPR!
429 						 */
430 						if (is_floating_type(vr->type)) {
431 							ret = ALLOC_GPR(curfunc,
432 								backend->get_ptr_size(),
433 								il, NULL);
434 						}
435 					} else {
436 						/* XXX hmm already seems to be handled */
437 						;
438 					}
439 				} else if (backend->arch == ARCH_POWER) {
440 				} else if (backend->arch == ARCH_MIPS) {
441 				} else {
442 					/*
443 					 * 02/11/08: Woah that unimpl() seems
444 					 * a bit strong, disallowing all static
445 					 * variable access regardless of offset!
446 					 */
447 				/*	unimpl();*/
448 				}
449 			}
450 		} else if (parent_struct != NULL) {
451 			struct decl	*d = parent_struct->var_backed;
452 
453 			if (d != NULL
454 				&& vr->from_ptr == NULL
455 				&& (d->dtype->storage == TOK_KEY_AUTO
456 				|| d->dtype->storage == 0)) {
457 				is_stack = 1;
458 #if 0
459 			} else if (parent_struct->stack_addr != NULL) {
460 				is_stack = 1;
461 #endif
462 			} else if (vr->from_ptr || parent_struct->from_ptr || d != NULL) {
463 				/*
464 				 * Parent is pointer or static struct
465 				 */
466 				long	off;
467 
468 				off = calc_offsets(vr);
469 				if (off > backend->max_displacement) {
470 					/* Offset too big */
471 					ret = ALLOC_GPR(curfunc, backend->get_ptr_size(),
472 						il, NULL);
473 				}
474 			} else {
475 				unimpl();
476 			}
477 		} else if (vr->stack_addr != NULL) {
478 			is_stack = 1;
479 		}
480 
481 		if (is_stack) {
482 			ret = ALLOC_GPR(curfunc, backend->get_ptr_size(),
483 				il, NULL);
484 		}
485 	}
486 
487 out:
488 	*is_stack0 = is_stack;
489 
490 	/* Restore allocatability */
491 	if (is_load) {
492 		/*
493 		 * 07/13/09: This also restored allocatability for dedicated
494 		 * temp regs
495 		 */
496 		if (!r->dedicated) {
497 			reg_set_allocatable(r);
498 		}
499 	} else {
500 		if (!protectme->pregs[0]->dedicated) {
501 			reg_set_allocatable(protectme->pregs[0]);
502 		}
503 		if (protectme->is_multi_reg_obj) {
504 			if (!protectme->pregs[1]->dedicated) {
505 				reg_set_allocatable(protectme->pregs[1]);
506 			}
507 		}
508 	}
509 	return ret;
510 }
511 
512 struct vreg *
promote_bitfield(struct vreg * vr,struct icode_list * il)513 promote_bitfield(struct vreg *vr, struct icode_list *il) {
514 
515 	/*
516 	 * 08/09/08: If this is a signed bitfield member, perform sign
517 	 * extension on it! We can do this comfortably by shifting left,
518 	 * then right. This requires ``expected'' arithmetic shift right
519 	 * behavior, which is not standard but works on all supported
520 	 * architectures
521 	 */
522 	if (vr->type->tbit != NULL) {
523 		decode_bitfield(vr->type, vr, il);
524 		vr = vreg_disconnect(vr);
525 		vreg_do_anonymify(vr);
526 	}
527 	return vr;
528 }
529 
530 /*
531  * XXX pass vreg instead??
532  * Note that this really only deals with one register at a time -
533  * multi-register objects are dealt with in vreg_faultin()
534  */
535 void
icode_make_load(struct reg * r,struct vreg * parent_struct,int is_not_first_load,struct icode_list * il)536 icode_make_load(struct reg *r, struct vreg *parent_struct,
537 	int is_not_first_load, struct icode_list *il) {
538 
539 	struct icode_instr	*ret = alloc_icode_instr();
540 	struct vreg		*vr = r->vreg;
541 	static struct reg	*supportreg;
542 	int			is_stack = 0;
543 
544 #if 0
545 	if (vr->from_ptr == NULL
546 		&& vr->var_backed == NULL
547 		&& vr->stack_addr == NULL
548 		&& vr->parent == NULL) {
549 		printf("vr %p is unbacked!\n", vr);
550 		abort();
551 	}
552 #endif
553 	if (IS_VLA(vr->type->flags) && is_immediate_vla_type(vr->type)) {
554 		if (vr->from_ptr != NULL
555 			&& vr->from_ptr->type->tlist->type == TN_POINTER_TO) {
556 			/*
557 			 * 05/27/11: Loading VLA address through pointer to
558 			 * VLA;
559 			 *   char (*p)[expr] = ...
560 			 *   strcpy(*p, "hello");
561 			 * This is handled like an ordinary array load, i.e.
562 			 * the pointer already constitutes the address.
563 			 * XXX We should probably trash that icode_make_load_vla(0
564 			 * stuff and handle all VLA load instructions exactly
565 			 * like ordinary array load operations, and have the
566 			 * emitters sort out the access (accessing the metadata
567 			 * array address rather than a stack or static buffer).
568 			 * It's not clear (3 years after VLAs were introduced)
569 			 * why the distinction is so explicit in the frontend
570 			 * right now
571 			 */
572 			;
573 		} else {
574 			append_icode_list(il, icode_make_load_vla(r, vr->type));
575 			return;
576 		}
577 	}
578 
579 	if (vr->parent != NULL && parent_struct == NULL) {
580 		parent_struct = get_parent_struct(vr);
581 	}
582 
583 	/*
584 	 * 11/24/07: Time for some load preparations! In particular,
585 	 * build source address in a register if we are using large
586 	 * offsets on RISC, generating PIC, or accessing TLS.
587 	 */
588 	if (is_not_first_load) {
589 		/*
590 		 * This is the second (or later) part of a multi-register
591 		 * load; All preparations have already been done at the
592 		 * first load (supportreg is static)
593 		 */
594 		;
595 	} else {
596 		supportreg = icode_prepare_loadstore(1, r, vr,
597 			parent_struct, NULL, il, &is_stack);
598 	}
599 
600 	if (supportreg != NULL) {
601 		if (is_stack) {
602 			/*
603 			 * It's not yet clear whether the register is needed;
604 			 * Only save it just in case
605 			 */
606 			ret->dat = supportreg;
607 		} else {
608 			/*
609 			 * We definitely have to indirect
610 			 */
611 /*			struct icode_instr	*ii;*/
612 			struct vreg		*ptrvr;
613 
614 			/*ii =*/ (void) icode_make_addrof(supportreg, vr, il);
615 /*			append_icode_list(il, ii);*/
616 			ptrvr = vreg_back_by_ptr(vr, supportreg, 0);
617 			parent_struct = NULL;
618 			vr = ptrvr;
619 
620 #if 1
621 			if (sysflag == OS_OSX
622 				&& vr->type->tlist != NULL
623 				&& vr->type->tlist->type == TN_FUNCTION) {
624 				/*
625 				 * 02/08/09: When loading the address of a
626 				 * function on OSX, the initial load already
627 				 * computes the final function addres (i.e.
628 				 * it doesn't create a pointer through which
629 				 * we have to indirect to get the result
630 				 * pointer). So return that
631 				 *
632 				 * XXX This only applies to locally defined
633 				 * functions (_foo) and not nonlazy symbol
634 				 * references (L_foo$non_lazy_ptr).
635 				 * Currently we always create a non_lazy_ptr
636 			 	 * entry even for local functions. This may
637 				 * be undesirable
638 				 */
639 				icode_make_copyreg(r, supportreg, NULL, NULL, il);
640 				return;
641 			}
642 #endif
643 		}
644 	}
645 
646 	if (vr->from_const && vr->from_const->data2) {
647 		/* Too big to be immediate */
648 		struct ty_llong	*tll;
649 
650 		tll = vr->from_const->data2;
651 		tll->loaded = 1;
652 	}
653 	if (vr->type->code == TY_STRUCT && vr->type->tlist == NULL) {
654 		puts("BUG: Attempt to load struct into register :-(");
655 		abort();
656 	}
657 
658 	/*
659 	 * 12/07/07: Order matters!!!! In  foo->bar, the vreg has both
660 	 * from_ptr and parent set... Hmm.. why anyway?
661 	 */
662 	if (vr->from_ptr) {
663 		ret->src_ptr_preg = vr->from_ptr->pregs[0];
664 	} else if (vr->parent != NULL && parent_struct != NULL) {
665 		/* 12/25/07: Always save parent, not just for pointers */
666 		ret->src_parent_struct = parent_struct;
667 		if (parent_struct->from_ptr) {
668 			ret->src_ptr_preg =
669 				parent_struct->from_ptr->pregs[0];
670 		}
671 	}
672 
673 	ret->type = INSTR_LOAD;
674 	ret->src_vreg = vr;
675 	ret->src_pregs = make_icode_pregs(NULL, r);
676 	if (!vr->var_backed
677 		&& !vr->from_const
678 		&& !vr->from_ptr
679 		&& !vr->parent
680 		&& !vr->stack_addr) {
681 #if VREG_SEQNO
682 		printf("BUG: load from unbacked vreg %p [seq %d]\n", vr, vr->seqno);
683 #else
684 		printf("BUG: load from unbacked vreg %p\n", vr);
685 #endif
686 		printf("calling abort()\n");
687 		abort();
688 #if 0
689 	} else {
690 		debug_print_vreg_backing(vr);
691 #endif
692 	}
693 
694 	append_icode_list(il, ret);
695 
696 	if (supportreg != NULL) {
697 		if (!vr->is_multi_reg_obj || is_not_first_load) {
698 			free_preg(supportreg, il, 1, 0);
699 			supportreg = NULL;
700 		}
701 	}
702 }
703 
704 void
icode_make_load_addrlabel(struct reg * r,struct icode_instr * label,struct icode_list * il)705 icode_make_load_addrlabel(struct reg *r, struct icode_instr *label,
706 	struct icode_list *il) {
707 
708 	struct icode_instr	*ii;
709 
710 	ii = alloc_icode_instr();
711 	ii->dest_pregs = make_icode_pregs(NULL, r);
712 	ii->dat = label;
713 	ii->type = INSTR_LOAD_ADDRLABEL;
714 	append_icode_list(il, ii);
715 	if (backend->icode_prepare_load_addrlabel != NULL) {
716 		/*
717 		 * 12/25/08: For PPC: We have to create a TOC entry
718 		 * for the label
719 		 */
720 		backend->icode_prepare_load_addrlabel(label);
721 	}
722 }
723 
724 void
icode_make_comp_goto(struct reg * addr,struct icode_list * il)725 icode_make_comp_goto(struct reg *addr, struct icode_list *il) {
726 	struct icode_instr	*ii;
727 
728 	ii = alloc_icode_instr();
729 	ii->dat = addr;
730 	ii->type = INSTR_COMP_GOTO;
731 	append_icode_list(il, ii);
732 }
733 
734 
735 /*
736  * 04/07/08: Ripped this out of icode_make_store()
737  *
738  * This allocates us a stack block for saving registers. The
739  * list of blocks will be allocated later
740  *
741  * XXXXXXXXXXXXXXXXXXXXX Why do we have to go here to get
742  * convenient stack allocation which gives us a stack_block
743  * immediately (so it can be assigned to multiple vregs), and
744  * why is there no other nice way?
745  *
746  * Is there something that could break here? (Alignment)
747  *
748  * Should we generalize the concept?
749  */
750 struct stack_block *
icode_alloc_reg_stack_block(struct function * f,size_t size)751 icode_alloc_reg_stack_block(struct function *f, size_t size) {
752 	struct stack_block	*sb;
753 
754 	sb = make_stack_block(0, size);
755 
756 	if (f->regs_head == NULL) {
757 		f->regs_head = f->regs_tail = sb;
758 	} else {
759 		f->regs_tail->next = sb;
760 		f->regs_tail = f->regs_tail->next;
761 	}
762 	return sb;
763 }
764 
765 /*
766  * Store current item to virtual register vr
767  * XXX this is complete messed up
768  *    Store current item (INSTR_SETITEM) to vr
769  *
770  */
771 void
icode_make_store(struct function * f,struct vreg * dest,struct vreg * src,struct icode_list * il)772 icode_make_store(struct function *f,
773 	struct vreg *dest, struct vreg *src, /* XXX order is WRONG!! */
774 	struct icode_list *il) {
775 
776 	struct icode_instr	*ret = alloc_icode_instr();
777 	static struct reg	*supportreg;
778 	struct vreg		*parent = NULL;
779 	int			is_stack = 0;
780 
781 	if (src->parent != NULL) {
782 		parent = get_parent_struct(src);
783 		if (src->from_ptr || parent->from_ptr) {
784 			/*
785 			 * 12/12/07: This preparation of parent vreg and
786 			 * pointer was missing (but present in make_load!)
787 			 */
788 			ret->src_parent_struct = parent;
789 			if (src->from_ptr) {
790 				ret->src_ptr_preg = parent->pregs[0];
791 			} else {
792 				ret->src_ptr_preg = parent->from_ptr->pregs[0];
793 			}
794 		}
795 	}
796 
797 	/*
798 	 * 11/24/07: Time for some store preparations! In particular,
799 	 * build target address in a register if we are using large
800 	 * offsets on RISC, generating PIC, or accessing TLS.
801 	 */
802 	supportreg = icode_prepare_loadstore(0, NULL, src, parent,
803 			dest, il, &is_stack);
804 
805 	if (supportreg != NULL) {
806 		if (is_stack) {
807 			/*
808 			 * It's not yet clear whether the register is needed;
809 			 * Only save it just in case
810 			 */
811 			ret->dat = supportreg;
812 		} else {
813 			/*
814 			 * We definitely have to indirect
815 			 */
816 			/*struct icode_instr	*ii;*/
817 			struct vreg		*ptrvr;
818 
819 			/*ii =*/ (void) icode_make_addrof(supportreg, src, il);
820 /*			append_icode_list(il, ii);*/
821 			ptrvr = vreg_back_by_ptr(src, supportreg, 0);
822 		/*	parent_struct = NULL;*/
823 			src = ptrvr;
824 		}
825 	}
826 
827 	ret->type = INSTR_STORE;
828 	ret->dest_vreg = dest;
829 	ret->dest_pregs = make_icode_pregs(dest, NULL);
830 	ret->src_vreg = src;
831 
832 	if (src != NULL) {
833 		ret->src_pregs = make_icode_pregs(src, NULL);
834 		if (src->type->code == TY_STRUCT
835 			&& src->type->tlist == NULL) {
836 			puts("BUG: Attempt to store register to struct :-((((");
837 			abort();
838 		}
839 	}
840 
841 	/*
842 	 * 12/10/07: Added
843 	 */
844 	if (src->from_ptr) {
845 		ret->src_ptr_preg = src->from_ptr->pregs[0];
846 	} else if (src->parent != NULL && parent != NULL) {
847 		ret->src_parent_struct = parent;
848 		if (parent->from_ptr) {
849 			ret->src_ptr_preg = parent->from_ptr->pregs[0];
850 		}
851 	}
852 
853 	if (src != NULL
854 		&& !src->var_backed
855 		&& !src->from_ptr
856 		&& !src->from_const
857 		&& !src->parent) {
858 		/*
859 		 * Need to allocate anonymous storage
860 		 * for register
861 		 */
862 		if (src->stack_addr == NULL) {
863 			/* Offset will be patched later */
864 			/* XXX long long !?!?!!! */
865 			size_t	size = src->pregs[0]->size;
866 
867 			if (src->is_multi_reg_obj) {
868 				size += src->pregs[1]->size;
869 			} else if (backend->arch == ARCH_SPARC) {
870 				/*
871 				 * XXX hmm this seems wrong and ugly
872 				 */
873 				if (src->pregs[0]->type == REG_FPR) {
874 					switch (src->type->code) {
875 					case TY_FLOAT:
876 						size = 4;
877 						break;
878 					case TY_DOUBLE:
879 						size = 8;
880 						break;
881 					case TY_LDOUBLE:
882 						size = 16;
883 						break;
884 					default: unimpl();
885 					}
886 				}
887 			}
888 
889 			src->stack_addr = icode_alloc_reg_stack_block(f, size);
890 		}
891 	} else if (src->from_ptr) {
892 		vreg_faultin_protected(src, NULL, NULL, src->from_ptr, il, 0);
893 	}
894 	append_icode_list(il, ret);
895 
896 	if (supportreg != NULL) {
897 		free_preg(supportreg, il, 1, 0);
898 		supportreg = NULL;
899 	}
900 }
901 
902 
903 struct icode_instr *
icode_make_sub(struct vreg * dest,struct vreg * src)904 icode_make_sub(struct vreg *dest, struct vreg *src) {
905 	return generic_icode_make_instr(dest, src, INSTR_SUB);
906 }
907 
908 struct icode_instr *
icode_make_neg(struct vreg * vr)909 icode_make_neg(struct vreg *vr) {
910 	return generic_icode_make_instr(NULL, vr, INSTR_NEG);
911 }
912 
913 
914 struct icode_instr *
icode_make_add(struct vreg * dest,struct vreg * src)915 icode_make_add(struct vreg *dest, struct vreg *src) {
916 	return generic_icode_make_instr(dest, src, INSTR_ADD);
917 }
918 
919 struct icode_instr *
icode_make_div(struct vreg * dest,struct vreg * src)920 icode_make_div(struct vreg *dest, struct vreg *src) {
921 	return generic_icode_make_instr(dest, src, INSTR_DIV);
922 }
923 
924 struct icode_instr *
icode_make_mod(struct vreg * dest,struct vreg * src)925 icode_make_mod(struct vreg *dest, struct vreg *src) {
926 	return generic_icode_make_instr(dest, src, INSTR_MOD);
927 }
928 
929 struct icode_instr *
icode_make_mul(struct vreg * dest,struct vreg * src)930 icode_make_mul(struct vreg *dest, struct vreg *src) {
931 	return generic_icode_make_instr(dest, src, INSTR_MUL);
932 }
933 
934 struct icode_instr *
icode_make_shl(struct vreg * dest,struct vreg * src)935 icode_make_shl(struct vreg *dest, struct vreg *src) {
936 	return generic_icode_make_instr(dest, src, INSTR_SHL);
937 }
938 
939 struct icode_instr *
icode_make_shr(struct vreg * dest,struct vreg * src)940 icode_make_shr(struct vreg *dest, struct vreg *src) {
941 	return generic_icode_make_instr(dest, src, INSTR_SHR);
942 }
943 
944 struct icode_instr *
icode_make_and(struct vreg * dest,struct vreg * src)945 icode_make_and(struct vreg *dest, struct vreg *src) {
946 	return generic_icode_make_instr(dest, src, INSTR_AND);
947 }
948 
949 struct icode_instr *
icode_make_xor(struct vreg * dest,struct vreg * src)950 icode_make_xor(struct vreg *dest, struct vreg *src) {
951 	struct icode_instr	*ret = alloc_icode_instr();
952 	ret->type = INSTR_XOR;
953 	ret->dest_vreg = dest;
954 	ret->dest_pregs = make_icode_pregs(dest, NULL);
955 	if (src != NULL) {
956 		ret->src_pregs = make_icode_pregs(src, NULL);
957 	}
958 	ret->src_vreg = src;
959 	return ret;
960 }
961 
962 struct icode_instr *
icode_make_not(struct vreg * vr)963 icode_make_not(struct vreg *vr) {
964 	return generic_icode_make_instr(NULL, vr, INSTR_NOT);
965 }
966 
967 struct icode_instr *
icode_make_or(struct vreg * dest,struct vreg * src)968 icode_make_or(struct vreg *dest, struct vreg *src) {
969 	return generic_icode_make_instr(dest, src, INSTR_OR);
970 }
971 
972 void
icode_make_preg_or(struct reg * dest,struct reg * src,struct icode_list * il)973 icode_make_preg_or(struct reg *dest, struct reg *src, struct icode_list *il) {
974 	struct icode_instr	*ret = alloc_icode_instr();
975 	ret->type = INSTR_PREG_OR;
976 	ret->dest_pregs = make_icode_pregs(NULL, dest);
977 	ret->src_pregs = make_icode_pregs(NULL, src);
978 	append_icode_list(il, ret);
979 }
980 
981 struct icode_instr *
icode_make_push(struct vreg * vr,struct icode_list * il)982 icode_make_push(struct vreg *vr, struct icode_list *il) {
983 	struct icode_instr	*ret = alloc_icode_instr();
984 
985 	ret->type = INSTR_PUSH;
986 
987 	/*
988 	 * 12/06/07: Wow, the unconditional type->tlist->type check
989 	 * below crashed when passing ``ar[i]'' to printf(): The
990 	 * subscript operator removed the type node but kept the
991 	 * is_vla flag.
992 	 * XXX Maybe we should change that instead?
993 	 */
994 	if (vr->type && IS_VLA(vr->type->flags) && vr->type->tlist != NULL) {
995 		if (vr->type->tlist->type == TN_ARRAY_OF
996 			|| vr->type->tlist->type == TN_VARARRAY_OF) {
997 			struct reg		*r;
998 
999 			if (vr->pregs[0] == NULL
1000 				|| vr->pregs[0]->vreg != vr) {
1001 				r = ALLOC_GPR(curfunc, backend->get_ptr_size(),
1002 					il, 0);
1003 				vreg_map_preg(vr, r);
1004 				icode_make_load(r, NULL, 0, il);
1005 				free_preg(r, il, 0, 0);
1006 			}
1007 		}
1008 	}
1009 	ret->src_vreg = vr;
1010 	ret->src_pregs= make_icode_pregs(vr, NULL);
1011 
1012 	return ret;
1013 }
1014 
1015 struct icode_instr *
icode_make_ret(struct vreg * vr)1016 icode_make_ret(struct vreg *vr) {
1017 	struct icode_instr	*ret = alloc_icode_instr();
1018 	ret->type = INSTR_RET;
1019 #if 0
1020 	if (vr != NULL) {
1021 		/*ret->src_preg = vr->preg; seems never used*/
1022 		ret->src_vreg = vr;
1023 	}
1024 #endif
1025 	ret->src_vreg = vr;
1026 	return ret;
1027 }
1028 
1029 struct icode_instr *
icode_make_indir(struct reg * r)1030 icode_make_indir(struct reg *r) {
1031 	struct icode_instr	*ret = alloc_icode_instr();
1032 	ret->type = INSTR_INDIR;
1033 	ret->dat = r;
1034 	return ret;
1035 }
1036 
1037 /*
1038  * vr = NULL means take address of next argument on stack in
1039  * variadic function
1040  */
1041 struct reg * /*icode_instr **/
icode_make_addrof(struct reg * r,struct vreg * vr,struct icode_list * il)1042 icode_make_addrof(struct reg *r, struct vreg *vr, struct icode_list *il) {
1043 	struct icode_instr	*ret;
1044 
1045 	ret = alloc_icode_instr();
1046 	ret->type = INSTR_ADDROF;
1047 	ret->src_vreg = vr;
1048 
1049 	/*
1050 	 * 06/15/09: This was needed for stale parent struct pointers
1051 	 * and such
1052 	 */
1053 	if (vr != NULL) {
1054 		(void) vreg_faultin_ptr(vr, il);
1055 
1056 		/*
1057 		 * 02/01/10: This ``from pointer'' load does not
1058 		 * work to load the address of a function in PIC
1059 		 * mode! That type of load has to load a base
1060 		 * address, then load the final address
1061 		 * indirectly. This fails for functions because
1062 		 * vreg_faultin_ptr() will recurse to
1063 		 * icode_make_addrof(), and then things are
1064 		 * going to get trashed because the address is
1065 		 * already assumed to have been loaded, which it
1066 		 * hasn't.
1067 		 *
1068 		 * The solution is to avoid icode_make_addrof()
1069 		 * for that particular case (the address-of
1070 		 * handling for functions in subexpr.c just
1071 		 * uses vreg_faultin() instead). There may be
1072 		 * other cases as well
1073 		 */
1074 	}
1075 #if 0
1076 	ret->dat = backend->alloc_gpr(curfunc, 4, il, NULL); /* XXX */
1077 #endif
1078 	if (r != NULL) {
1079 		ret->dat = r;
1080 	} else {
1081 		ret->dat = ALLOC_GPR(curfunc, backend->get_ptr_size(),
1082 			il, NULL); /* XXX */
1083 	}
1084 
1085 	append_icode_list(il, ret);
1086 	return ret->dat;
1087 }
1088 
1089 struct icode_instr *
icode_make_inc(struct vreg * vr)1090 icode_make_inc(struct vreg *vr) {
1091 	return generic_icode_make_instr(NULL, vr, INSTR_INC);
1092 }
1093 
1094 struct icode_instr *
icode_make_dec(struct vreg * vr)1095 icode_make_dec(struct vreg *vr) {
1096 	return generic_icode_make_instr(NULL, vr, INSTR_DEC);
1097 }
1098 
1099 /*
1100  * =====================================================
1101  * x86-specific instructions
1102  * =====================================================
1103  */
1104 void
icode_make_x86_fxch(struct reg * r,struct reg * r2,struct icode_list * il)1105 icode_make_x86_fxch(struct reg *r, struct reg *r2, struct icode_list *il) {
1106 	struct icode_instr	*ret = alloc_icode_instr();
1107 	struct vreg		*tmp = r2->vreg;
1108 
1109 	ret->type = INSTR_X86_FXCH;
1110 	ret->src_pregs = make_icode_pregs(NULL, r);
1111 	ret->dest_pregs = make_icode_pregs(NULL, r2);
1112 	append_icode_list(il, ret);
1113 	if (r->vreg != NULL) {
1114 		r->vreg->pregs[0] = r2;
1115 		r2->vreg = r->vreg;
1116 	}
1117 	if (tmp != NULL) {
1118 		r->vreg = tmp;
1119 		r->vreg->pregs[0] = r;
1120 	}
1121 }
1122 
1123 void
icode_make_asm(struct inline_asm_stmt * inl,struct icode_list * il)1124 icode_make_asm(struct inline_asm_stmt *inl, struct icode_list *il) {
1125 	struct icode_instr	*ret = alloc_icode_instr();
1126 	ret->type = INSTR_ASM;
1127 	ret->dat = inl;
1128 	append_icode_list(il, ret);
1129 }
1130 
1131 void
icode_make_x86_cdq(struct icode_list * il)1132 icode_make_x86_cdq(struct icode_list *il) {
1133 	struct icode_instr	*ret = alloc_icode_instr();
1134 	ret->type = INSTR_X86_CDQ;
1135 	append_icode_list(il, ret);
1136 }
1137 
1138 void
icode_make_x86_ffree(struct reg * r,struct icode_list * il)1139 icode_make_x86_ffree(struct reg *r, struct icode_list *il) {
1140 	struct icode_instr	*ret = alloc_icode_instr();
1141 	ret->type = INSTR_X86_FFREE;
1142 	ret->src_pregs = make_icode_pregs(NULL, r);
1143 	append_icode_list(il, ret);
1144 }
1145 
1146 void
icode_make_x86_store_x87cw(struct vreg * vr,struct icode_list * il)1147 icode_make_x86_store_x87cw(struct vreg *vr, struct icode_list *il) {
1148 	struct icode_instr	*ii;
1149 
1150 	ii = generic_icode_make_instr(NULL, vr, INSTR_X86_FNSTCW);
1151 	append_icode_list(il, ii);
1152 }
1153 
1154 void
icode_make_x86_load_x87cw(struct vreg * vr,struct icode_list * il)1155 icode_make_x86_load_x87cw(struct vreg *vr, struct icode_list *il) {
1156 	struct icode_instr	*ii;
1157 
1158 	ii = generic_icode_make_instr(NULL, vr, INSTR_X86_FLDCW);
1159 	append_icode_list(il, ii);
1160 }
1161 
1162 void
icode_make_x86_fild(struct reg * r,struct vreg * vr,struct icode_list * il)1163 icode_make_x86_fild(struct reg *r,
1164 	struct vreg *vr, struct icode_list *il) {
1165 
1166 	struct icode_instr	*ii;
1167 	struct filddata		*fdat;
1168 
1169 	ii = generic_icode_make_instr(NULL, NULL, INSTR_X86_FILD);
1170 	fdat = n_xmalloc(sizeof *fdat);
1171 	fdat->r = r;
1172 	fdat->vr = vr;
1173 	ii->dat = fdat;
1174 	append_icode_list(il, ii);
1175 }
1176 
1177 void
icode_make_x86_fist(struct reg * r,struct vreg * vr,struct type * ty,struct icode_list * il)1178 icode_make_x86_fist(struct reg *r,
1179 	struct vreg *vr, struct type *ty, struct icode_list *il) {
1180 
1181 	struct icode_instr	*ii;
1182 	struct fistdata		*fdat;
1183 
1184 	ii = generic_icode_make_instr(NULL, NULL, INSTR_X86_FIST);
1185 	fdat = n_xmalloc(sizeof *fdat);
1186 	fdat->r = r;
1187 	fdat->vr = vr;
1188 	fdat->target_type = ty;
1189 	ii->dat = fdat;
1190 	append_icode_list(il, ii);
1191 }
1192 
1193 
1194 /*
1195  * =====================================================
1196  * MIPS-specific instructions
1197  * =====================================================
1198  */
1199 
1200 void
icode_make_mips_mtc1(struct reg * dest,struct vreg * src,struct icode_list * il)1201 icode_make_mips_mtc1(
1202 	struct reg *dest,
1203 	struct vreg *src,
1204 	struct icode_list *il) {
1205 	struct icode_instr	*ii;
1206 
1207 	ii = generic_icode_make_instr(NULL, src, INSTR_MIPS_MTC1);
1208 	ii->dat = dest;
1209 	append_icode_list(il, ii);
1210 }
1211 
1212 void
icode_make_mips_mfc1(struct reg * dest,struct vreg * src,struct icode_list * il)1213 icode_make_mips_mfc1(
1214 	struct reg *dest,
1215 	struct vreg *src,
1216 	struct icode_list *il) {
1217 	struct icode_instr	*ii;
1218 
1219 	ii = generic_icode_make_instr(NULL, src, INSTR_MIPS_MFC1);
1220 	ii->dat = dest;
1221 	append_icode_list(il, ii);
1222 }
1223 
1224 void
icode_make_mips_cvt(struct vreg * dest,struct vreg * src,struct icode_list * il)1225 icode_make_mips_cvt(
1226 	struct vreg *dest,
1227 	struct vreg *src,
1228 	struct icode_list *il) {
1229 
1230 	struct icode_instr	*ii;
1231 
1232 	ii = generic_icode_make_instr(dest, src, INSTR_MIPS_CVT);
1233 	append_icode_list(il, ii);
1234 }
1235 
1236 void
icode_make_mips_trunc(struct vreg * dest,struct vreg * src,struct icode_list * il)1237 icode_make_mips_trunc(
1238 	struct vreg *dest,
1239 	struct vreg *src,
1240 	struct icode_list *il) {
1241 
1242 	struct icode_instr	*ii;
1243 
1244 	ii = generic_icode_make_instr(dest, src, INSTR_MIPS_TRUNC);
1245 	append_icode_list(il, ii);
1246 }
1247 
1248 void
icode_make_mips_make_32bit_mask(struct reg * r,struct icode_list * il)1249 icode_make_mips_make_32bit_mask(struct reg *r, struct icode_list *il) {
1250 	struct icode_instr	*ii = alloc_icode_instr();
1251 
1252 	ii->type = INSTR_MIPS_MAKE_32BIT_MASK;
1253 	ii->dat = r;
1254 	append_icode_list(il, ii);
1255 }
1256 
1257 /*
1258  * =====================================================
1259  * PowerPC-specific instructions
1260  * =====================================================
1261  */
1262 void
icode_make_power_srawi(struct reg * dest,struct reg * src,int bits,struct icode_list * il)1263 icode_make_power_srawi(struct reg *dest, struct reg *src,
1264 	int bits, struct icode_list *il) {
1265 
1266 	struct icode_instr	*ii;
1267 
1268 	ii = generic_icode_make_instr(NULL, NULL, INSTR_POWER_SRAWI);
1269 	ii->dest_pregs = make_icode_pregs(NULL, dest);
1270 	ii->src_pregs = make_icode_pregs(NULL, src);
1271 	ii->dat = n_xmemdup(&bits, sizeof(int));
1272 	append_icode_list(il, ii);
1273 }
1274 
1275 void
icode_make_power_rldicl(struct reg * dest,struct reg * src,int bits,struct icode_list * il)1276 icode_make_power_rldicl(struct reg *dest, struct reg *src,
1277 	int bits, struct icode_list *il) {
1278 
1279 	struct icode_instr	*ii;
1280 
1281 	ii = generic_icode_make_instr(NULL, NULL, INSTR_POWER_RLDICL);
1282 	ii->dest_pregs = make_icode_pregs(NULL, dest);
1283 	ii->src_pregs = make_icode_pregs(NULL, src);
1284 	ii->dat = n_xmemdup(&bits, sizeof(int));
1285 	append_icode_list(il, ii);
1286 }
1287 
1288 void
icode_make_power_fcfid(struct reg * dest,struct reg * src,struct icode_list * il)1289 icode_make_power_fcfid(struct reg *dest, struct reg *src,
1290 	struct icode_list *il) {
1291 
1292 	struct icode_instr	*ii;
1293 
1294 	ii = generic_icode_make_instr(NULL, NULL, INSTR_POWER_FCFID);
1295 	ii->dest_pregs = make_icode_pregs(NULL, dest);
1296 	ii->src_pregs = make_icode_pregs(NULL, src);
1297 	append_icode_list(il, ii);
1298 }
1299 
1300 void
icode_make_power_frsp(struct reg * dest,struct icode_list * il)1301 icode_make_power_frsp(struct reg *dest, struct icode_list *il) {
1302 	struct icode_instr	*ii;
1303 
1304 	ii = generic_icode_make_instr(NULL, NULL, INSTR_POWER_FRSP);
1305 	ii->dat = dest;
1306 	append_icode_list(il, ii);
1307 }
1308 
1309 
1310 void
icode_make_power_slwi(struct reg * dest,struct reg * src,int bits,struct icode_list * il)1311 icode_make_power_slwi(struct reg *dest, struct reg *src,
1312 	int bits, struct icode_list *il) {
1313 	struct icode_instr	*ii;
1314 
1315 	ii = generic_icode_make_instr(NULL, NULL, INSTR_POWER_SLWI);
1316 	ii->dest_pregs = make_icode_pregs(NULL, dest);
1317 	ii->src_pregs = make_icode_pregs(NULL, src);
1318 	ii->dat = n_xmemdup(&bits, sizeof(int));
1319 	append_icode_list(il, ii);
1320 }
1321 
1322 void
icode_make_power_rlwinm(struct reg * dest,struct reg * src,int value,struct icode_list * il)1323 icode_make_power_rlwinm(struct reg *dest, struct reg *src, int
1324 	value, struct icode_list *il) {
1325 
1326 	struct icode_instr	*ii;
1327 
1328 	ii = generic_icode_make_instr(NULL, NULL, INSTR_POWER_RLWINM);
1329 	ii->dest_pregs = make_icode_pregs(NULL, dest);
1330 	ii->src_pregs = make_icode_pregs(NULL, src);
1331 	ii->dat = n_xmemdup(&value, sizeof(int));
1332 	append_icode_list(il, ii);
1333 }
1334 
1335 void
icode_make_power_extsb(struct reg * r,struct icode_list * il)1336 icode_make_power_extsb(struct reg *r, struct icode_list *il) {
1337 	struct icode_instr	*ii;
1338 
1339 	ii = generic_icode_make_instr(NULL, NULL, INSTR_POWER_EXTSB);
1340 	ii->dat = r;
1341 	append_icode_list(il, ii);
1342 }
1343 
1344 void
icode_make_power_extsh(struct reg * r,struct icode_list * il)1345 icode_make_power_extsh(struct reg *r, struct icode_list *il) {
1346 	struct icode_instr	*ii;
1347 
1348 	ii = generic_icode_make_instr(NULL, NULL, INSTR_POWER_EXTSH);
1349 	ii->dat = r;
1350 	append_icode_list(il, ii);
1351 }
1352 
1353 void
icode_make_power_extsw(struct reg * r,struct icode_list * il)1354 icode_make_power_extsw(struct reg *r, struct icode_list *il) {
1355 	struct icode_instr	*ii;
1356 
1357 	ii = generic_icode_make_instr(NULL, NULL, INSTR_POWER_EXTSW);
1358 	ii->dat = r;
1359 	append_icode_list(il, ii);
1360 }
1361 
1362 
1363 void
icode_make_power_xoris(struct reg * dest,int val,struct icode_list * il)1364 icode_make_power_xoris(struct reg *dest, int val, struct icode_list *il) {
1365 	struct icode_instr	*ii;
1366 
1367 	ii = generic_icode_make_instr(NULL, NULL, INSTR_POWER_XORIS);
1368 	ii->dest_pregs = make_icode_pregs(NULL, dest);
1369 	ii->dat = n_xmemdup(&val, sizeof(int));
1370 	append_icode_list(il, ii);
1371 }
1372 
1373 void
icode_make_power_lis(struct reg * dest,int val,struct icode_list * il)1374 icode_make_power_lis(struct reg *dest, int val, struct icode_list *il) {
1375 	struct icode_instr	*ii;
1376 
1377 	ii = generic_icode_make_instr(NULL, NULL, INSTR_POWER_LIS);
1378 	ii->dest_pregs = make_icode_pregs(NULL, dest);
1379 	ii->dat = n_xmemdup(&val, sizeof(int));
1380 	append_icode_list(il, ii);
1381 }
1382 
1383 void
icode_make_power_loadup4(struct reg * dest,struct vreg * src,struct icode_list * il)1384 icode_make_power_loadup4(struct reg *dest, struct vreg *src,
1385 	struct icode_list *il) {
1386 
1387 	struct icode_instr	*ii;
1388 
1389 	ii = generic_icode_make_instr(NULL, src, INSTR_POWER_LOADUP4);
1390 	ii->dest_pregs = make_icode_pregs(NULL, dest);
1391 	append_icode_list(il, ii);
1392 }
1393 
1394 void
icode_make_power_fctiwz(struct reg * r,int for_unsigned,struct icode_list * il)1395 icode_make_power_fctiwz(struct reg *r, int for_unsigned, struct icode_list *il) {
1396 	struct icode_instr	*ii;
1397 
1398 	ii = generic_icode_make_instr(NULL, NULL, INSTR_POWER_FCTIWZ);
1399 	ii->dat = r;
1400 	if (for_unsigned) {
1401 		ii->hints |= HINT_INSTR_GENERIC_MODIFIER;
1402 	}
1403 	append_icode_list(il, ii);
1404 }
1405 
1406 /*
1407  * =====================================================
1408  * SPARC-specific instructions
1409  * =====================================================
1410  */
1411 
1412 void
icode_make_sparc_load_int_from_ldouble(struct reg * dest,struct vreg * src,struct icode_list * il)1413 icode_make_sparc_load_int_from_ldouble(struct reg *dest,
1414 	struct vreg *src,
1415 	struct icode_list *il) {
1416 
1417 	struct icode_instr		*ii;
1418 
1419 	ii = generic_icode_make_instr(NULL, NULL,
1420 			INSTR_SPARC_LOAD_INT_FROM_LDOUBLE);
1421 	ii->src_vreg = src;
1422 	ii->dat = dest;
1423 	append_icode_list(il, ii);
1424 }
1425 
1426 /*
1427  * =====================================================
1428  * AMD64-specific instructions
1429  * =====================================================
1430  */
1431 void
icode_make_amd64_cvtsi2sd(struct reg * dest,struct vreg * src,struct icode_list * il)1432 icode_make_amd64_cvtsi2sd(
1433 	struct reg *dest,
1434 	struct vreg *src,
1435 	struct icode_list *il) {
1436 
1437 	struct icode_instr	*ii;
1438 
1439 	ii = generic_icode_make_instr(NULL, src, INSTR_AMD64_CVTSI2SD);
1440 	ii->dest_pregs = make_icode_pregs(NULL, dest);
1441 	append_icode_list(il, ii);
1442 }
1443 
1444 void
icode_make_amd64_cvtsi2sdq(struct reg * dest,struct vreg * src,struct icode_list * il)1445 icode_make_amd64_cvtsi2sdq(
1446 	struct reg *dest,
1447 	struct vreg *src,
1448 	struct icode_list *il) {
1449 
1450 	struct icode_instr	*ii;
1451 
1452 	ii = generic_icode_make_instr(NULL, src, INSTR_AMD64_CVTSI2SDQ);
1453 	ii->dest_pregs = make_icode_pregs(NULL, dest);
1454 	append_icode_list(il, ii);
1455 }
1456 
1457 void
icode_make_amd64_cvtsi2ssq(struct reg * dest,struct vreg * src,struct icode_list * il)1458 icode_make_amd64_cvtsi2ssq(
1459 	struct reg *dest,
1460 	struct vreg *src,
1461 	struct icode_list *il) {
1462 
1463 	struct icode_instr	*ii;
1464 
1465 	ii = generic_icode_make_instr(NULL, src, INSTR_AMD64_CVTSI2SSQ);
1466 	ii->dest_pregs = make_icode_pregs(NULL, dest);
1467 	append_icode_list(il, ii);
1468 }
1469 
1470 void
icode_make_amd64_cvtsi2ss(struct reg * dest,struct vreg * src,struct icode_list * il)1471 icode_make_amd64_cvtsi2ss(
1472 	struct reg *dest,
1473 	struct vreg *src,
1474 	struct icode_list *il) {
1475 
1476 	struct icode_instr	*ii;
1477 
1478 	ii = generic_icode_make_instr(NULL, src, INSTR_AMD64_CVTSI2SS);
1479 	ii->dest_pregs = make_icode_pregs(NULL, dest);
1480 	append_icode_list(il, ii);
1481 }
1482 
1483 void
icode_make_amd64_cvttss2si(struct reg * dest,struct reg * src,struct icode_list * il)1484 icode_make_amd64_cvttss2si(
1485 	struct reg *dest,
1486 	struct reg *src,
1487 	struct icode_list *il) {
1488 
1489 	struct icode_instr	*ii;
1490 
1491 	ii = generic_icode_make_instr(NULL, NULL, INSTR_AMD64_CVTTSS2SI);
1492 	ii->dest_pregs = make_icode_pregs(NULL, dest);
1493 	ii->src_pregs = make_icode_pregs(NULL, src);
1494 	append_icode_list(il, ii);
1495 }
1496 
1497 void
icode_make_amd64_cvttsd2si(struct reg * dest,struct reg * src,struct icode_list * il)1498 icode_make_amd64_cvttsd2si(
1499 	struct reg *dest,
1500 	struct reg *src,
1501 	struct icode_list *il) {
1502 
1503 	struct icode_instr	*ii;
1504 
1505 	ii = generic_icode_make_instr(NULL, NULL, INSTR_AMD64_CVTTSD2SI);
1506 	ii->dest_pregs = make_icode_pregs(NULL, dest);
1507 	ii->src_pregs = make_icode_pregs(NULL, src);
1508 	append_icode_list(il, ii);
1509 }
1510 
1511 void
icode_make_amd64_cvttss2siq(struct reg * dest,struct reg * src,struct icode_list * il)1512 icode_make_amd64_cvttss2siq(
1513         struct reg *dest,
1514         struct reg *src,
1515         struct icode_list *il) {
1516 
1517         struct icode_instr      *ii;
1518 
1519         ii = generic_icode_make_instr(NULL, NULL, INSTR_AMD64_CVTTSS2SIQ);
1520         ii->dest_pregs = make_icode_pregs(NULL, dest);
1521         ii->src_pregs = make_icode_pregs(NULL, src);
1522         append_icode_list(il, ii);
1523 }
1524 
1525 void
icode_make_amd64_cvtss2sd(struct reg * r,struct icode_list * il)1526 icode_make_amd64_cvtss2sd(struct reg *r, struct icode_list *il) {
1527 	struct icode_instr	*ii;
1528 
1529 	ii = generic_icode_make_instr(NULL, NULL, INSTR_AMD64_CVTSS2SD);
1530 	ii->dat = r;
1531 	append_icode_list(il, ii);
1532 }
1533 
1534 void
icode_make_amd64_cvttsd2siq(struct reg * dest,struct reg * src,struct icode_list * il)1535 icode_make_amd64_cvttsd2siq(
1536         struct reg *dest,
1537         struct reg *src,
1538         struct icode_list *il) {
1539 
1540         struct icode_instr      *ii;
1541 
1542         ii = generic_icode_make_instr(NULL, NULL, INSTR_AMD64_CVTTSD2SIQ);
1543         ii->dest_pregs = make_icode_pregs(NULL, dest);
1544         ii->src_pregs = make_icode_pregs(NULL, src);
1545         append_icode_list(il, ii);
1546 }
1547 
1548 
1549 void
icode_make_amd64_cvtsd2ss(struct reg * r,struct icode_list * il)1550 icode_make_amd64_cvtsd2ss(struct reg *r, struct icode_list *il) {
1551 	struct icode_instr	*ii;
1552 
1553 	ii = generic_icode_make_instr(NULL, NULL, INSTR_AMD64_CVTSD2SS);
1554 	ii->dat = r;
1555 	append_icode_list(il, ii);
1556 }
1557 
1558 void
icode_make_amd64_load_negmask(struct reg * dest,struct reg * support,int for_double,struct icode_list * il)1559 icode_make_amd64_load_negmask(struct reg *dest, struct reg *support, int for_double,
1560 	struct icode_list *il) {
1561 
1562 	struct icode_instr		*ii;
1563 	static struct vreg		dummyvr;
1564 	struct amd64_negmask_data	*dat = n_xmalloc(sizeof *dat);
1565 
1566 	ii = generic_icode_make_instr(NULL, NULL, INSTR_AMD64_LOAD_NEGMASK);
1567 /*	ii->dat = r;*/
1568 	dat->target_fpr = dest;
1569 	dat->support_gpr = support;
1570 	ii->dat = dat;
1571 
1572 	if (for_double) {
1573 		/* XXX ugly kludge to distinguish between float and double */
1574 		ii->src_vreg = &dummyvr;
1575 		amd64_need_negmask |= 2;
1576 	} else {
1577 		amd64_need_negmask |= 1;
1578 	}
1579 
1580 	append_icode_list(il, ii);
1581 }
1582 
1583 void
icode_make_amd64_xorps(struct vreg * dest,struct reg * src,struct icode_list * il)1584 icode_make_amd64_xorps(struct vreg *dest, struct reg *src, struct icode_list *il) {
1585 	struct icode_instr	*ii;
1586 
1587 	ii = generic_icode_make_instr(dest, NULL, INSTR_AMD64_XORPS);
1588 	ii->dat = src;
1589 	append_icode_list(il, ii);
1590 }
1591 
1592 void
icode_make_amd64_xorpd(struct vreg * dest,struct reg * src,struct icode_list * il)1593 icode_make_amd64_xorpd(struct vreg *dest, struct reg *src, struct icode_list *il) {
1594 	struct icode_instr	*ii;
1595 
1596 	ii = generic_icode_make_instr(dest, NULL, INSTR_AMD64_XORPD);
1597 	ii->dat = src;
1598 	append_icode_list(il, ii);
1599 }
1600 
1601 
1602 void
icode_make_amd64_ulong_to_float(struct reg * src_gpr,struct reg * temp,struct reg * dest_sse_reg,int code,struct icode_list * il)1603 icode_make_amd64_ulong_to_float(struct reg *src_gpr, struct reg *temp,
1604 	struct reg *dest_sse_reg, int code, struct icode_list *il) {
1605 
1606 	struct icode_instr		*ii;
1607 	struct amd64_ulong_to_float	*data = n_xmalloc(sizeof *data);
1608 
1609 	if (code == TY_LDOUBLE /* AMD64 */
1610 		|| backend->arch == ARCH_X86) {
1611 		amd64_need_ulong_float_mask = 1;
1612 	}
1613 
1614 	ii = generic_icode_make_instr(NULL, NULL, INSTR_AMD64_ULONG_TO_FLOAT);
1615 	data->src_gpr = src_gpr;
1616 	data->temp_gpr = temp;
1617 	data->dest_sse_reg = dest_sse_reg;
1618 	data->code = code;
1619 	ii->dat = data;
1620 	append_icode_list(il, ii);
1621 }
1622 
1623 struct icode_instr *
icode_make_seqpoint(struct var_access * stores)1624 icode_make_seqpoint(struct var_access *stores) {
1625 	struct icode_instr	*ret = alloc_icode_instr();
1626 	ret->type = INSTR_SEQPOINT;
1627 	ret->dat = stores;
1628 	return ret;
1629 }
1630 
1631 extern int lastmapseq;
1632 extern struct vreg *poi;
1633 
1634 void
icode_make_debug(struct icode_list * il,const char * fmt,...)1635 icode_make_debug(struct icode_list *il, const char *fmt, ...) {
1636 	struct icode_instr	*ret = alloc_icode_instr();
1637 	char			buf[2048];
1638 	va_list			va;
1639 
1640 #define EXTRAMSG 0
1641 #if EXTRAMSG
1642 	char 			extramsg[128];
1643 
1644 	*extramsg = 0;
1645 
1646 	if (poi)
1647 	sprintf(extramsg, " eax %p / poi %p  ->  %p   %p   ", x86_gprs[0].vreg,poi,poi->pregs[0],poi->pregs[1]);
1648 #endif
1649 
1650 	va_start(va, fmt);
1651 	vsprintf(buf, fmt, va);
1652 	va_end(va);
1653 
1654 #if EXTRAMSG
1655 	strcat(buf, extramsg);
1656 #endif
1657 
1658 	ret->type = INSTR_DEBUG;
1659 	ret->dat = n_xstrdup(buf);
1660 
1661 	append_icode_list(il, ret);
1662 }
1663 
1664 void
icode_make_dbginfo_line(struct statement * stmt,struct icode_list * il)1665 icode_make_dbginfo_line(struct statement *stmt, struct icode_list *il) {
1666 	struct icode_instr	*ii = NULL;
1667 	struct decl		*dec;
1668 	struct expr		*ex;
1669 
1670 	if (!gflag) return;
1671 
1672 	switch (stmt->type) {
1673 	case ST_CODE:
1674 		ii = alloc_icode_instr();
1675 		ii->type = INSTR_DBGINFO_LINE;
1676 		ex = stmt->data;
1677 		ii->dat = ex->tok;
1678 		break;
1679 	case ST_DECL:
1680 		/* A declaration with initializer has ``code'' */
1681 		dec = stmt->data;
1682 		if (dec->init != NULL) {
1683 			ii = alloc_icode_instr();
1684 			ii->type = INSTR_DBGINFO_LINE;
1685 			ex = dec->init->data;
1686 			ii->dat = ex->tok;
1687 		}
1688 		break;
1689 	default:
1690 		abort();
1691 	}
1692 	if (ii != NULL) { /* XXX */
1693 		append_icode_list(il, ii);
1694 	}
1695 }
1696 
1697 
1698 
1699 int	unimpl_instr;
1700 
1701 void
icode_make_unimpl(struct icode_list * il)1702 icode_make_unimpl(struct icode_list *il) {
1703 	struct icode_instr	*ii = alloc_icode_instr();
1704 
1705 	unimpl_instr = 1;
1706 	ii->type = INSTR_UNIMPL;
1707 	unimpl();
1708 	append_icode_list(il, ii);
1709 }
1710 
1711 void
icode_make_copyinit(struct decl * d,struct icode_list * il)1712 icode_make_copyinit(struct decl *d, struct icode_list *il) {
1713 	struct icode_instr	*ii = alloc_icode_instr();
1714 
1715 	ii->type = INSTR_COPYINIT;
1716 	ii->dat = d;
1717 	append_icode_list(il, ii);
1718 }
1719 
1720 
1721 void
icode_make_putstructregs(struct reg * firstreg,struct reg * ptrreg,struct vreg * vr,struct icode_list * il)1722 icode_make_putstructregs(struct reg *firstreg,
1723 	struct reg *ptrreg,
1724 	struct vreg *vr,
1725 	struct icode_list *il) {
1726 
1727 	struct icode_instr	*ii = alloc_icode_instr();
1728 	struct putstructregs	*ps = n_xmalloc(sizeof *ps);
1729 
1730 	ps->ptrreg = ptrreg;
1731 	ps->destreg = firstreg;
1732 	ps->src_vreg = vr;
1733 
1734 	ii->type = INSTR_PUTSTRUCTREGS;
1735 	ii->dat = ps;
1736 	append_icode_list(il, ii);
1737 }
1738 
1739 /*
1740  * Copy struct src to struct dest. Both may be automatic, static,
1741  * indirect, etc. If dest is a null pointer, then it is assumed that
1742  * the current function returns a structure type, and src will be
1743  * copied to the hidden pointer for struct returns (hidden_pointer
1744  * member of ``struct function''). This only works with the MIPS
1745  * backend right now.
1746  *
1747  * If any argument comes from a pointer, that pointer will be loaded
1748  * into a register as necessary. Note that most backends currently
1749  * call memcpy() to copy structs, so it is essential to save all GPRs
1750  * as necessary (backend->invalidate_gprs().) Perhaps it would make
1751  * sense to add a backend->prepare_copystruct() for register saving.
1752  *
1753  * XXX seems dest_preg and src_preg are never used and conceptually
1754  * totally nonsense because a struct is never gpr-resident
1755  */
1756 void
icode_make_copystruct(struct vreg * dest,struct vreg * src,struct icode_list * il)1757 icode_make_copystruct(
1758 	struct vreg *dest,
1759 	struct vreg *src,
1760 	struct icode_list *il) {
1761 
1762 	struct icode_instr	*ii = alloc_icode_instr();
1763 	struct copystruct		*cs;
1764 	struct vreg			*stop;
1765 	static struct copystruct	nullcs;
1766 
1767 
1768 	/*
1769 	 * 05/22/11: Zero-sized arrays are possible in GNU C;
1770 	 *   struct foo { char x[0]; }
1771 	 * A gcc test suite case uses this and causes a crash
1772 	 * when passing such a struct to a function
1773 	 */
1774 	if (src->size == 0) {
1775 		/* Empty struct - nothing to do */
1776 		return;
1777 	}
1778 
1779 	cs = n_xmalloc(sizeof *cs);
1780 	*cs = nullcs;
1781 
1782 	/* If source is indirect, do not trash pointer register */
1783 	vreg_set_unallocatable(src);
1784 
1785 	cs->dest_vreg = dest;
1786 	if (dest != NULL) {
1787 		vreg_faultin_ptr(dest, il);
1788 		cs->dest_preg = dest->pregs[0];
1789 		if (dest->from_ptr) {
1790 			cs->dest_from_ptr = dest->from_ptr->pregs[0];
1791 		} else if (dest->parent
1792 			&& (stop = get_parent_struct(dest))->from_ptr) {
1793 			cs->dest_from_ptr = NULL;
1794 			cs->dest_from_ptr_struct = stop->from_ptr->pregs[0];
1795 		} else {
1796 			cs->dest_from_ptr = NULL;
1797 		}
1798 		vreg_set_unallocatable(dest);
1799 	}
1800 	cs->src_vreg = src;
1801 	cs->src_preg = src->pregs[0];
1802 
1803 	vreg_faultin_ptr(src, il);
1804 	vreg_set_allocatable(src);
1805 	if (dest != NULL) {
1806 		vreg_set_allocatable(dest);
1807 	}
1808 	if (src->from_ptr) {
1809 		cs->src_from_ptr = src->from_ptr->pregs[0];
1810 	} else if (src->parent
1811 		&& (stop = get_parent_struct(src))->from_ptr) {
1812 		cs->src_from_ptr = NULL;
1813 		cs->src_from_ptr_struct = stop->from_ptr->pregs[0];
1814 	} else {
1815 		cs->src_from_ptr = NULL;
1816 	}
1817 
1818 	if (backend->icode_make_structreloc) {
1819 		backend->icode_make_structreloc(cs, il);
1820 	}
1821 
1822 	ii->type = INSTR_COPYSTRUCT;
1823 	ii->dat = cs;
1824 	append_icode_list(il, ii);
1825 }
1826 
1827 /*
1828  * Intrinsically copy nbytes of src to dest. Currently dest and src must
1829  * be pointers or arrays. This is currently only used by __builtin_memcpy,
1830  * but should eventually replace INSTR_COPYSTRUCT and INSTR_COPYINIT.
1831  * If may_call_lib is set, the library memcpy() may be called, which
1832  * makes sense for huge data items (the primary point of __builtin_memcpy
1833  * is probably to avoid library dependencies.)
1834  */
1835 void
icode_make_intrinsic_memcpy_or_memset(int type,struct vreg * dest,struct vreg * src,struct vreg * nbytes,int may_call_lib,struct icode_list * il)1836 icode_make_intrinsic_memcpy_or_memset(int type,
1837 	struct vreg *dest,
1838 	struct vreg *src,
1839 	struct vreg *nbytes,
1840 	int may_call_lib,
1841 	struct icode_list *il) {
1842 
1843 	struct icode_instr	*ii = alloc_icode_instr();
1844 	struct int_memcpy_data	*imdata = n_xmalloc(sizeof *imdata);
1845 	struct reg		*dest_reg;
1846 	struct reg		*src_reg;
1847 	struct reg		*temp_reg;
1848 
1849 	ii->type = INSTR_INTRINSIC_MEMCPY;
1850 
1851 	imdata->type = type;
1852 	if (src->type->tlist == NULL
1853 		|| src->type->tlist == NULL) {
1854 		/*
1855 		 * In the future we should allow copying non-
1856 		 * pointer objects too (take the address here)
1857 		 * for convenient struct and initializer copying
1858 		 */
1859 		if (type == BUILTIN_MEMCPY) {
1860 			unimpl();
1861 		}
1862 	}
1863 
1864 
1865 	vreg_faultin_ptr(dest, il);
1866 	if (dest->from_ptr) {
1867 		dest_reg = dest->from_ptr->pregs[0];
1868 	} else {
1869 		/* Array or function */
1870 		dest_reg = dest->pregs[0];
1871 	}
1872 	reg_set_unallocatable(dest_reg);
1873 
1874 	if (type == BUILTIN_MEMCPY) {
1875 		vreg_faultin_ptr(src, il);
1876 		if (src->from_ptr) {
1877 			src_reg = src->from_ptr->pregs[0];
1878 		} else {
1879 			/* Array or function */
1880 			src_reg = src->pregs[0];
1881 		}
1882 	} else {
1883 		vreg_faultin(NULL, NULL, src, il, 0);
1884 		src_reg = src->pregs[0];
1885 	}
1886 	reg_set_unallocatable(src_reg);
1887 
1888 	/*
1889 	 * Now allocate temporary register for holding one byte. This
1890 	 * will be used for byte-wise simplistic copying by all
1891 	 * backends until more sophisticated implementations are
1892 	 * written. Then it will be time to have some sort of backend
1893 	 * flag which tells us whether such a temp reg is needed or
1894 	 * not, and what else may have to be done here
1895 	 *
1896 	 * 02/09/09: Allocation moved up before nbytes allocation.
1897 	 * This was needed on OSX with PIC code because otherwise we
1898 	 * may run out of GPRs. This is because ebx is reserved as PIC
1899 	 * register, eax to ecx may be allocated for the memcpy()
1900 	 * arguments, and then we have no registers left for the 1
1901 	 * byte temp reg because esi and edi are unusable for that
1902 	 * purpose! (Since they do not have 8bit sub registers)
1903 	 *
1904 	 * 02/09/09: OK this STILL failed in case there is only one
1905 	 * allocatable GPR, and that GPR was allocated the last time
1906 	 * alloc_gpr() got called.
1907 	 * So we have to relax the alloc_gpr() constraint which
1908 	 * prevents it from allocating the same GPR as during the
1909 	 * last invocation
1910 	 */
1911 	backend->relax_alloc_gpr_order = 1;
1912 	temp_reg = ALLOC_GPR(curfunc, 1, il, NULL);
1913 	backend->relax_alloc_gpr_order = 0;
1914 	if (temp_reg == NULL) {
1915 		(void) fprintf(stderr, "BUG: Cannot allocate GPR\n");
1916 		abort();
1917 	}
1918 
1919 	reg_set_unallocatable(temp_reg);
1920 
1921 	vreg_faultin(NULL, NULL, nbytes, il, 0);
1922 	reg_set_unallocatable(nbytes->pregs[0]);
1923 
1924 #if 0
1925 	/* 02/09/09: Allocation moved up */
1926 	/*
1927 	 * Now allocate temporary register for holding one byte. This
1928 	 * will be used for byte-wise simplistic copying by all
1929 	 * backends until more sophisticated implementations are
1930 	 * written. Then it will be time to have some sort of backend
1931 	 * flag which tells us whether such a temp reg is needed or
1932 	 * not, and what else may have to be done here
1933 	 */
1934 	temp_reg = ALLOC_GPR(curfunc, 1, il, NULL);
1935 #endif
1936 
1937 	reg_set_allocatable(dest_reg);
1938 	reg_set_allocatable(src_reg);
1939 	reg_set_allocatable(nbytes->pregs[0]);
1940 	reg_set_allocatable(temp_reg);
1941 
1942 	imdata->dest_addr = dest_reg;
1943 	imdata->src_addr = src_reg;
1944 	imdata->nbytes = nbytes->pregs[0];
1945 	imdata->temp_reg = temp_reg;
1946 	if (may_call_lib /*  && makes_sense_to_call_lib */) {
1947 		imdata->dest_addr->used = 0;
1948 		imdata->src_addr->used = 0;
1949 		imdata->nbytes->used = 0;
1950 		imdata->temp_reg->used = 0;
1951 		backend->invalidate_gprs(il, 1, INV_FOR_FCALL);
1952 	}
1953 	ii->dat = imdata;
1954 	append_icode_list(il, ii);
1955 }
1956 
1957 void
icode_make_dealloca(struct stack_block * sb,struct icode_list * il)1958 icode_make_dealloca(struct stack_block *sb, struct icode_list *il) {
1959 	struct icode_instr	*ii = alloc_icode_instr();
1960 	struct reg		*r;
1961 	struct type		*st;
1962 
1963 	st = backend->get_size_t();
1964 
1965 	r = backend->get_abi_reg(0, st);
1966 	if (r == NULL) {
1967 		r = ALLOC_GPR(curfunc, backend->get_sizeof_type(st, 0), il, 0);
1968 	}
1969 
1970 	ii->type = INSTR_DEALLOCA;
1971 	ii->src_pregs = make_icode_pregs(NULL, r);
1972 	ii->dat = sb;
1973 	append_icode_list(il, ii);
1974 }
1975 
1976 void
icode_make_alloca(struct reg * r,struct vreg * size_vr,struct stack_block * sb,struct icode_list * il)1977 icode_make_alloca(struct reg *r, struct vreg *size_vr,
1978 	struct stack_block *sb,
1979 	struct icode_list *il) {
1980 
1981 	struct allocadata	*a = n_xmalloc(sizeof *a);
1982 	struct icode_instr	*ii = alloc_icode_instr();
1983 
1984 	/*
1985 	 * First we unconditionally free the hidden pointer slot
1986 	 * for this allocation. Such that
1987 	 *
1988 	 *   for (i = 0; i < 10; ++i) {
1989 	 *      void *p = __builtin_alloca(20);
1990 	 *
1991 	 * ... always performs a free() before overwriting the
1992 	 * saved pointer with a newly allocated one. This is OK
1993 	 * even at the first call because the save area is
1994 	 * initialized to all-null-pointers, and free(NULL) is ok
1995 	 *
1996 	 * XXX 08/09/07: This is completely wrong. Removed the
1997 	 * free, thus repeated allocas leak memory now. But better
1998 	 * than not having it work at all
1999 	 */
2000 	backend->invalidate_gprs(il, 1, INV_FOR_FCALL);
2001 #if 0
2002 	icode_make_dealloca(sb, il);
2003 #endif
2004 
2005 	reg_set_unallocatable(r);
2006 	vreg_faultin(NULL, NULL, size_vr, il, 0);
2007 	a->result_reg = r;
2008 	a->size_reg = size_vr->pregs[0];
2009 	a->addr = sb;
2010 
2011 	ii->dat = a;
2012 	ii->type = INSTR_ALLOCA;
2013 
2014 	/*
2015 	 * Because the current implementation is carried out
2016 	 * using malloc() and free(), we have to save all
2017 	 * registers except for the size argument register!
2018 	 */
2019 	a->result_reg->used = 0;
2020 	a->size_reg->used = 0;
2021 	reg_set_allocatable(r);
2022 	backend->invalidate_gprs(il, 1, INV_FOR_FCALL);
2023 	append_icode_list(il, ii);
2024 #if 0
2025 	store_reg_to_stack_block(a->result_reg, a->addr);
2026 #endif
2027 }
2028 
2029 void
icode_make_dealloc_vla(struct stack_block * sb,struct icode_list * il)2030 icode_make_dealloc_vla(struct stack_block *sb, struct icode_list *il) {
2031 	struct icode_instr	*ii = alloc_icode_instr();
2032 
2033 #if 0
2034 	r = backend->get_abi_reg(0, st);
2035 	if (r == NULL) {
2036 		r = ALLOC_GPR(curfunc, backend->get_sizeof_type(st, 0), il, 0);
2037 	}
2038 #endif
2039 
2040 	ii->type = INSTR_DEALLOC_VLA;
2041 #if 0
2042 	ii->src_pregs = make_icode_pregs(NULL, r);
2043 #endif
2044 	ii->dat = sb;
2045 	append_icode_list(il, ii);
2046 }
2047 
2048 void
icode_make_alloc_vla(struct stack_block * sb,struct icode_list * il)2049 icode_make_alloc_vla(
2050 	struct stack_block *sb,
2051 	struct icode_list *il) {
2052 
2053 	struct allocadata	*a = n_xmalloc(sizeof *a);
2054 	struct icode_instr	*ii = alloc_icode_instr();
2055 
2056 	/*
2057 	 * First we unconditionally free the hidden pointer slot
2058 	 * for this allocation. Such that
2059 	 *
2060 	 *   for (i = 0; i < 10; ++i) {
2061 	 *      void *p = __builtin_alloca(20);
2062 	 *
2063 	 * ... always performs a free() before overwriting the
2064 	 * saved pointer with a newly allocated one. This is OK
2065 	 * even at the first call because the save area is
2066 	 * initialized to all-null-pointers, and free(NULL) is ok
2067 	 */
2068 	backend->invalidate_gprs(il, 1, INV_FOR_FCALL);
2069 	icode_make_dealloc_vla(sb, il);
2070 
2071 	ii->dat = sb;
2072 	ii->type = INSTR_ALLOC_VLA;
2073 
2074 	/*
2075 	 * Because the current implementation is carried out
2076 	 * using malloc() and free(), we have to save all
2077 	 * registers
2078 	 */
2079 	backend->invalidate_gprs(il, 1, INV_FOR_FCALL);
2080 	append_icode_list(il, ii);
2081 }
2082 
2083 void
icode_make_builtin_frame_address(struct reg * r,struct reg * r2,size_t * n,struct icode_list * il)2084 icode_make_builtin_frame_address(struct reg *r, struct reg *r2,
2085 	size_t *n, struct icode_list *il) {
2086 
2087 	struct icode_instr		*ii = alloc_icode_instr();
2088 	struct builtinframeaddressdata	*dat = n_xmalloc(sizeof *dat);
2089 
2090 	ii->type = INSTR_BUILTIN_FRAME_ADDRESS;
2091 	dat->result_reg = r;
2092 	dat->temp_reg = r2;
2093 	dat->count = n;
2094 
2095 	ii->dat = dat;
2096 	append_icode_list(il, ii);
2097 }
2098 
2099 
2100 void
icode_make_put_vla_whole_size(struct reg * size,struct stack_block * sb,struct icode_list * il)2101 icode_make_put_vla_whole_size(struct reg *size, struct stack_block *sb,
2102 	struct icode_list *il) {
2103 
2104 	struct icode_instr	*ii = alloc_icode_instr();
2105 	struct vlasizedata	*dat = n_xmalloc(sizeof *dat);
2106 
2107 	ii->type = INSTR_PUT_VLA_SIZE;
2108 	dat->size = size;
2109 	dat->offset = backend->get_ptr_size();
2110 	dat->blockaddr = sb;
2111 	ii->dat = dat;
2112 	append_icode_list(il, ii);
2113 }
2114 
2115 
2116 void
icode_make_put_vla_size(struct reg * size,struct stack_block * sb,int idx,struct icode_list * il)2117 icode_make_put_vla_size(struct reg *size, struct stack_block *sb,
2118 	int idx, struct icode_list *il) {
2119 
2120 	struct icode_instr	*ii = alloc_icode_instr();
2121 	struct vlasizedata	*dat = n_xmalloc(sizeof *dat);
2122 	int			offset;
2123 
2124 	offset = backend->get_ptr_size()
2125 		+ (1 + idx) * backend->get_sizeof_type(
2126 				make_basic_type(TY_ULONG), NULL);
2127 
2128 	ii->type = INSTR_PUT_VLA_SIZE;
2129 	dat->size = size;
2130 	dat->blockaddr = sb;
2131 	dat->offset = offset;
2132 	ii->dat = dat;
2133 	append_icode_list(il, ii);
2134 }
2135 
2136 struct vreg *
icode_make_retr_vla_size(struct reg * size,struct stack_block * sb,int idx,struct icode_list * il)2137 icode_make_retr_vla_size(struct reg *size, struct stack_block *sb,
2138 	int idx, struct icode_list *il) {
2139 
2140 	struct icode_instr	*ii = alloc_icode_instr();
2141 	struct vlasizedata	*dat = n_xmalloc(sizeof *dat);
2142 	struct vreg		*ret;
2143 	int			offset;
2144 
2145 	offset = backend->get_ptr_size()
2146 		+ (1 + idx) * backend->get_sizeof_type(
2147 				make_basic_type(TY_ULONG), NULL);
2148 
2149 
2150 	ii->type = INSTR_RETR_VLA_SIZE;
2151 	dat->size = size;
2152 	dat->blockaddr = sb;
2153 	dat->offset = offset;
2154 	ii->dat = dat;
2155 	append_icode_list(il, ii);
2156 	ret = vreg_alloc(NULL, NULL, NULL, NULL);
2157 	vreg_set_new_type(ret, make_basic_type(TY_ULONG));
2158 	vreg_map_preg(ret, size);
2159 	return ret;
2160 }
2161 
2162 void
icode_make_allocstack(struct vreg * vr,size_t size,struct icode_list * il)2163 icode_make_allocstack(struct vreg *vr, size_t size, struct icode_list *il) {
2164 	struct icode_instr	*ii = alloc_icode_instr();
2165 	struct allocstack	*as = n_xmalloc(sizeof *as);
2166 
2167 	as->nbytes = size;
2168 	as->patchme = vr;
2169 
2170 	ii->type = INSTR_ALLOCSTACK;
2171 	ii->dat = as;
2172 	append_icode_list(il, ii);
2173 }
2174 
2175 /*
2176  * XXX should this really deal with multi-gpr objects?!
2177  */
2178 struct icode_instr *
icode_make_cmp(struct vreg * dest,struct vreg * src)2179 icode_make_cmp(struct vreg *dest, struct vreg *src) {
2180 	struct icode_instr	*ret = alloc_icode_instr();
2181 
2182 	ret->type = INSTR_CMP;
2183 	ret->dest_vreg = dest;
2184 	ret->dest_pregs = make_icode_pregs(dest, NULL);
2185 	if (src != NULL) {
2186 		ret->src_pregs = make_icode_pregs(src, NULL);
2187 		ret->src_vreg = src;
2188 	}
2189 	return ret;
2190 }
2191 
2192 void
icode_make_extend_sign(struct vreg * vr,struct type * to,struct type * from,struct icode_list * il)2193 icode_make_extend_sign(struct vreg *vr, struct type *to, struct type *from,
2194 	struct icode_list *il) {
2195 
2196 	struct icode_instr	*ret = alloc_icode_instr();
2197 	struct extendsign	*data = n_xmalloc(sizeof *data);
2198 
2199 	data->dest_preg = vr->pregs[0];
2200 	data->dest_type = to;
2201 	data->src_type = from;
2202 	ret->dat = data;
2203 	ret->type = INSTR_EXTEND_SIGN;
2204 	append_icode_list(il, ret);
2205 }
2206 
2207 /* XXX misleading order of to/from :/ */
2208 void
icode_make_conv_fp(struct reg * destr,struct reg * srcr,struct type * to,struct type * from,struct icode_list * il)2209 icode_make_conv_fp(struct reg *destr, struct reg *srcr,
2210 	struct type *to, struct type *from,
2211 	struct icode_list *il) {
2212 
2213 	struct icode_instr	*ret = alloc_icode_instr();
2214 	struct extendsign	*data = n_xmalloc(sizeof *data);
2215 
2216 	data->dest_preg = destr;
2217 	data->src_preg = srcr;
2218 	data->dest_type = to;
2219 	data->src_type = from;
2220 	ret->dat = data;
2221 	ret->type = INSTR_CONV_FP;
2222 	append_icode_list(il, ret);
2223 }
2224 
2225 void
icode_make_conv_to_ldouble(struct vreg * dest,struct vreg * src,struct icode_list * il)2226 icode_make_conv_to_ldouble(struct vreg *dest, struct vreg *src,
2227 	struct icode_list *il) {
2228 
2229 	struct icode_instr	*ii;
2230 
2231 	ii = generic_icode_make_instr(dest, src, INSTR_CONV_TO_LDOUBLE);
2232 	append_icode_list(il, ii);
2233 }
2234 
2235 void
icode_make_conv_from_ldouble(struct vreg * dest,struct vreg * src,struct icode_list * il)2236 icode_make_conv_from_ldouble(struct vreg *dest, struct vreg *src,
2237 	struct icode_list *il) {
2238 
2239 	struct icode_instr	*ii;
2240 
2241 	ii = generic_icode_make_instr(dest, src, INSTR_CONV_FROM_LDOUBLE);
2242 	append_icode_list(il, ii);
2243 }
2244 
2245 
2246 struct icode_instr *
icode_make_jump(struct icode_instr * label)2247 icode_make_jump(struct icode_instr *label) {
2248 	struct icode_instr	*ret = alloc_icode_instr();
2249 	ret->type = INSTR_JUMP;
2250 	ret->dat = label;
2251 	return ret;
2252 }
2253 
2254 void
put_label_scope(struct label * l)2255 put_label_scope(struct label *l) {
2256 	struct statement	*stmt;
2257 
2258 	stmt = alloc_statement();
2259 	stmt->type = ST_LABEL;
2260 	stmt->data = l;
2261 	append_statement(
2262 		&curscope->code, &curscope->code_tail, stmt);
2263 	append_label_list(&curfunc->labels_head, &curfunc->labels_tail, l);
2264 }
2265 
2266 
2267 void
put_expr_scope(struct expr * e)2268 put_expr_scope(struct expr *e) {
2269 	struct statement	*stmt;
2270 
2271 	stmt = alloc_statement();
2272 	stmt->type = ST_CODE;
2273 	stmt->data = e;
2274 	append_statement(&curscope->code, &curscope->code_tail, stmt);
2275 }
2276 
2277 void
put_ctrl_scope(struct control * c)2278 put_ctrl_scope(struct control *c) {
2279 	struct statement	*stmt;
2280 
2281 	stmt = alloc_statement();
2282 	stmt->type = ST_CTRL;
2283 	stmt->data = c;
2284 	append_statement(&curscope->code, &curscope->code_tail, stmt);
2285 }
2286 
2287 /*
2288  * XXX acts as fxch for x86 fp...is this ok?
2289  */
2290 void
icode_make_copyreg(struct reg * dest,struct reg * src,struct type * desttype,struct type * srctype,struct icode_list * il)2291 icode_make_copyreg(
2292         struct reg *dest,
2293         struct reg *src,
2294         struct type *desttype,
2295         struct type *srctype,
2296         struct icode_list *il) {
2297 
2298         struct icode_instr      *ii = alloc_icode_instr();
2299         struct copyreg          *cr = n_xmalloc(sizeof *cr);
2300 
2301 if (dest->type != src->type) abort();
2302         cr->src_preg = src;
2303         cr->dest_preg = dest;
2304         cr->src_type = srctype;
2305         cr->dest_type = desttype;
2306 
2307         ii->type = INSTR_MOV;
2308         ii->dat = cr;
2309 
2310         append_icode_list(il, ii);
2311 }
2312 
2313 void
add_const_to_vreg(struct vreg * valist_vr,int size,struct icode_list * il)2314 add_const_to_vreg(struct vreg *valist_vr, int size, struct icode_list *il) {
2315 	struct token		*c;
2316 	struct vreg		*tmpvr;
2317 	struct icode_instr	*ii;
2318 
2319 	c = const_from_value(&size, NULL);
2320 	tmpvr = vreg_alloc(NULL, c, NULL, NULL);
2321 	vreg_faultin(NULL, NULL, tmpvr, il, 0);
2322 	vreg_faultin_protected(tmpvr, NULL, NULL, /*valist->vreg*/valist_vr, il, 0);
2323 	ii = icode_make_add(  /*valist->vreg*/valist_vr, tmpvr);
2324 	append_icode_list(il, ii);
2325 	icode_make_store(curfunc, /*valist->vreg*/valist_vr,
2326 		/*valist->vreg*/valist_vr, il);
2327 }
2328 
2329