1 /*
2  * Copyright (c) 2006 - 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  * MIPS backend
28  * XXX there is some SGI assembler specific stuff here which may or may not work
29  * with gas on Linux/MIPS
30  */
31 #include "backend.h"
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <stdarg.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <assert.h>
38 #include <limits.h>
39 #include "scope.h"
40 #include "decl.h"
41 #include "type.h"
42 #include "decl.h"
43 #include "icode.h"
44 #include "functions.h"
45 #include "control.h"
46 #include "debug.h"
47 #include "token.h"
48 #include "misc.h"
49 #include "error.h"
50 #include "functions.h"
51 #include "symlist.h"
52 #include "icode.h"
53 #include "stack.h"
54 #include "reg.h"
55 #include "subexpr.h"
56 #include "expr.h"
57 /* #include "x86_emit_gas.h" */
58 #include "inlineasm.h"
59 #include "mips_emit_as.h"
60 #include "cc1_main.h"
61 #include "features.h"
62 #include "n_libc.h"
63 
64 static FILE			*out;
65 struct emitter_mips	*emit_mips;
66 
67 #define N_GPRS 32
68 #define N_FPRS 32
69 
70 
71 struct reg		mips_gprs[N_GPRS];
72 static struct reg		mips_fprs[N_FPRS];
73 static struct vreg		saved_gprs[N_GPRS];
74 static struct stack_block	*saved_gprs_sb[N_GPRS];
75 
76 static int	callee_save_map[] = {
77 /* 0-3 */   0, 0, 0, 0,
78 /* 4-7 */   0, 0, 0, 0,
79 /* 8-11 */  0, 0, 0, 0,
80 /* 12-15 */ 0, 0, 0, 0,
81 /* 16-19 */ 1, 1, 1, 1, /* 16 - 23 = callee save temp */
82 /* 20-23 */ 1, 1, 1, 1,
83 /* 24-27 */ 0, 0, 0, 0,
84 /* 28-31 */ 0, 0, 1<<8, 0  /* 30 = callee save temp */
85 };
86 
87 static void
init_regs(void)88 init_regs(void) {
89 	int	i;
90 
91 	/* Registers are just named after their number */
92 	for (i = 0; i < N_GPRS; ++i) {
93 		static char *names[] = {
94 			"0", "1", "2", "3", "4", "5", "6", "7",
95 			"8", "9", "10", "11", "12", "13", "14", "15",
96 			"16", "17", "18", "19", "20", "21", "22", "23",
97 			"24", "25", "26", "27", "28", "29", "30", "31"
98 		};
99 		mips_gprs[i].type = REG_GPR;
100 		mips_gprs[i].allocatable = 1;
101 		mips_gprs[i].size = 8;
102 		mips_gprs[i].name = names[i];
103 	}
104 	for (i = 0; i < N_FPRS; ++i) {
105 		static char	*names[] = {
106 			"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
107 			"f8", "f9", "f10", "f11", "f12", "f13", "f14",
108 			"f15", "f16", "f17", "f18", "f19", "f20", "f21",
109 			"f22", "f23", "f24", "f25", "f26", "f27", "f28",
110 			"f29", "f30", "f31"
111 		};
112 		mips_fprs[i].type = REG_FPR;
113 		mips_fprs[i].allocatable = 1;
114 		mips_fprs[i].size = 8;
115 		mips_fprs[i].name = names[i];
116 	}
117 
118 	/* Some registers with predefined meaning should not be allocated */
119 	/* 07/13/09: Dedicated settings were missing */
120 	mips_gprs[0].allocatable = 0; /* zero register */
121 	reg_set_dedicated(&mips_gprs[0]);
122 	mips_gprs[1].allocatable = 0; /* assembler temporary register */
123 	reg_set_dedicated(&mips_gprs[1]);
124 	mips_gprs[26].allocatable = 0; /* kernel */
125 	reg_set_dedicated(&mips_gprs[26]);
126 	mips_gprs[27].allocatable = 0; /* kernel */
127 	reg_set_dedicated(&mips_gprs[27]);
128 	mips_gprs[28].allocatable = 0; /* gp */
129 	reg_set_dedicated(&mips_gprs[28]);
130 	mips_gprs[29].allocatable = 0; /* sp */
131 	reg_set_dedicated(&mips_gprs[29]);
132 	mips_gprs[30].allocatable = 0; /* frame pointer */
133 	reg_set_dedicated(&mips_gprs[30]);
134 	mips_gprs[31].allocatable = 0; /* return address */
135 	reg_set_dedicated(&mips_gprs[31]);
136 
137 	mips_gprs[25].allocatable = 0;
138 	tmpgpr = &mips_gprs[25];
139 	reg_set_dedicated(tmpgpr);
140 
141 	mips_gprs[24].allocatable = 0;
142 	tmpgpr2 = &mips_gprs[24];
143 	reg_set_dedicated(tmpgpr2);
144 
145 	if (picflag) {
146 		pic_reg = &mips_gprs[28];
147 		reg_set_dedicated(pic_reg);
148 	}
149 }
150 
151 
152 static void
do_invalidate(struct reg * r,struct icode_list * il,int save)153 do_invalidate(struct reg *r, struct icode_list *il, int save) {
154 	/* Neither allocatable nor used means SPECIAL register */
155 	if (!r->allocatable && !r->used) {
156 		return;
157 	}
158 	free_preg(r, il, 1, save);
159 }
160 
161 /*
162  * XXX Hm should distinguish between function calls and other
163  * invalidations
164  */
165 static void
invalidate_gprs(struct icode_list * il,int saveregs,int for_fcall)166 invalidate_gprs(struct icode_list *il, int saveregs, int for_fcall) {
167 	int	i;
168 
169 	(void) for_fcall;
170 	for (i = 0; i < N_GPRS; ++i) {
171 		do_invalidate(&mips_gprs[i], il, saveregs);
172 	}
173 	for (i = 0; i < N_FPRS; ++i) {
174 		do_invalidate(&mips_fprs[i], il, saveregs);
175 	}
176 }
177 
178 
179 static void
invalidate_except(struct icode_list * il,int save,int for_fcall,...)180 invalidate_except(struct icode_list *il, int save, int for_fcall,...) {
181 	int		i;
182 	struct reg	*except[8];
183 	struct reg	*arg;
184 	va_list		va;
185 
186 	va_start(va, for_fcall);
187 	for (i = 0; (arg = va_arg(va, struct reg *)) != NULL; ++i) {
188 		except[i] = arg;
189 	}
190 	va_end(va);
191 	except[i] = NULL;
192 
193 	for (i = 0; i < N_GPRS; ++i) {
194 		int	j;
195 
196 		for (j = 0; except[j] != NULL; ++j) {
197 			if (&mips_gprs[i] == except[j]) {
198 				break;
199 			}
200 		}
201 		if (except[j] != NULL) {
202 			continue;
203 		}
204 		do_invalidate(&mips_gprs[i], il, save);
205 	}
206 }
207 
208 static struct reg *
alloc_gpr(struct function * f,int size,struct icode_list * il,struct reg * dontwipe,int line)209 alloc_gpr(
210 	struct function *f,
211 	int size,
212 	struct icode_list *il,
213 	struct reg *dontwipe,
214 
215 	int line) {
216 	return generic_alloc_gpr(f,size,il,dontwipe,mips_gprs,N_GPRS,
217 		callee_save_map, line);
218 }
219 
220 static struct reg *
alloc_fpr(struct function * f,int size,struct icode_list * il,struct reg * dontwipe)221 alloc_fpr(struct function *f, int size, struct icode_list *il,
222 struct reg *dontwipe) {
223 	int			i;
224 	struct reg	*ret = NULL;
225 
226 	(void) f; (void) size; (void) il; (void) dontwipe;
227 
228 	for (i = 0; i < N_FPRS; ++i) {
229 		if (!mips_fprs[i].used && mips_fprs[i].allocatable) {
230 			ret = &mips_fprs[i];
231 			break;
232 		}
233 	}
234 	if (ret == NULL) {
235 #if 0
236 		puts("uh-huh your floating point code is too heavy");
237 		puts("sorry.");
238 		irix_abort();
239 #endif
240 		ret = &mips_fprs[12];
241 		free_preg(ret, il, 1, 1);
242 	}
243 	ret->used = 1; /* 07/16/09: Ouch, this was missing */
244 	return ret;
245 }
246 
247 static int
init(FILE * fd,struct scope * s)248 init(FILE *fd, struct scope *s) {
249 	out = fd;
250 
251 	init_regs();
252 
253 	if (asmflag && strcmp(asmname, "as") != 0) {
254 		(void) fprintf(stderr, "Unknown MIPS assembler `%s'\n",
255 			asmflag);
256 		exit(EXIT_FAILURE);
257 	}
258 	emit = &mips_emit_as;
259 	emit_mips = &mips_emit_mips_as;
260 	backend->emit = emit;
261 	return emit->init(out, s);
262 }
263 
264 static int
get_ptr_size(void)265 get_ptr_size(void) {
266 	if (backend->abi != ABI_MIPS_N64) {
267 		return 4;
268 	} else {
269 		return 8;
270 	}
271 }
272 
273 static struct type *
get_size_t(void)274 get_size_t(void) {
275 	if (backend->abi != ABI_MIPS_N64) {
276 		return make_basic_type(TY_UINT);
277 	} else {
278 		return make_basic_type(TY_ULONG);
279 	}
280 }
281 
282 static struct type *
get_uintptr_t(void)283 get_uintptr_t(void) {
284 	return make_basic_type(TY_ULONG);
285 }
286 
287 static struct type *
get_wchar_t(void)288 get_wchar_t(void) {
289 	return make_basic_type(TY_INT);
290 }
291 
292 
293 static size_t
get_sizeof_basic(int type)294 get_sizeof_basic(int type) {
295 	switch (type) {
296 	case TY_ENUM:
297 		return 4; /* XXX */
298 
299 	case TY_INT:
300 	case TY_UINT:
301 	case TY_LONG:
302 	case TY_ULONG:
303 		if (backend->abi == ABI_MIPS_N64) {
304 			if (IS_LONG(type)) {
305 				return 8;
306 			}
307 		}
308 		return 4;
309 
310 	case TY_LLONG:
311 	case TY_ULLONG:
312 		return 8;
313 
314 	case TY_CHAR:
315 	case TY_UCHAR:
316 	case TY_SCHAR:
317 	case TY_BOOL:
318 		return 1;
319 
320 	case TY_SHORT:
321 	case TY_USHORT:
322 		return 2;
323 
324 	case TY_FLOAT:
325 		return 4;
326 
327 	case TY_DOUBLE:
328 		return 8;
329 	case TY_LDOUBLE:
330 		return 16;
331 	default:
332 	printf("err sizeof cannot cope w/ it, wuz %d\n", type);
333 	irix_abort();
334 		return 1; /* XXX */
335 	}
336 }
337 
338 static void
do_ret(struct function * f,struct icode_instr * ip)339 do_ret(struct function *f, struct icode_instr *ip) {
340 	int	i;
341 
342 	if (f->alloca_head != NULL) {
343 		struct stack_block	*sb;
344 		static struct vreg	rvr;
345 
346 		rvr.stack_addr = f->alloca_regs;
347 		rvr.size = mips_gprs[0].size;
348 		backend_vreg_map_preg(&rvr, &mips_gprs[2]);
349 		emit->store(&rvr, &rvr);
350 		backend_vreg_unmap_preg(&mips_gprs[2]);
351 
352 		for (sb = f->alloca_head; sb != NULL; sb = sb->next) {
353 			emit->dealloca(sb, NULL);
354 		}
355 
356 		emit->load(&mips_gprs[2], &rvr);
357 	}
358 	if (f->vla_head != NULL) {
359 		struct stack_block	*sb;
360 		static struct vreg	rvr;
361 
362 		rvr.stack_addr = f->alloca_regs;
363 		rvr.size = mips_gprs[0].size;
364 		backend_vreg_map_preg(&rvr, &mips_gprs[2]);
365 		emit->store(&rvr, &rvr);
366 		backend_vreg_unmap_preg(&mips_gprs[2]);
367 
368 		for (sb = f->vla_head; sb != NULL; sb = sb->next) {
369 			emit->dealloc_vla(sb, NULL);
370 		}
371 
372 		emit->load(&mips_gprs[2], &rvr);
373 	}
374 	for (i = 0; i < N_GPRS; ++i) {
375 		if (saved_gprs[i].stack_addr != NULL) {
376 			emit->load(&mips_gprs[i], &saved_gprs[i]);
377 		}
378 	}
379 	emit->freestack(f, NULL);
380 	emit->ret(ip);
381 }
382 
383 static struct reg *
get_abi_reg(int index,struct type * ty)384 get_abi_reg(int index, struct type *ty) {
385 	if (index == 0) {
386 		if (is_integral_type(ty)
387 			|| ty->tlist != NULL) {
388 			return &mips_gprs[4];
389 		} else {
390 			unimpl();
391 		}
392 	} else {
393 		unimpl();
394 	}
395 	return NULL;
396 }
397 
398 static struct reg *
get_abi_ret_reg(struct type * ty)399 get_abi_ret_reg(struct type *ty) {
400 	if (is_integral_type(ty)
401 		|| ty->tlist != NULL) {
402 		if (backend->abi == ABI_MIPS_N32
403 			|| backend->abi == ABI_MIPS_N64) {
404 			return &mips_gprs[2];
405 		} else {
406 			unimpl();
407 		}
408 	} else {
409 		unimpl();
410 	}
411 	/* NOTREACHED */
412 	return NULL;
413 }
414 
415 /* XXX platform-independent?!?! used by amd64 */
416 void
417 store_preg_to_var(struct decl *d, size_t size, struct reg *r)
418 ;
419 #if 0
420 
421 {
422 	static struct vreg	vr;
423 
424 	vr.type = d->dtype;
425 	vr.size = size;
426 	vr.var_backed = d;
427 	vreg_map_preg(&vr, r);
428 	emit->store(&vr, &vr);
429 	r->used = 0;
430 }
431 #endif
432 
433 #define IS_UNION_OR_ARRAY(ty) \
434 	((ty->code == TY_UNION && ty->tlist == NULL) \
435 	 || (ty->tlist && ty->tlist->type == TN_ARRAY_OF))
436 
437 /* Get total size for struct field se, including alignment (except last) */
438 #define TOTAL_BYTES(se) \
439 	(se->next? se->next->dec->offset - se->dec->offset: \
440 	 backend->get_sizeof_type(se->dec->dtype, NULL))
441 
442 static void
align_stack(struct function * f,struct type * t,size_t size)443 align_stack(struct function *f, struct type *t, size_t size) {
444 	size_t	align;
445 
446 	align = backend->get_align_type(t);
447 	while ((f->total_allocated + size) % align) {
448 		++f->total_allocated;
449 	}
450 }
451 
452 static void
do_map_parameter(struct function * f,int * gprs_used,int * fprs_used,size_t * stack_bytes_used,struct sym_entry * se)453 do_map_parameter(
454 	struct function *f,
455 	int *gprs_used,
456 	int *fprs_used,
457 	size_t *stack_bytes_used,
458 	struct sym_entry *se) {
459 
460 	size_t			size;
461 	int			need_gpr_block = 0;
462 
463 	size = backend->get_sizeof_type(se->dec->dtype,0);
464 	if (is_integral_type(se->dec->dtype)
465 		|| se->dec->dtype->tlist != NULL) {
466 		if (*gprs_used < 8) {
467 			align_stack(f, se->dec->dtype, size);
468 #if 0
469 			se->dec->stack_addr
470 				= stack_malloc(f, size);
471 #endif
472 			if (*gprs_used == 0) {
473 				need_gpr_block = 1;
474 			}
475 			se->dec->stack_addr = make_stack_block(
476 				(8 - *gprs_used) * mips_gprs[0].size,
477 				size);
478 			se->dec->stack_addr->from_reg =
479 				&mips_gprs[4 + *gprs_used];
480 			++*gprs_used;
481 		} else {
482 			int	adjustment;
483 
484 			/*
485 			 * 07/23/09: 64bit argument slots are right-adjusted
486 			 * on big endian, left on little endian
487 			 */
488 			if (get_target_endianness() == ENDIAN_LITTLE) {
489 				adjustment = 0;
490 			} else {
491 				adjustment = 8 - size;
492 			}
493 			se->dec->stack_addr = make_stack_block(
494 				*stack_bytes_used + adjustment /*(8 - size)*/, size);
495 			*stack_bytes_used += 8;
496 		}
497 	} else if (IS_FLOATING(se->dec->dtype->code)) {
498 		if (se->dec->dtype->code == TY_LDOUBLE) {
499 			/* 07/20/09: Align long double */
500 			if (*fprs_used < 8) {
501 				/* Registers */
502 				if (*fprs_used & 1) {
503 					++*fprs_used;
504 				}
505 			} else {
506 				/* Stack */
507 				if (*stack_bytes_used & 15) {
508 					/* Not 16-byte-aligned */
509 					*stack_bytes_used += 8;
510 					assert((*stack_bytes_used & 15) == 0);
511 				}
512 			}
513 		}
514 
515 		if (*fprs_used < 8) {
516 			align_stack(f, se->dec->dtype, size);
517 			se->dec->stack_addr
518 				= stack_malloc(f, size);
519 			se->dec->stack_addr->from_reg =
520 				&mips_fprs[12 + *fprs_used];
521 			++*fprs_used;
522 			if (se->dec->dtype->code == TY_LDOUBLE) {
523 				++*fprs_used;
524 			}
525 		} else {
526 		/* XXX broken */
527 			se->dec->stack_addr = make_stack_block(
528 				*stack_bytes_used, size);
529 			if (size < 8) {
530 				/*
531 				 * 07/20/09: Floats take up an 8-byte
532 				 * slot as well
533 				 */
534 				*stack_bytes_used += mips_gprs[0].size;
535 			} else {
536 				*stack_bytes_used += size;
537 			}
538 		}
539 	} else if (se->dec->dtype->code == TY_STRUCT
540 		|| se->dec->dtype->code == TY_UNION) {
541 		int	temp;
542 
543 #if 0
544 		*stack_bytes_used += se->dec->dtype->tstruc->size;
545 #endif
546 		if (*gprs_used < 8) {
547 			/*
548 			 * Some parts of the struct are passed in one or
549 			 * more registers. This requires us to allocate
550 			 * backing storage for the registers (which must
551 			 * be located at the top of the stack frame)
552 			 */
553 			int	total_slots = size / mips_gprs[0].size;
554 
555 			if (*gprs_used == 0) {
556 				need_gpr_block = 1;
557 			}
558 
559 			if (total_slots * mips_gprs[0].size != size) {
560 				++total_slots;
561 			}
562 
563 			if (total_slots > 8 - *gprs_used) {
564 				total_slots = 8 - *gprs_used;
565 			}
566 
567 
568 			/* Allocate register backing block */
569 #if 0
570 			se->dec->stack_addr
571 				= stack_malloc(f, total_slots * mips_gprs[0].size);
572 #endif
573 			se->dec->stack_addr = make_stack_block(
574 				(8 - *gprs_used) * mips_gprs[0].size,
575 				size);
576 #if 0
577 			/*
578 			 * Now resize it to cover the whole struct (there may
579 			 * be data behind the register area which is already
580 			 * allocated on the stack) (Does this even make any
581 			 * difference at all?)
582 			 */
583 			se->dec->stack_addr->nbytes = size;
584 #endif
585 
586 			se->dec->stack_addr->from_reg =
587 				&mips_gprs[4+*gprs_used];
588 		} else {
589 			/*
590 			 * The entire struct is passed on the stack
591 			 */
592 			se->dec->stack_addr = make_stack_block(*stack_bytes_used,
593 				se->dec->dtype->tstruc->size);
594 		}
595 
596 		temp = se->dec->dtype->tstruc->size;
597 		while (temp > 0) {
598 			/*++*slots_used;*/
599 			if (*gprs_used >= 8) {
600 				break;
601 			}
602 			++*gprs_used;
603 			temp -= mips_gprs[0].size;
604 		}
605 
606 		if (temp > 0) {
607 			if (temp % mips_gprs[0].size) {
608 				temp += mips_gprs[0].size - (temp % mips_gprs[0].size);
609 			}
610 			*stack_bytes_used += temp;
611 		}
612 	} else {
613 		unimpl();
614 	}
615 	se->dec->stack_addr->is_func_arg = 1;
616 
617 	if (need_gpr_block) {
618 		(void) stack_malloc(f, 8 * mips_gprs[0].size);
619 	}
620 }
621 
622 static void
map_parameters(struct function * f,struct ty_func * proto)623 map_parameters(struct function *f, struct ty_func *proto) {
624 	int			i;
625 	int			gprs_used = 0;
626 	int			fprs_used = 0;
627 	size_t			stack_bytes_used = 0;
628 	struct sym_entry	*se;
629 
630 	if (f->fty->variadic) {
631 		/*
632 		 * Allocate enough storage for all registers. If none
633 		 * of the unprototyped variadic arguments are passed
634 		 * in registers (quite unlikely), then the allocation
635 		 * below is redundant
636 		 */
637 		f->fty->lastarg = alloc_decl();
638 		f->fty->lastarg->stack_addr = stack_malloc(f, 64);
639 	}
640 
641 	se = proto->scope->slist;
642 	if (f->proto->dtype->tlist->next == NULL
643 		&& (f->proto->dtype->code == TY_STRUCT
644 		|| f->proto->dtype->code == TY_UNION)) {
645 		/*
646 		 * Function returns struct/union - accomodate for
647 		 * hidden pointer (passed as first argument)
648 		 */
649 		size_t	ptrsize = backend->abi == ABI_MIPS_N64? 8: 4;
650 
651 		f->hidden_pointer = vreg_alloc(NULL, NULL, NULL, NULL);
652 		f->hidden_pointer->size = ptrsize;
653 		f->hidden_pointer->var_backed = alloc_decl();
654 		f->hidden_pointer->var_backed->dtype =
655 			n_xmemdup(f->proto->dtype, sizeof *f->proto->dtype);
656 		f->hidden_pointer->var_backed->dtype->tlist =
657 			alloc_type_node();
658 		f->hidden_pointer->var_backed->dtype->tlist->type =
659 			TN_POINTER_TO;
660 		f->hidden_pointer->type = f->hidden_pointer->var_backed->dtype;
661 #if 0
662 		f->hidden_pointer->var_backed->stack_addr =
663 			stack_malloc(f, ptrsize);
664 #endif
665 		/*
666 		 * 07/23/09: Just allocate a whole block for all 8 registers
667 		 * in case we pass struct-by-value or somesuch. This is usually
668 		 * done in do_map_parameter() when encountering the first
669 		 * register, but we take that one up here, so the block must
670 		 * be created here
671 		 *
672 		 * Note that we assign the 64 byte block here, but all other
673 		 * allocations requiring a GPR save area slot will hard-code
674 		 * an offset into this block
675 		 */
676 		f->hidden_pointer->var_backed->stack_addr =
677 			stack_malloc(f, 8 * mips_gprs[0].size);
678 		f->hidden_pointer->var_backed->stack_addr->from_reg =
679 			&mips_gprs[4];
680 		++gprs_used;
681 	}
682 
683 	/*
684 	 * Allocate stack space for those arguments that were
685 	 * passed in registers, set addresses to existing
686 	 * space for those that were passed on the stack
687 	 */
688 	for (i = 0; i < proto->nargs; ++i, se = se->next) {
689 		do_map_parameter(f, &gprs_used, &fprs_used,
690 			&stack_bytes_used, se);
691 	}
692 	if (f->fty->variadic) {
693 		if (gprs_used >= 8) {
694 			/* Wow, all variadic stuff passed on stack */
695 			f->fty->lastarg->stack_addr->offset =
696 				stack_bytes_used;
697 		} else {
698 			/*
699 			 * 64 bytes were allocated, skip as many as
700 			 * necessary
701 			 */
702 			f->fty->lastarg->stack_addr->offset -=
703 				gprs_used * 8;
704 			f->fty->lastarg->stack_addr->from_reg =
705 				&mips_gprs[4 + gprs_used];
706 		}
707 	}
708 }
709 
710 static void
make_local_variables(struct function * f)711 make_local_variables(struct function *f) {
712 	struct scope	*scope;
713 	int				i;
714 	size_t			size;
715 
716 	for (scope = f->scope; scope != NULL; scope = scope->next) {
717 		struct stack_block	*sb;
718 		struct scope		*tmp;
719 		struct decl		**dec;
720 		size_t			align;
721 
722 		for (tmp = scope; tmp != NULL; tmp = tmp->parent) {
723 			if (tmp == f->scope) {
724 				break;
725 			}
726 		}
727 
728 		if (tmp == NULL) {
729 			/* End of function reached */
730 			break;
731 		}
732 		if (scope->type != SCOPE_CODE) continue;
733 
734 		dec = scope->automatic_decls.data;
735 		for (i = 0; i < scope->automatic_decls.ndecls; ++i) {
736 			if (dec[i]->stack_addr != NULL) { /* XXX sucks */
737 				continue;
738 			} else if (IS_VLA(dec[i]->dtype->flags)) {
739                                 /*
740                                  * 05/22/11: Handle pointers to VLAs properly;
741                                  * We have to create a metadata block to
742                                  * record dimension sizes, but we allocate
743                                  * the pointers themselves on the stack
744                                  *
745                                  *   char (*p)[N];
746                                  *
747                                  * ... "p" on stack, N in metadata block
748                                  */
749                                 if (dec[i]->dtype->tlist->type == TN_POINTER_TO) {
750                                         ;
751                                 } else {
752                                         continue;
753                                 }
754 			}
755 
756 			size = backend->
757 				get_sizeof_decl(dec[i], NULL);
758 			align = backend->get_align_type(dec[i]->dtype);
759 			while ((f->total_allocated + size) % align) {
760 				++f->total_allocated;
761 			}
762 
763 			sb = stack_malloc(f, size/*+align*/);
764 			sb->nbytes = size;
765 			dec[i]->stack_addr = sb;
766 		}
767 	}
768 }
769 
770 static int
gen_function(struct function * f)771 gen_function(struct function *f) {
772 	unsigned int		mask;
773 	int			i;
774 	int			nsaved;
775 	char			*funcname;
776 	struct ty_func		*proto;
777 	struct scope		*scope;
778 	struct icode_instr	*lastret = NULL;
779 	struct stack_block	*sb;
780 	struct sym_entry	*se;
781 	size_t			alloca_bytes = 0;
782 	size_t			vla_bytes = 0;
783 
784 
785 	emit->setsection(SECTION_TEXT);
786 	/* XXX use emit->intro() ??? */
787 	x_fprintf(out, "\t.align 2\n");
788 	if (f->proto->dtype->storage != TOK_KEY_STATIC) {
789 		x_fprintf(out, "\t.globl %s\n", f->proto->dtype->name);
790 	}
791 	x_fprintf(out, "\t.ent %s\n", f->proto->dtype->name);
792 
793 	emit->label(f->proto->dtype->name, 1);
794 	funcname = f->proto->dtype->name;
795 
796 	proto = f->proto->dtype->tlist->tfunc;
797 
798 	map_parameters(f, proto);
799 
800 	stack_align(f, 16); /* 07/19/09: 16 bytes for long double */
801 	make_local_variables(f);
802 	stack_align(f, 16);
803 
804 	/*
805 	 * Allocate storage for saving callee-saved registers
806 	 * (but defer saving them until sp has been updated)
807 	 */
808 	nsaved = 0;
809 	for (mask = 1, i = 0; i < N_GPRS; ++i, mask <<= 1) {
810 		if ((f->callee_save_used & mask)
811 			|| i == 28 /* global pointer */
812 			|| i == 30 /* frame pointer */
813 			|| i == 31 /* return address */) {
814 #if ! USE_ZONE_ALLOCATOR
815 			/*
816 			 * 07/12/09: Whoops, not allocating a new block and
817 			 * setting the frame pointer flag breaks since the
818 			 * introduction of the zone allocator
819 			 */
820 			if (saved_gprs_sb[i] == NULL)
821 #endif
822 			{
823 				saved_gprs_sb[i] =
824 					make_stack_block(0, 8);
825 
826 				/*
827 				 * The frame pointer cannot be used yet
828 				 * because it needs to be saved as well
829 				 */
830 				saved_gprs_sb[i]->use_frame_pointer = 0;
831 			}
832 			f->total_allocated += 8;
833 			saved_gprs[i].stack_addr = saved_gprs_sb[i];
834 			saved_gprs[i].size = 8;
835 			saved_gprs[i].stack_addr->offset =
836 				f->total_allocated;
837 			++nsaved;
838 		} else {
839 			saved_gprs[i].stack_addr = NULL;
840 		}
841 	}
842 	f->callee_save_offset = f->total_allocated;
843 
844 	/*
845 	 * Allocate storage for temporarily saving GPRs. Offsets need to
846 	 * be patched once more when the size of the entire stack frame
847 	 * is known :-(
848 	 */
849 	for (sb = f->regs_head; sb != NULL; sb = sb->next) {
850 		stack_align(f, sb->nbytes);
851 		f->total_allocated += sb->nbytes;
852 		sb->offset = f->total_allocated;
853 	}
854 
855 	/*
856 	 * Allocate storage for saving alloca() pointers, and initialize
857 	 * it to zero (must be patched like temporary register storage)
858 	 */
859 	stack_align(f, mips_gprs[0].size);
860 	for (sb = f->alloca_head; sb != NULL; sb = sb->next) {
861 		f->total_allocated += sb->nbytes;
862 		alloca_bytes += sb->nbytes;
863 		sb->offset = f->total_allocated;
864 	}
865 
866 	/*
867 	 * Allocate storage for saving VLA data, and initialize
868 	 * it to zero (must be patched like temporary register storage)
869 	 */
870 	for (sb = f->vla_head; sb != NULL; sb = sb->next) {
871 		f->total_allocated += sb->nbytes;
872 		vla_bytes += sb->nbytes;
873 		sb->offset = f->total_allocated;
874 	}
875 
876 	stack_align(f, mips_gprs[0].size);
877 
878 	if (f->alloca_head != NULL || f->vla_head != NULL) {
879 		/*
880 		 * Get stack for saving return value register (r4) before
881 		 * performing free() on alloca()ted blocks
882 		 */
883 		f->alloca_regs = make_stack_block(0, mips_gprs[0].size);
884 		f->total_allocated += mips_gprs[0].size;
885 		f->alloca_regs->offset = f->total_allocated;
886 	}
887 
888 	stack_align(f, 16); /* 07/19/09: 16 bytes for long double */
889 
890 	if (f->total_allocated > 0) {
891 		emit->allocstack(f, f->total_allocated);
892 	}
893 
894 	/*
895 	 * Local variable offsets can only now be patched because the
896 	 * MIPS frame pointer points to the bottom of the frame, not
897 	 * the top, which is terrible.
898 	 */
899 	for (scope = f->scope; scope != NULL; scope = scope->next) {
900 		struct scope		*tmp;
901 		struct decl		**dec;
902 
903 		for (tmp = scope; tmp != NULL; tmp = tmp->parent) {
904 			if (tmp == f->scope) {
905 				break;
906 			}
907 		}
908 
909 		if (tmp == NULL) {
910 			/* End of function reached */
911 			break;
912 		}
913 		if (scope->type != SCOPE_CODE) continue;
914 
915 		dec = scope->automatic_decls.data;
916 		for (i = 0; i < scope->automatic_decls.ndecls; ++i) {
917 			if (IS_VLA(dec[i]->dtype->flags)) {
918 				/* XXX This ignores pointers to VLAs */
919 				continue;
920 			}
921 			if (dec[i]->stack_addr->is_func_arg
922 				&& !dec[i]->stack_addr->from_reg) {
923 				/*
924 				 * Argument passed on stack - needs different
925 				 * kind of patchery later
926 				 */
927 				continue;
928 			}
929 			dec[i]->stack_addr->offset =
930 				f->total_allocated - dec[i]->stack_addr->offset;
931 		}
932 	}
933 
934 	/*
935 	 * 07/19/09: hidden_pointer's address was patched in the loop (!) above
936 	 * so the offset ended up getting changed multiple times
937 	 */
938 	if (f->hidden_pointer) {
939 		f->hidden_pointer->var_backed->stack_addr->offset =
940 			f->total_allocated -
941 			f->hidden_pointer->var_backed->stack_addr->offset;
942 	}
943 
944 
945 #if 0 /* 07/20/09: This was apparently done twice! Done again below */
946 	if (f->fty->variadic) {
947 		f->fty->lastarg->stack_addr->offset =
948 			f->total_allocated -
949 			f->fty->lastarg->stack_addr->offset;
950 	}
951 #endif
952 
953 	se = proto->scope->slist;
954 
955 	for (sb = f->regs_head; sb != NULL; sb = sb->next) {
956 		sb->offset = f->total_allocated - sb->offset;
957 	}
958 	for (sb = f->alloca_head; sb != NULL; sb = sb->next) {
959 		sb->offset = f->total_allocated - sb->offset;
960 	}
961 	for (sb = f->vla_head; sb != NULL; sb = sb->next) {
962 		sb->offset = f->total_allocated - sb->offset;
963 	}
964 	if (f->alloca_head != NULL || f->vla_head != NULL) {
965 		f->alloca_regs->offset = f->total_allocated -
966 			f->alloca_regs->offset;
967 	}
968 
969 	/*
970 	 * Construct mask of saved registers (must be in little
971 	 * endian format)
972 	 */
973 	mask = 0;
974 	for (i = 0; i < N_GPRS; ++i) {
975 		if (saved_gprs[i].stack_addr != NULL) {
976 			mask |= 1 << i;
977 		}
978 	}
979 
980 	x_fprintf(out, "\t.mask 0x%x,-%lu\n", mask,
981 		f->total_allocated - f->callee_save_offset);
982 	if (mask != 0) {
983 		for (i = 0; i < N_GPRS; ++i) {
984 			if (saved_gprs[i].stack_addr != NULL) {
985 				saved_gprs[i].stack_addr->offset =
986 					f->total_allocated -
987 					saved_gprs[i].stack_addr->offset;
988 
989 				backend_vreg_map_preg(&saved_gprs[i],
990 					&mips_gprs[i]);
991 				emit->store(&saved_gprs[i],
992 					&saved_gprs[i]);
993 				backend_vreg_unmap_preg(
994 					&mips_gprs[i]);
995 				mips_gprs[i].used = 0;
996 			}
997 		}
998 	}
999 	x_fprintf(out, "\tmove $fp, $sp\n");
1000 
1001 	/*
1002 	 * Patch parameter offsets and save corresponding argument
1003 	 * registers to stack, if necessary
1004 	 */
1005 	for (i = 0; i < proto->nargs; ++i, se = se->next) {
1006 		if (se->dec->stack_addr->from_reg != NULL) {
1007 			/* Write argument register contents to stack */
1008 			if ((se->dec->dtype->code == TY_STRUCT
1009 				|| se->dec->dtype->code == TY_UNION)
1010 				&& se->dec->dtype->tlist == NULL) {
1011 				/* Passed on stack */
1012 #if 0
1013 				se->dec->stack_addr->offset =
1014 					f->total_allocated +
1015 					se->dec->stack_addr->offset;
1016 #endif
1017 				generic_store_struct_arg_slots(f, se);
1018 			} else {
1019 				store_preg_to_var(se->dec,
1020 					se->dec->stack_addr->nbytes,
1021 					se->dec->stack_addr->from_reg);
1022 			}
1023 		} else {
1024 			/*
1025 			 * Argument passed on stack;
1026 			 * fp . . . . . . [frame start] [arguments ...]
1027 			 * ^ lowest address           highest address ^
1028 			 * So the offset (with fp) is the size of the entire
1029 			 * stack frame plus the offset in the stack arg area
1030 			 */
1031 			se->dec->stack_addr->offset =
1032 				f->total_allocated +
1033 				se->dec->stack_addr->offset;
1034 		}
1035 	}
1036 	if (f->hidden_pointer) {
1037 		struct decl	*d = f->hidden_pointer->var_backed;
1038 
1039 		store_preg_to_var(d,
1040 			d->stack_addr->nbytes,
1041 			d->stack_addr->from_reg);
1042 	}
1043 	if (f->fty->variadic) {
1044 		size_t	saved_offset;
1045 
1046 		if (f->fty->lastarg->stack_addr->from_reg == NULL) {
1047 			/* Entirely on stack */
1048 			f->fty->lastarg->stack_addr->offset =
1049 				f->total_allocated +
1050 				f->fty->lastarg->stack_addr->offset;
1051 		} else {
1052 			struct reg	*r =
1053 				f->fty->lastarg->stack_addr->from_reg;
1054 
1055 			/*
1056 			 * 07/20/09: Get offset from frame pointer to
1057 			 * last argument (this used to be done above,
1058 			 * which wrongly applied to the case ``entirely
1059 			 * on stack'' as well)
1060 			 */
1061 			f->fty->lastarg->stack_addr->offset =
1062 				f->total_allocated -
1063 				f->fty->lastarg->stack_addr->offset;
1064 
1065 			/*
1066 			 * Save all GPRs to their corresponding save
1067 			 * area location
1068 			 */
1069 			saved_offset = f->fty->lastarg->stack_addr->offset;
1070 			for (; r != &mips_gprs[4+8]; ++r) {
1071 				store_preg_to_var(f->fty->lastarg, 8, r);
1072 				f->fty->lastarg->stack_addr->offset += 8;
1073 			}
1074 			f->fty->lastarg->stack_addr->offset = saved_offset;
1075 		}
1076 	}
1077 
1078 	/*
1079 	 * 07/17/09: Changed PIC stuff slightly for Linux. At first I tried
1080 	 * to generate an INSTR_INITIALIZE_PIC, but we have to generate the
1081 	 * initialization sequence immediately because emit->zerostack()
1082 	 * below already needs a properly set up PIC register
1083 	 */
1084 	if (sysflag == OS_IRIX) {
1085 		x_fprintf(out, "\t.set noat\n");
1086 		x_fprintf(out, "\tlui $1, %%hi(%%neg(%%gp_rel(%s)))\n",
1087 			funcname);
1088 		x_fprintf(out, "\taddiu $1, $1, %%lo(%%neg(%%gp_rel(%s)))\n",
1089 			funcname);
1090 		x_fprintf(out, "\tdaddu $gp, $1, $25\n");
1091 		x_fprintf(out, "\t.set at\n");
1092 	} else if (picflag) {
1093 		emit->initialize_pic(f);
1094 	}
1095 
1096 	/*
1097 	 * 08/27/07: This wrongly came before the gp_rel stuff above, thus
1098 	 * yielding a crash
1099 	 */
1100 	if (f->alloca_head != NULL) {
1101 		emit->zerostack(f->alloca_tail, alloca_bytes);
1102 	}
1103 	if (f->vla_head != NULL) {
1104 		emit->zerostack(f->vla_tail, vla_bytes);
1105 	}
1106 
1107 	if (xlate_icode(f, f->icode, &lastret) != 0) {
1108 		return -1;
1109 	}
1110 #if 0
1111 	if (lastret != NULL) {
1112 		struct icode_instr	*tmp;
1113 
1114 		for (tmp = lastret->next; tmp != NULL; tmp = tmp->next) {
1115 			if (tmp->type != INSTR_SETITEM) {
1116 				lastret = NULL;
1117 				break;
1118 			}
1119 		}
1120 	}
1121 
1122 	if (lastret == NULL) {
1123 		do_ret(f, NULL);
1124 	}
1125 #endif
1126 
1127 	x_fprintf(out, "\t.end %s\n", f->proto->dtype->name);
1128 
1129 	return 0;
1130 }
1131 
1132 #if XLATE_IMMEDIATELY
1133 
1134 static int
gen_prepare_output(void)1135 gen_prepare_output(void) {
1136 	/*
1137 	 * 07/12/09: Amazing, this was missing. I guess MIPS support was
1138 	 * broken for 0.7.8/9 then?!
1139 	 */
1140 	x_fprintf(out, "\t.option pic2\n");
1141 	x_fprintf(out, "\t.section .rodata,0x1,0x2,0,8\n");
1142 	x_fprintf(out, "\t.section .data,0x1,0x3,0,8\n");
1143 	x_fprintf(out, "\t.section .text,0x1,0x6,4,4\n");
1144 	return 0;
1145 }
1146 
1147 static int
gen_finish_output(void)1148 gen_finish_output(void) {
1149 	/*
1150 	 * 07/12/09: Amazing, this was missing. I guess MIPS support was
1151 	 * broken for 0.7.8/9 then?!
1152 	 */
1153 	emit->global_extern_decls(global_scope.extern_decls.data,
1154 			global_scope.extern_decls.ndecls);
1155 	emit->global_static_decls(
1156 			global_scope.static_decls.data,
1157 			global_scope.static_decls.ndecls);
1158 #if 0
1159 	emit->static_decls();
1160 #endif
1161 	emit->static_init_vars(static_init_vars);
1162 	emit->static_uninit_vars(static_uninit_vars);
1163 	emit->static_init_thread_vars(static_init_thread_vars);
1164 	emit->static_uninit_thread_vars(static_uninit_thread_vars);
1165 
1166 #if 0 /* 07/12/09: Strings and fp constans have already been emitted */
1167 	emit->struct_inits(init_list_head);
1168 
1169 	emit->empty();
1170 	emit->strings(str_const); /* XXX bad */
1171 	emit->fp_constants(float_const);
1172 #endif
1173 	x_fflush(out);
1174 	return 0;
1175 }
1176 
1177 #else
1178 
1179 static int
gen_program(void)1180 gen_program(void) {
1181 	struct function		*func;
1182 
1183 	x_fprintf(out, "\t.option pic2\n");
1184 	x_fprintf(out, "\t.section .rodata,0x1,0x2,0,8\n");
1185 	x_fprintf(out, "\t.section .data,0x1,0x3,0,8\n");
1186 	x_fprintf(out, "\t.section .text,0x1,0x6,4,4\n");
1187 #if 0
1188 	emit->global_decls();
1189 #endif
1190 	emit->global_extern_decls(global_scope.extern_decls.data,
1191 			global_scope.extern_decls.ndecls);
1192 	emit->global_static_decls(
1193 			global_scope.static_decls.data,
1194 			global_scope.static_decls.ndecls);
1195 #if 0
1196 	emit->static_decls();
1197 #endif
1198 	emit->static_init_vars(static_init_vars);
1199 	emit->static_uninit_vars(static_uninit_vars);
1200 	emit->static_init_thread_vars(static_init_thread_vars);
1201 	emit->static_uninit_thread_vars(static_uninit_thread_vars);
1202 
1203 	emit->struct_inits(init_list_head);
1204 
1205 	emit->empty();
1206 	emit->strings(str_const); /* XXX bad */
1207 	emit->fp_constants(float_const);
1208 
1209 	x_fprintf(out, ".section .text\n");
1210 	for (func = funclist; func != NULL; func = func->next) {
1211 		curfunc = func;
1212 		if (gen_function(func) != 0) {
1213 			return -1;
1214 		}
1215 		emit->empty();
1216 		emit->empty();
1217 	}
1218 	x_fflush(out);
1219 
1220 	return 0;
1221 }
1222 
1223 #endif
1224 
1225 static void
pass_arg_stack(struct vreg * vr,size_t bytes_left,size_t * stack_bytes_used,struct icode_list * il)1226 pass_arg_stack(
1227 	struct vreg *vr,
1228 	size_t bytes_left,
1229 	size_t *stack_bytes_used,
1230 	struct icode_list *il) {
1231 
1232 	struct vreg	*dest;
1233 
1234 	/*
1235 	 * All types are passed as double words
1236 	 * (right-justified)
1237 	 */
1238 	/*size_t*/ int	size;
1239 
1240 	(void) bytes_left;
1241 
1242 	size = backend->get_sizeof_type(vr->type, NULL);
1243 	if (vr->type->tlist
1244 		&& vr->type->tlist->type ==
1245 		TN_ARRAY_OF) {
1246 		size = 4;
1247 	}
1248 
1249 	if (vr->type->code == TY_LDOUBLE && vr->type->tlist == NULL) {
1250 		/*
1251 		 * 07/19/09: Align long double to even slot number
1252 		 */
1253 		if ((*stack_bytes_used / 8) & 1) {
1254 			*stack_bytes_used += 8;
1255 		}
1256 	} else if (8 - size > 0) {
1257 		/* Need to right-adjust */
1258 		/* 07/15/09: Not for little endian */
1259 		if (get_target_endianness() != ENDIAN_LITTLE) {
1260 			*stack_bytes_used += 8 - size;
1261 		}
1262 	}
1263 	dest = vreg_alloc(NULL, NULL, NULL, NULL);
1264 	dest->type = vr->type;
1265 	dest->size = vr->size;
1266 	if (dest->type->code == TY_LDOUBLE && dest->type->tlist == NULL) {
1267 		dest->is_multi_reg_obj = 2;
1268 	}
1269 	dest->stack_addr = make_stack_block(
1270 		*stack_bytes_used, dest->size);
1271 	dest->stack_addr->use_frame_pointer = 0;
1272 	*stack_bytes_used += size;
1273 
1274 
1275 	/*
1276 	 * 12/27/08: Use new dedicated functions which do not set
1277 	 * the ``used'' flag (which tarshes the dedicated property
1278 	 * of the register and makes it allocatable eventually
1279 	 */
1280 	if (IS_FLOATING(vr->type->code)) {
1281 		/*
1282 		 * 07/14/09: Don't use a temp GPR for an FP item,
1283 		 * which triggers sanity checks and probably never
1284 		 * worked correctly (if the item is already FPR-
1285 		 * resident, the faultin would try to ``copyreg''
1286 		 * it to the GPR)
1287 		 */
1288 		vreg_faultin(NULL, NULL, vr, il, 0);
1289 		vreg_map_preg(dest, vr->pregs[0]);
1290 		if (dest->is_multi_reg_obj) {
1291 			vreg_map_preg2(dest, vr->pregs[1]);
1292 		}
1293 	} else {
1294 		vreg_faultin_dedicated(tmpgpr, NULL, vr, il, 0);
1295 		vreg_map_preg_dedicated(dest, tmpgpr);
1296 	}
1297 	icode_make_store(curfunc, dest, dest, il);
1298 
1299 
1300 	/*
1301 	 * 07/17/09: For little endian, which isn't right-adjusted:
1302 	 * Fill slot after argument
1303 	 */
1304 	if (8 - size > 0) {
1305 		if (get_target_endianness() == ENDIAN_LITTLE) {
1306 			*stack_bytes_used += 8 - size;
1307 		}
1308 	}
1309 }
1310 
1311 /* XXX generic? */
1312 void
1313 put_arg_into_reg(
1314 	struct reg *regset,
1315 	int *index, int startat,
1316 	struct vreg *vr,
1317 	struct icode_list *il);
1318 
1319 unsigned long	reg_offset;
1320 
1321 /*
1322  * Calculates the amount of stack bytes needed to pass vrs to
1323  * a function, if any. This is because it's more convenient
1324  * to pre-allocated any needed space in advance, rather than
1325  * doing it when needed. Special care must be taken to ensure
1326  * that this stuff is always in sync with the code that
1327  * actually pushes the arguments onto the stack.
1328  *
1329  * It is assumed that the stack starts out being word aligned.
1330  *
1331  * 07/17/09: This used to calculate in terms of GPR/FPR slots,
1332  * which is wrong. So like on PPC, we now add an argument slot
1333  * per scalar argument (except long double), and then align to
1334  * save area slot alignment (for structs).
1335  */
1336 size_t
mips_calc_stack_bytes(struct vreg ** vrs,int nvrs,int * takes_struct)1337 mips_calc_stack_bytes(struct vreg **vrs, int nvrs, int *takes_struct) {
1338 	size_t	nbytes = 0;
1339 	int	i;
1340 	int	stackstruct = 0;
1341 
1342 	for (i = 0; i < nvrs; ++i) {
1343 		/*if (is_integral_type(vrs[i]->type)
1344 			|| vrs[i]->type->tlist != NULL) {
1345 			if (gprs_used < 8) {
1346 				++gprs_used;
1347 			} else {
1348 				nbytes += 8;
1349 			}
1350 		} else if (IS_FLOATING(vrs[i]->type->code)) {
1351 			if (fprs_used < 8) {
1352 				++fprs_used;
1353 			} else {
1354 				if (vrs[i]->type->code == TY_LDOUBLE) {
1355 					nbytes += 16;
1356 				} else {
1357 					nbytes += 8;
1358 				}
1359 			}
1360 		} else*/
1361 
1362 		if (vrs[i]->type->code == TY_STRUCT
1363 			|| vrs[i]->type->code == TY_UNION) {
1364 			nbytes += vrs[i]->type->tstruc->size;
1365 			stackstruct = 1;
1366 		} else if (vrs[i]->type->code == TY_LDOUBLE
1367 			&& vrs[i]->type->tlist == NULL) {
1368 			nbytes += 16;
1369 		} else {
1370 			nbytes += mips_gprs[0].size;
1371 		}
1372 	}
1373 	if (nbytes & 15) { /* Align to 16 for long double */
1374 		nbytes += 16 - (nbytes & 15);
1375 	}
1376 
1377 	/* Allocate space for saving registers */
1378 	if (stackstruct) {
1379 		/* XXXXXXXX wow reg_offset seems broken!??! */
1380 		reg_offset = nbytes;
1381 		nbytes += 8 * 16;
1382 		*takes_struct = 1;
1383 	} else {
1384 		*takes_struct = 0;
1385 	}
1386 	return nbytes;
1387 }
1388 
1389 void
1390 generic_double_vreg_to_ldouble(struct vreg *ret, struct icode_list *il);
1391 void
1392 generic_conv_fp_to_or_from_ldouble(struct vreg *ret,
1393 	struct type *to, struct type *from,
1394 	struct icode_list *il);
1395 
1396 
1397 
1398 
1399 static struct vreg *
icode_make_fcall(struct fcall_data * fcall,struct vreg ** vrs,int nvrs,struct icode_list * il)1400 icode_make_fcall(struct fcall_data *fcall, struct vreg **vrs, int nvrs,
1401 struct icode_list *il)
1402 {
1403 	unsigned long		allpushed = 0;
1404 	struct vreg		*tmpvr;
1405 	struct vreg		*ret = NULL;
1406 	struct vreg		*vr2;
1407 	struct type		*ty;
1408 	struct icode_instr	*ii;
1409 	struct type_node	*tn;
1410 	struct vreg		*struct_lvalue;
1411 	size_t			stack_bytes_used = 0;
1412 	int			i;
1413 	int			takes_struct = 0;
1414 	int			need_dap = 0;
1415 	int			struct_return = 0;
1416 	int			gprs_used = 0;
1417 	int			fprs_used = 0;
1418 	int			ret_is_anon_struct = 0;
1419 
1420 
1421 	ty = fcall->calltovr->type;
1422 	tmpvr = fcall->calltovr;
1423 
1424 	tn = ty->tlist;
1425 	if (tn->type == TN_POINTER_TO) {
1426 		/* Called thru function pointer */
1427 		tn = tn->next;
1428 	}
1429 
1430 	struct_lvalue = fcall->lvalue;
1431 
1432 	if ((ty->code == TY_STRUCT
1433 		|| ty->code == TY_UNION)
1434 		&& tn->next == NULL) {
1435 		struct_return = 1;
1436 
1437 		/*
1438 		 * This is a big struct that doesn't fit into
1439 		 * regsiters, so it is necessary to pass a pointer
1440 		 * to some space to store the result into in r4
1441 		 */
1442 		if (struct_lvalue == NULL || fcall->need_anon) {
1443 			struct type_node	*tnsav;
1444 			/*
1445 			 * Result of function is not assigned so we need
1446 			 * to allocate storage for the callee to store
1447 			 * its result into
1448 			 */
1449 
1450 #if 1 /* XXX should go! Use rettype */
1451 			tnsav = ty->tlist;
1452 			ty->tlist = NULL;
1453 #endif
1454 			/* XXX hm */
1455 			/*
1456 			 * 08/23/07: This gave a bus error because alignemtn
1457 			 * was missing. Fortunately we have the vreg_stack_alloc()
1458 			 * flag which says ``allocate buffer when creating stack
1459 			 * frame, not now'', and it seems to work here. This was
1460 			 * still disabled because it didn't work on x86, for
1461 			 * unknown reasons
1462 			 */
1463 			struct_lvalue = vreg_stack_alloc(ty, il, 1 /*0*/, NULL);
1464 
1465 #if 1 /*  XXX should go! Use rettype */
1466 			ty->tlist = tnsav;
1467 #endif
1468 			/*
1469 			 * 08/05/08: Don't add to allpushed since struct is
1470 			 * created on frame. This bug occurred on AMD64 and
1471 			 * hasn't been verified on MIPS yet
1472 			 */
1473 	/*		allpushed += struct_lvalue->size;*/
1474 			while (allpushed % 8) ++allpushed;
1475 			ret_is_anon_struct = 1;
1476 		}
1477 
1478 		/* Hidden pointer is passed in first GPR! */
1479 #if 0
1480 		ii = icode_make_addrof(NULL, struct_lvalue, il);
1481 		append_icode_list(il, ii);
1482 #endif
1483 		{
1484 			struct reg *r;
1485 
1486 			/*ii*/ r = make_addrof_structret(struct_lvalue, il);
1487 			free_preg(&mips_gprs[4], il, 1, 1);
1488 			icode_make_copyreg(&mips_gprs[4], r /*ii->dat*/,
1489 				NULL, NULL, il);
1490 			++gprs_used;
1491 		}
1492 	}
1493 
1494 	/*
1495 	 * 07/20/08: This wrongly took an implicit return type into account
1496 	 * to determine whether default argument promotions are needed!
1497 	 */
1498 	if (fcall->functype->nargs == -1
1499 		/*|| ty->implicit*/) {
1500 		/* Need default argument promotions */
1501 		need_dap = 1;
1502 	}
1503 
1504 	allpushed += mips_calc_stack_bytes(vrs, nvrs, &takes_struct);
1505 	if (takes_struct) {
1506 		/* memcpy() will be called to pass argument(s) */
1507 		backend->invalidate_gprs(il, 1, INV_FOR_FCALL);
1508 	}
1509 	if (allpushed > 0) {
1510 		icode_make_allocstack(NULL, allpushed, il);
1511 	}
1512 
1513 	for (i = 0; i < nvrs; ++i) {
1514 		if ((fcall->functype->variadic
1515 			&& i >= fcall->functype->nargs)
1516 			|| fcall->functype->nargs == -1) {
1517 			need_dap = 1;
1518 		}
1519 
1520 		if (vrs[i]->parent) {
1521 			vr2 = get_parent_struct(vrs[i]);
1522 		} else {
1523 			vr2 = NULL;
1524 		}
1525 
1526 		/*
1527 		 * 07/14/09: Removed from_const check - that wrongly
1528 		 * included floating point constants!
1529 		 */
1530 		if (is_integral_type(vrs[i]->type)
1531 			|| vrs[i]->type->tlist
1532 			/*|| vrs[i]->from_const*/) {
1533 			if (vrs[i]->type->tlist == NULL
1534 				&& (IS_CHAR(vrs[i]->type->code)
1535 				|| IS_SHORT(vrs[i]->type->code))) {
1536 				struct type	*ty =
1537 					make_basic_type(TY_INT);
1538 
1539 				vrs[i] = backend->
1540 					icode_make_cast(vrs[i], ty, il);
1541 			}
1542 			if (gprs_used < 8) { /* 4 in o32 */
1543 				put_arg_into_reg(mips_gprs,
1544 					&gprs_used, 4, vrs[i], il);
1545 			} else {
1546 				pass_arg_stack(vrs[i], 0,
1547 					&stack_bytes_used, il);
1548 			}
1549 		} else if (vrs[i]->type->code == TY_STRUCT
1550 			|| vrs[i]->type->code == TY_UNION) {
1551 #if 0
1552 			pass_struct_union(vrs[i],
1553 				&gprs_used, &fprs_used,	&stack_bytes_used, il);
1554 #endif
1555 			generic_pass_struct_union(vrs[i],
1556 				&gprs_used, NULL, &stack_bytes_used, il);
1557 			if (gprs_used >= 8) {
1558 				/*
1559 				 * XXXXXX the function thinks in terms of slots,
1560 				 * but we are still stuck with GPRs on MIPS. So
1561 				 * limit them to 8
1562 				 */
1563 				gprs_used = 8;
1564 			}
1565 		} else if (IS_FLOATING(vrs[i]->type->code)) {
1566 			/*
1567 			 * For variadic functions, floating point values
1568 			 * go into gprs (floats are promoted to double)
1569 			 */
1570 			if (/*fcall->functype->variadic
1571 				&&*/ need_dap) {
1572 				if (vrs[i]->type->code == TY_FLOAT) {
1573 					vrs[i] = backend->
1574 						icode_make_cast(vrs[i],
1575 							make_basic_type(TY_DOUBLE), il);
1576 				} else if (vrs[i]->type->code == TY_LDOUBLE) {
1577 					if (gprs_used & 1) {
1578 						++gprs_used;
1579 					}
1580 				}
1581 
1582 				if (gprs_used < 8) {
1583 					if (vrs[i]->type->code == TY_LDOUBLE) {
1584 						struct vreg	*tmp;
1585 	free_pregs_vreg(vrs[i], il, 1, 1);
1586 						tmp = dup_vreg(vrs[i]);
1587 /*						tmp->pregs[0] = NULL;
1588 hello*/
1589 						free_preg(&mips_gprs[4+gprs_used], il, 1, 1);
1590 						free_preg(&mips_gprs[4+gprs_used+1], il, 1, 1);
1591 						vreg_faultin(&mips_gprs[4+gprs_used],
1592 							&mips_gprs[4+gprs_used+1],
1593 							tmp, il, 0);
1594 						reg_set_unallocatable(&mips_gprs[4+gprs_used]);
1595 						reg_set_unallocatable(&mips_gprs[4+gprs_used+1]);
1596 						gprs_used += 2;
1597 					} else {
1598 						vreg_reinterpret_as(&vrs[i], vrs[i]->type,
1599 							make_basic_type(TY_ULLONG), il);
1600 						put_arg_into_reg(mips_gprs,
1601 							&gprs_used, 4, vrs[i], il);
1602 					}
1603 				} else {
1604 					pass_arg_stack(vrs[i], 0,
1605 						&stack_bytes_used, il);
1606 				}
1607 			} else {
1608 				if (vrs[i]->type->code == TY_LDOUBLE) {
1609 					/*
1610 					 * Align FPR number (note that
1611 					 * pass_arg_stack() aligns for
1612 					 * the stack case)
1613 					 */
1614 					if (fprs_used < 8) {
1615 						if (fprs_used & 1) {
1616 							++fprs_used;
1617 						}
1618 					}
1619 				}
1620 
1621 				if (fprs_used < 8) {
1622 					put_arg_into_reg(mips_fprs,
1623 						&fprs_used, 12, vrs[i], il);
1624 				} else {
1625 					pass_arg_stack(vrs[i], 0,
1626 						&stack_bytes_used, il);
1627 				}
1628 			}
1629 		} else {
1630 			unimpl();
1631 		}
1632 
1633 		/* We can free the register(s) - marked unallocatable */
1634 		/*free_pregs_vreg(vrs[i], il, 0, 0);*/
1635 		if (vr2 && vr2->from_ptr && vr2->from_ptr->pregs[0]
1636 			&& vr2->from_ptr->pregs[0]->vreg == vr2->from_ptr) {
1637 			free_preg(vr2->from_ptr->pregs[0], il, 0, 0);
1638 		}
1639 	}
1640 
1641 	if (struct_return) {
1642         /* XXX uh-huh what's going on here?!!?! why this AGAIN??? */
1643 #if 0
1644 		ii = icode_make_addrof(NULL, struct_lvalue, il);
1645 		append_icode_list(il, ii);
1646 #endif
1647 		struct reg *r;
1648 
1649 		/*ii*/ r = make_addrof_structret(struct_lvalue, il);
1650 
1651 		icode_make_copyreg(&mips_gprs[4], r /*ii->dat*/, NULL, NULL, il);
1652 
1653 		free_preg(r /*ii->dat*/, il, 0, 0);
1654 	}
1655 
1656 	for (i = 0; i < gprs_used; ++i) {
1657 		/* Don't save argument registers */
1658 		mips_gprs[4+i].used = 0;
1659 		mips_gprs[4+i].vreg = NULL;
1660 
1661 		/* 12/29/07: This was wrong (see SPARC) */
1662 #if 0
1663 		mips_gprs[4+i].allocatable = 1;
1664 #endif
1665 	}
1666 
1667 	for (i = 0; i < fprs_used; ++i) {
1668 		/* Don't save argument fp registers */
1669 		mips_fprs[12+i].used = 0;
1670 		mips_fprs[12+i].vreg = NULL;
1671 		mips_fprs[12+i].allocatable = 0;
1672 	}
1673 
1674 	if (!takes_struct) {
1675 		backend->invalidate_gprs(il, 1, INV_FOR_FCALL);
1676 	}
1677 
1678 	for (i = 0; i < gprs_used; ++i) {
1679 		mips_gprs[4+i].allocatable = 1;
1680 	}
1681 	for (i = 0; i < fprs_used; ++i) {
1682 		mips_fprs[12+i].allocatable = 1;
1683 	}
1684 
1685 	if (ty->tlist->type == TN_POINTER_TO) {
1686 		/* Need to indirect thru function pointer */
1687 		vreg_faultin(&mips_gprs[12], NULL, tmpvr, il, 0);
1688 		ii = icode_make_call_indir(tmpvr->pregs[0]);
1689 		tmpvr->pregs[0]->used = 0;
1690 		tmpvr->pregs[0]->vreg = NULL;
1691 	} else {
1692 		ii = icode_make_call(ty->name);
1693 	}
1694 	append_icode_list(il, ii);
1695 	if (allpushed > 0) {
1696 		ii = icode_make_freestack(allpushed);
1697 		append_icode_list(il, ii);
1698 	}
1699 
1700 	ret = vreg_alloc(NULL, NULL, NULL, NULL);
1701 	ret->type = ty;
1702 
1703 	/*
1704 	 * XXX this stuff SUCKS!
1705 	 */
1706 #if 0
1707 	if (ty->tlist->next != NULL) {
1708 #endif
1709 
1710 	if ((ty->tlist->type == TN_POINTER_TO
1711 		&& ty->tlist->next->next != NULL)
1712 		|| (ty->tlist->type == TN_FUNCTION
1713 		&& ty->tlist->next != NULL)) {
1714 		/* Must be pointer */
1715 		ret->pregs[0] = &mips_gprs[2];
1716 	} else {
1717 #if 1 /* 06/17/08: XXX Should go, use rettype! */
1718 		struct type_node	*tnsav = ty->tlist;
1719 
1720 		ty->tlist = NULL;
1721 #endif
1722 		if (is_integral_type(ty)) {
1723 			ret->pregs[0] = &mips_gprs[2];
1724 		} else if (ty->code == TY_FLOAT
1725 			|| ty->code == TY_DOUBLE
1726 			|| ty->code == TY_LDOUBLE) {
1727 			ret->pregs[0] = &mips_fprs[0];
1728 			if (ty->code == TY_LDOUBLE) {
1729 				ret->pregs[1] = &mips_fprs[2];
1730 				ret->is_multi_reg_obj = 2;
1731 			}
1732 		} else if (ty->code == TY_STRUCT
1733 			|| ty->code == TY_UNION) {
1734 			if (ret_is_anon_struct) {
1735 				ret = struct_lvalue;
1736 			}
1737 			ret->struct_ret = 1;
1738 			ret->pregs[0] = NULL;
1739 		} else if (ty->code == TY_VOID) {
1740 			; /* Nothing! */
1741 		}
1742 		ty->tlist = tnsav;
1743 	}
1744 	for (i = 4; i < 12; ++i) {
1745 		reg_set_allocatable(&mips_gprs[i]);
1746 	}
1747 
1748 	if (ret->pregs[0] != NULL) {
1749 		vreg_map_preg(ret, ret->pregs[0]);
1750 	}
1751 	if (ret->is_multi_reg_obj) {
1752 		vreg_map_preg2(ret, ret->pregs[1]);
1753 	}
1754 
1755 	ret->type = n_xmemdup(ret->type, sizeof *ret->type);
1756 	if (ret->type->tlist->type == TN_POINTER_TO) {
1757 		copy_tlist(&ret->type->tlist, ret->type->tlist->next->next);
1758 	} else {
1759 		copy_tlist(&ret->type->tlist, ret->type->tlist->next);
1760 	}
1761 	if (ret->type->code != TY_VOID || ret->type->tlist) {
1762 		ret->size = backend->get_sizeof_type(ret->type, NULL);
1763 	}
1764 
1765 	return ret;
1766 }
1767 
1768 static int
1769 icode_make_return(struct vreg *vr, struct icode_list *il) {
1770 	struct icode_instr	*ii;
1771 #if 0
1772 	struct type_node	*oldtn;
1773 #endif
1774 	struct type		*rtype = curfunc->rettype; /*proto->dtype;*/
1775 
1776 	/* 06/17/08: Don't use type kludgery, but rettype! */
1777 #if 0
1778 	oldtn = rtype->tlist;
1779 	rtype->tlist = rtype->tlist->next;
1780 #endif
1781 
1782 
1783 	if (vr != NULL) {
1784 		if (is_integral_type(rtype)
1785 			|| rtype->code == TY_ENUM /* 06/15/09: Was missing?!? */
1786 			|| rtype->tlist != NULL) {
1787 			vreg_faultin(&mips_gprs[2], NULL, vr, il, 0);
1788 		} else if (rtype->code == TY_FLOAT
1789 			|| rtype->code == TY_DOUBLE) {
1790 			vreg_faultin(&mips_fprs[0], NULL, vr, il, 0);
1791 		} else if (rtype->code == TY_LDOUBLE) {
1792 			vreg_faultin(&mips_fprs[0], &mips_fprs[2], vr, il, 0);
1793 		} else if (rtype->code == TY_STRUCT
1794 			|| rtype->code == TY_UNION) {
1795 			/* vr may come from pointer */
1796 			vreg_faultin_ptr(vr, il);
1797 			icode_make_copystruct(NULL, vr, il);
1798 		}
1799 	}
1800 	ii = icode_make_ret(vr);
1801 	append_icode_list(il, ii);
1802 
1803 #if 0
1804 	rtype->tlist = oldtn;
1805 #endif
1806 	return 0;
1807 }
1808 
1809 static void
1810 icode_prepare_op(
1811 	struct vreg **dest,
1812 	struct vreg **src,
1813 	int op,
1814 	struct icode_list *il) {
1815 
1816 	vreg_faultin(NULL, NULL, *dest, il, 0);
1817 	vreg_faultin(NULL, NULL, *src, il, 0);
1818 	(void) op;
1819 }
1820 
1821 
1822 /*
1823  * Most of the time, instructions give meaning to data. This function
1824  * generates code required to convert virtual register ``src'' to type
1825  * ``to'' where necessary
1826  */
1827 static struct vreg *
1828 icode_make_cast(struct vreg *src, struct type *to, struct icode_list *il) {
1829 	struct vreg		*ret;
1830 	struct type		*from = src->type;
1831 	struct type		*orig_to = to;
1832 
1833 	ret = src;
1834 
1835 	if (ret->type->tlist != NULL
1836 		|| (ret->type->code != TY_STRUCT
1837 		&& ret->type->code != TY_UNION)) {
1838 		vreg_anonymify(&ret, NULL, NULL /*r*/, il);
1839 	}
1840 	if (ret == src) {
1841 		/* XXX ... */
1842 		ret = vreg_disconnect(src);
1843 	}
1844 
1845 	ret->type = to;
1846 
1847 	if (to->code == TY_VOID) {
1848 		if (to->tlist == NULL) {
1849 			ret->size = 0;
1850 			free_pregs_vreg(ret, il, 0, 0);
1851 			return ret;
1852 		}
1853 	} else {
1854 		ret->is_nullptr_const = 0;
1855 	}
1856 	ret->size = backend->get_sizeof_type(to, NULL);
1857 
1858 	if (from->tlist != NULL && to->tlist != NULL) {
1859 		/*
1860 		 * Pointers are always of same size
1861 		 * and use same registers
1862 		 */
1863 		return ret;
1864 	} else if (to->tlist != NULL) {
1865 		/*
1866 		 * Integral type to pointer type - cast to
1867 		 * uintptr_t to get it to the same size
1868 		 */
1869 		to = backend->get_uintptr_t();
1870 	}
1871 
1872 	if (to->code != from->code) {
1873 		/*
1874 		 * XXX source type may be trashed. This is perhaps a
1875 		 * bug in vreg_anonymify()!!? this kludge fixes it
1876 		 * for now ...
1877 		 */
1878 		src = n_xmemdup(src, sizeof *src);
1879 		src->type = from;
1880 		src->size = backend->get_sizeof_type(from, 0);
1881 	}
1882 
1883 	/*
1884 	 * We may have to move the item to a different
1885 	 * register as a result of the conversion
1886 	 */
1887 	if (to->code == from->code) {
1888 		; /* Nothing to do */
1889 	} else if (IS_FLOATING(to->code)) {
1890 		if (!IS_FLOATING(from->code)) {
1891 			struct reg	*r;
1892 			struct vreg	*double_vr;
1893 
1894 			r = backend->alloc_fpr(curfunc, 0, il, NULL);
1895 			icode_make_mips_mtc1(r, src, il);
1896 			free_preg(ret->pregs[0], il, 0, 0);
1897 			ret->pregs[0] = r;
1898 
1899 			if (to->code == TY_LDOUBLE) {
1900 				double_vr = dup_vreg(ret);
1901 				vreg_set_new_type(double_vr, make_basic_type(TY_DOUBLE));
1902 			} else {
1903 				double_vr = ret;
1904 			}
1905 
1906 			icode_make_mips_cvt(/*ret*/double_vr, src, il);
1907 
1908 			if (to->code == TY_LDOUBLE) {
1909 				/*
1910 				 * 07/19/09: Integer to emulated long double
1911 				 * conversion
1912 				 */
1913 				generic_double_vreg_to_ldouble(ret, il);
1914 			}
1915 		} else if (to->code != from->code) {
1916 			/* From fp to fp */
1917 			/* 07/16/09: long double now emulated using double */
1918 			if (to->code == TY_LDOUBLE || from->code == TY_LDOUBLE) {
1919 				generic_conv_fp_to_or_from_ldouble(ret, to, from, il);
1920 			} else {
1921 				icode_make_mips_cvt(ret, src, il);
1922 			}
1923 		}
1924 	} else if (IS_FLOATING(from->code)) {
1925 		struct reg	*r;
1926 
1927 		/* ``to'' has already been found to be non-fp */
1928 
1929 		icode_make_mips_trunc(ret, src, il);
1930 		r = ALLOC_GPR(curfunc, 0, il, NULL);
1931 		icode_make_mips_mfc1(r, src, il);
1932 		free_preg(ret->pregs[0], il, 0, 0);
1933 		ret->pregs[0] = r;
1934 	} else {
1935 		int	to_size = backend->get_sizeof_type(to, NULL);
1936 		int	from_size = backend->get_sizeof_type(from, NULL);
1937 		struct icode_instr	*ii;
1938 		unsigned			needand = 0;
1939 
1940 		/* integer <-> integer */
1941 		if (to_size == from_size) {
1942 			;
1943 		} else if (to->tlist != NULL) {
1944 			; /* XXX what 2 do */
1945 		} else if (to_size < from_size) {
1946 
1947 			/* Truncate */
1948 			if (to->tlist != NULL) {
1949 				/* XXX hmm... */
1950 			} else if (IS_CHAR(to->code)) {
1951 				needand = 0xff;
1952 			} else if (IS_SHORT(to->code)) {
1953 				needand = 0xffff;
1954 			} else if (IS_INT(to->code)
1955 				|| IS_LONG(to->code)) {
1956 				/*
1957 				 * Must be coming from a 64bit long or long long
1958 				 */
1959 				icode_make_mips_make_32bit_mask(tmpgpr, il);
1960 				ii = icode_make_and(ret, NULL);
1961 				append_icode_list(il, ii);
1962 			} else {
1963 				unimpl();
1964 			}
1965 		} else {
1966 			/* Destination type bigger - sign- or zero-extend */
1967 			if (from->sign == TOK_KEY_UNSIGNED) {
1968 				/*
1969 				 * zero-extend - nothing to do! Unless, of
1970 				 * course, we're converting to 64bit values.
1971 				 * Because 32bit operations immediately
1972 				 * sign-extend to the 64bit register
1973 				 * portion, it is then necessary to AND with
1974 				 * a 32bit mask
1975 				 */
1976 				if (IS_LLONG(to->code) || IS_LONG(to->code)) {
1977 					icode_make_mips_make_32bit_mask(tmpgpr, il);
1978 					ii = icode_make_and(ret, NULL);
1979 					append_icode_list(il, ii);
1980 				}
1981 			} else {
1982 				/* sign-extend */
1983 				icode_make_extend_sign(ret, to, from, il);
1984 			}
1985 		}
1986 		if (needand) {
1987 			ii = icode_make_setreg(tmpgpr, needand);
1988 			append_icode_list(il, ii);
1989 			ii = icode_make_and(ret, NULL);
1990 			append_icode_list(il, ii);
1991 		}
1992 	}
1993 
1994 	vreg_set_new_type(ret, orig_to);
1995 	vreg_map_preg(ret, ret->pregs[0]);
1996 	if (ret->type->code == TY_BOOL && ret->type->tlist == NULL) {
1997 		boolify_result(ret, il);
1998 	} else if (ret->type->code == TY_LDOUBLE && ret->type->tlist == NULL) {
1999 		ret->is_multi_reg_obj = 2;
2000 		vreg_map_preg2(ret, ret->pregs[1]);
2001 	}
2002 
2003 	return ret;
2004 }
2005 
2006 static void
2007 icode_make_structreloc(struct copystruct *cs, struct icode_list *il) {
2008 	relocate_struct_regs(cs, &mips_gprs[4], &mips_gprs[5], &mips_gprs[6],
2009 		il);
2010 }
2011 
2012 static void
2013 do_print_gpr(struct reg *r) {
2014 	printf("%s=%d ", r->name, r->used);
2015 	if (r->vreg && r->vreg->pregs[0] == r) {
2016 		printf("<-> %p", r->vreg);
2017 	}
2018 }
2019 
2020 static void
2021 debug_print_gprs(void) {
2022 	int	i;
2023 
2024 	for (i = 0; i < N_GPRS; ++i) {
2025 		if ((i % 3) == 0) {
2026 			printf("\t\t");
2027 		} else {
2028 			putchar('\t');
2029 		}
2030 		do_print_gpr(&mips_gprs[i]);
2031 		if (((i+1) % 3) == 0) {
2032 			putchar('\n');
2033 		}
2034 	}
2035 }
2036 
2037 static int
2038 is_multi_reg_obj(struct type *t) {
2039 	if (t->code == TY_LDOUBLE && t->tlist == NULL) {
2040 		/*
2041 		 * 07/14/09: Note that this isn't true for o32 if we
2042 		 * ever do support that (then we also have to disable
2043 		 * long double emulation settings)
2044 		 */
2045 		return 2;
2046 	}
2047 	return 0;
2048 }
2049 
2050 static struct reg *
2051 name_to_reg(const char *name) {
2052 	(void) name;
2053 	return NULL;
2054 }
2055 
2056 static struct reg *
2057 asmvreg_to_reg(
2058 	struct vreg **vr0,
2059 	int ch,
2060 	struct inline_asm_io *io,
2061 	struct icode_list *il,
2062 	int faultin) {
2063 
2064 	struct vreg	*vr = *vr0;
2065 
2066 	(void) ch; (void) io; (void) il; (void)faultin;
2067 
2068 	if ((vr->type->code == TY_STRUCT || vr->type->code == TY_UNION)
2069 		&& vr->type->tlist == NULL) {
2070 		errorfl(io->expr->tok,
2071 			"Cannot load struct/union into register");
2072 	}
2073 	return NULL;
2074 }
2075 
2076 static char *
2077 get_inlineasm_label(const char *tmpl) {
2078 	char	*ret = n_xmalloc(strlen(tmpl) + sizeof "inlasm");
2079 	sprintf(ret, "inlasm%s", tmpl);
2080 	return ret;
2081 }
2082 
2083 static int
2084 have_immediate_op(struct type *ty, int op) {
2085 	(void) ty; (void) op;
2086 	if (Oflag == -1) { /* XXX */
2087 		return 0;
2088 	}
2089 	return 0;
2090 }
2091 
2092 struct backend mips_backend = {
2093 	ARCH_MIPS,
2094 	0, /* ABI */
2095 	0, /* multi_gpr_object */
2096 	8, /* structure alignment (set by init()) */
2097 	1, /* need pic initialization? */
2098 	1, /* emulate long double?  As of 07/15/09: YES! */
2099 	0, /* relax alloc gpr order */
2100 	32767, /* max displacement */
2101 	-32768, /* min displacement */
2102 	have_immediate_op,
2103 	init,
2104 	is_multi_reg_obj,
2105 	get_ptr_size,
2106 	get_size_t,
2107 	get_uintptr_t,
2108 	get_wchar_t,
2109 	get_sizeof_basic,
2110 	get_sizeof_type,
2111 	get_sizeof_elem_type,
2112 	get_sizeof_decl,
2113 	get_sizeof_const,
2114 	get_sizeof_vla_type,
2115 	get_align_type,
2116 	gen_function,
2117 #if XLATE_IMMEDIATELY
2118 	gen_prepare_output,
2119 	gen_finish_output,
2120 #else
2121 	gen_program,
2122 #endif
2123 	NULL,
2124 	NULL,
2125 	invalidate_gprs,
2126 	invalidate_except,
2127 	/*generic_*/ alloc_gpr,
2128 	NULL,
2129 	alloc_fpr,
2130 	NULL,
2131 	icode_make_fcall,
2132 	icode_make_return,
2133 	NULL,
2134 	icode_prepare_op,
2135 	NULL, /* prepare_load_addrlabel */
2136 	icode_make_cast,
2137 	icode_make_structreloc,
2138 	generic_icode_initialize_pic,
2139 	NULL, /* icode_complete_func */
2140 	make_null_block,
2141 	make_init_name,
2142 	debug_print_gprs,
2143 	name_to_reg,
2144 	asmvreg_to_reg,
2145 	get_inlineasm_label,
2146 	do_ret,
2147 	get_abi_reg,
2148 	get_abi_ret_reg,
2149 	generic_same_representation
2150 };
2151 
2152