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