Added numerous target specific options. Use --target-help to list the
[zpugcc.git] / toolchain / gcc / gcc / config / zpu / zpu.c
blob389f5664c44c139904023201b1ade0c3a30b1527
1 /* Subroutines used for code generation on transputer.
2 Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
4 Written by Øyvind Harboe <oyvind.harboe@zylin.com>
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 #include <stdio.h>
24 #include <limits.h>
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tm.h"
29 #include "rtl.h"
30 #include "tree.h"
31 #include "tm_p.h"
32 #include "regs.h"
33 #include "real.h"
34 #include "insn-config.h"
35 #include "insn-flags.h"
36 #include "expr.h"
37 #include "recog.h"
38 #include "reload.h"
39 #include "output.h"
40 #include "hard-reg-set.h"
41 #include "real.h"
42 #include "insn-config.h"
43 #include "conditions.h"
44 #include "output.h"
45 #include "insn-attr.h"
46 #include "flags.h"
47 #include "libfuncs.h"
48 #include "toplev.h"
49 #include "basic-block.h"
50 #include "function.h"
51 #include "ggc.h"
53 #include "target.h"
54 #include "target-def.h"
56 const char *zpu_board_name;
60 static const int MAX_ADDSP=15*4;
61 /* GCC's concept of registers and the ZPU's concept of registers sometimes,
62 * but not always refer to the same
64 * Hence we have a table of rtx expressions that redirect to the correct
65 * location
67 static GTY(()) rtx reg[R_NUM];
68 static unsigned int regStackTop;
70 static int regMapper[R_NUM-R_STACK_REG];
71 static int debug_output=0;
72 static rtx current_insn;
73 static int stackOffset; /* when the RTL references the SP, we need to track the offset */
75 #define missingOperand() \
77 fprintf(stderr, "Instruction emit failure:\n"); \
78 debug_rtx (current_insn); \
79 fprintf(stderr, "\n"); \
80 abort(); \
83 static int zpu_first_only_push(rtx x, rtx find);
84 static int loadstoresp_offset(rtx operand, int *found);
85 static void zpu_storesp(int offset);
86 static int prevImmediate;
87 static void zpu_asm(const char *format, rtx *operands);
88 static void store_to_operand(rtx *operand);
89 static void zpu_loadsp(int offset);
90 static const char *zpu_immediate(rtx *operand);
91 static int calcStackRegSize(void);
92 static int totalStackOffset(void);
94 static int stackSlotNum(int regNo)
96 if (regMapper[regNo-R_STACK_REG]==-1)
98 missingOperand();
100 return regMapper[regNo-R_STACK_REG];
103 /* sp + offset to stack register */
104 static int stackRegOffset(rtx operand)
106 int num;
107 num=stackSlotNum(REGNO(operand));
108 return current_function_outgoing_args_size+num*4-totalStackOffset();
111 static int addSpRange(rtx operand, int *found)
113 *found=0;
115 if (current_function_calls_alloca)
117 /* no way to know in this case */
118 return -1;
121 if ((GET_CODE(operand)==REG)&&(REGNO(operand)<R_NUM))
123 if (GET_CODE(reg[REGNO(operand)])==MEM)
125 return loadstoresp_offset(reg[REGNO(operand)], found)-totalStackOffset();
126 } else
128 if ((REGNO(operand)>=R_STACK_REG)&&
129 (REGNO(operand)<=R_STACK_REG_LAST))
131 *found=1;
132 return stackRegOffset(operand);
135 } else
137 return loadstoresp_offset(operand, found)-totalStackOffset();
139 return -1;
142 static void pushRegAddress(rtx operand)
144 /* painful handling of compatiblity with obscure case
145 * of alloca or dynamically sized objects on stack
147 int num;
148 rtx offset;
149 rtx regAddr;
151 num=stackSlotNum(REGNO(operand));
152 regAddr=GEN_INT(REGNO(hard_frame_pointer_rtx)*4);
153 zpu_asm("im %0", &regAddr);
154 zpu_asm("load", NULL);
155 offset=GEN_INT(-(get_frame_size()+calcStackRegSize())+num*4);
156 zpu_immediate(&offset);
157 stackOffset+=4;
158 zpu_asm("add", NULL);
162 static void pushreg(rtx operand)
164 if (REGNO(operand)<R_STACK_REG)
166 if (REGNO(operand)<R_NUM)
168 rtx addr;
169 addr=GEN_INT(REGNO(operand)*4);
170 zpu_asm("im %0", &addr);
171 zpu_asm("load", &operand);
172 } else
174 missingOperand();
176 } else if (REGNO(operand)<R_NUM)
178 if (current_function_calls_alloca)
180 pushRegAddress(operand);
181 zpu_asm("load", NULL);
182 } else
184 int num;
185 num=stackSlotNum(REGNO(operand));
186 zpu_loadsp(current_function_outgoing_args_size+num*4);
187 stackOffset+=4;
189 } else
191 missingOperand();
195 static void popreg(rtx operand)
197 if (REGNO(operand)<R_STACK_REG)
199 if (REGNO(operand)<R_NUM)
201 rtx addr;
202 addr=GEN_INT(REGNO(operand)*4);
203 zpu_asm("im %0", &addr);
204 zpu_asm("store", &operand);
206 } else if (REGNO(operand)<R_NUM)
208 if (current_function_calls_alloca)
210 pushRegAddress(operand);
211 zpu_asm("store", NULL);
212 } else
214 int num;
215 num=stackSlotNum(REGNO(operand));
216 zpu_storesp(current_function_outgoing_args_size+num*4);
218 } else
220 missingOperand();
225 /* returns true if both are registers and they are the same register*/
226 static int compareReg(rtx a, rtx b)
228 if (GET_CODE(a)!=REG)
230 return 0;
232 if (GET_CODE(b)!=REG)
234 return 0;
237 return REGNO(a)==REGNO(b);
240 static void comment(const char *format ATTRIBUTE_UNUSED, rtx *operands ATTRIBUTE_UNUSED)
242 #if 0
243 /* the testsuite chokes on this */
244 output_asm_insn(format, operands);
245 #endif
248 const char * zpu_asm_multi(const char *format, rtx *operands, int byteCount ATTRIBUTE_UNUSED)
250 int im;
251 /* imX, matches IM & IMPCREL */
252 im=strncmp("im", format, 2)==0;
254 if (im&&prevImmediate)
256 /* we need to break the pipe when two immediate instructions follow eachother */
257 output_asm_insn("nop", operands);
259 output_asm_insn(format, operands);
261 prevImmediate=im;
262 return "";
265 static void zpu_asm(const char *format, rtx *operands)
267 zpu_asm_multi(format, operands, 1);
272 struct RegStackEntry GTY(())
274 rtx reg; /* the current location of the register */
277 static GTY(()) struct RegStackEntry regStack[R_NUM*2];
278 static const unsigned int regStackSize=sizeof(regStack)/sizeof(*regStack);
280 static rtx next_insn_saved;
281 static rtx current_insn_saved;
283 static void storeToReg(rtx newLocation, rtx origReg)
285 comment("; explicit pop", &newLocation);
286 if (GET_CODE(newLocation)==REG)
288 popreg(newLocation);
289 } else
291 int found;
292 int loadsp_offset=loadstoresp_offset(newLocation, &found);
293 if (!found)
295 fprintf(stderr, "\nZPU: corrupt regStack\n");
296 missingOperand();
299 comment("; store to register on stack %0", &origReg);
300 zpu_storesp(loadsp_offset);
305 static void persistReg(rtx t)
307 storeToReg(reg[REGNO(t)], t);
308 stackOffset+=4;
312 static void discardRegStackTop(int persist)
314 rtx newLocation;
315 int i;
316 if ((regStackTop>regStackSize)||(regStackTop<=0))
318 fprintf(stderr, "ZPU: corrupt regStack\n");
319 missingOperand();
322 /* this is where we pop the register to... */
323 newLocation=gen_rtx_REG(SImode, REGNO(regStack[regStackTop-1].reg));
325 /* ...or is it still on the stack? */
326 for (i=regStackTop-2; i>=0; i--)
328 if (compareReg(regStack[regStackTop-1].reg, regStack[i].reg))
330 newLocation=gen_rtx_MEM(SImode,
331 gen_rtx_PLUS(SImode, gen_rtx_REG(SImode, R_SP), GEN_INT(-(i+1)*4)));
332 break;
336 reg[REGNO(regStack[regStackTop-1].reg)]=newLocation;
338 if (persist)
340 /* pop the register into the current location */
341 storeToReg(newLocation, regStack[regStackTop-1].reg);
344 regStackTop--;
347 static void popRegStack(void)
349 discardRegStackTop(1);
352 static void pushRegStack(rtx t)
354 if (regStackTop>=regStackSize)
356 fprintf(stderr, "ZPU: corrupt regStack\n");
357 missingOperand();
360 regStack[regStackTop].reg=t;
361 regStackTop++;
363 /* GCC does not know that we are changing the stack pointer.
365 * Hence the saved registers are at a negative offset to GCC's concept of
366 * SP
368 reg[REGNO(t)]=gen_rtx_MEM(SImode,
369 gen_rtx_PLUS(SImode, gen_rtx_REG(SImode, R_SP), GEN_INT(-regStackTop*4)));
373 static int zpu_noop_set(rtx insn)
375 rtx set;
376 set=single_set(insn);
377 if (set!=NULL_RTX)
379 return
380 GET_CODE (SET_SRC (set)) == REG
381 && GET_CODE (SET_DEST (set)) == REG
382 && REGNO (SET_SRC (set)) == REGNO (SET_DEST (set));
384 return 0;
387 static int zpu_can_be_split(rtx insn)
389 rtx set;
390 set=single_set(insn);
391 if (set!=NULL_RTX)
393 return (GET_MODE(SET_SRC (set)) != SImode);
395 return 0;
399 /* it is safe to err on the side of caution here and return 0
400 * if we don't know.
402 static rtx zpu_next_insn(rtx insn)
404 while (insn)
406 insn = NEXT_INSN (insn);
407 switch (GET_CODE(insn))
409 case JUMP_INSN:
410 return insn;
412 case INSN:
413 if (zpu_noop_set(insn))
415 /* DRAGONS! we must skip noop moves, because they
416 * are eliminated by the emitter
418 break;
421 if (zpu_can_be_split(insn))
423 return NULL;
426 return insn;
428 /* skip */
429 case NOTE:
430 break;
432 default:
433 /* we don't handle these */
434 return NULL;
438 return insn;
441 static int stackPlusConst(rtx operand, int *found)
443 rtx op0,op1;
444 *found=0;
445 if(GET_CODE(operand) != PLUS)
447 return 0;
449 op0=XEXP (operand, 0);
450 op1=XEXP (operand, 1);
451 if((GET_CODE(op0)==REG) &&(REGNO(op0)==R_SP)
452 && (GET_CODE(op1)==CONST_INT))
454 *found=1;
455 return INTVAL(op1);
457 if((GET_CODE(op1)==REG) &&(REGNO(op1)==R_SP)
458 && (GET_CODE(op0)==CONST_INT))
460 *found=1;
461 return INTVAL(op0);
463 return 0;
466 static int loadstoresp_offset(rtx operand, int *found)
468 *found=0;
469 if (GET_MODE(operand)!=SImode)
471 return -1;
473 if (GET_CODE(operand)!=MEM)
475 return -1;
477 operand=XEXP(operand, 0);
479 if ((GET_CODE(operand)==REG)&&(REGNO(operand)==R_SP))
481 *found=1;
482 return 0;
484 return stackPlusConst(operand, found);
489 int zpu_binary_operator (rtx op ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED)
491 if (GET_MODE(op)!=SImode)
493 return 0;
496 switch (GET_CODE(op))
498 case LE:
499 case GE:
500 case LEU:
501 case GEU:
502 case GT:
503 case LT:
504 case GTU:
505 case LTU:
506 case COMPARE:
507 case ASHIFT:
508 case XOR:
511 case IOR:
512 case AND:
513 case MINUS:
514 case PLUS:
516 return 1;
517 case ASHIFTRT:
518 return TARGET_ASHIFTRT;
519 case LSHIFTRT:
520 return TARGET_LSHIFTRT;
521 case MULT:
522 return TARGET_MULT;
523 case DIV:
524 return TARGET_DIV;
525 case MOD:
526 return TARGET_MOD;
528 default:
529 break;
531 return 0;
537 int zpu_unary_operator (rtx op ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED)
539 if (GET_MODE(op)!=SImode)
541 return 0;
544 switch (GET_CODE(op))
546 case NEG:
547 case NOT:
548 return 1;
550 default:
551 break;
553 return 0;
556 static int countReg;
558 static int opCheckTerminal(rtx op, enum machine_mode mode ATTRIBUTE_UNUSED, int strict)
560 if (CONSTANT_P(op)&&(GET_CODE(op)!=CONST_DOUBLE))
562 return 1;
565 switch (GET_CODE(op))
567 case REG:
568 if ((REGNO(op)<FIRST_PSEUDO_REGISTER)||!strict)
570 if ((REGNO(op)!=R_PC)&&(REGNO(op)!=R_SP))
572 countReg++;
574 return 1;
576 break;
578 default:
579 break;
582 return 0;
585 /* This function is not about what the ZPU is capable of, but what
586 * the GCC & the backend wants/needs.
588 static int opCheck(rtx op, enum machine_mode mode, int strict)
590 switch (GET_CODE(op))
592 /* we support only *2,4,8 */
593 case MULT:
594 if (opCheckTerminal(XEXP(op, 0), mode, strict))
596 if (GET_CODE(XEXP(op, 1))==CONST_INT)
598 int c=INTVAL(XEXP(op, 1));
599 if ((c==2)||(c==4)||(c==8))
601 return 1;
605 return 0;
606 case PLUS:
607 return opCheckTerminal(XEXP(op, 0), mode, strict)&&
608 opCheckTerminal(XEXP(op, 1), mode, strict);
610 case PRE_DEC:
611 if (REG_P(XEXP(op, 0))&&(REGNO(XEXP(op, 0))==R_SP))
613 return 1;
615 break;
617 case POST_INC:
618 if (((mode==DFmode)||(mode==DImode))&&
619 REG_P(XEXP(op, 0))&&
620 (REGNO(XEXP(op, 0))==R_SP))
622 return 1;
625 if ((mode!=SImode)&&(mode!=HImode)&&(mode!=QImode))
627 return 0;
629 if (REG_P(XEXP(op, 0))&&
630 ((REGNO(XEXP(op, 0))<=R_SP)
632 (!strict&&(REGNO(XEXP(op, 0))>=FIRST_PSEUDO_REGISTER))
637 return 1;
639 break;
641 default:
642 return opCheckTerminal(op, mode, strict);
645 return 0;
650 int zpu_legitimate_address(enum machine_mode mode ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, int strict ATTRIBUTE_UNUSED)
652 countReg=0;
654 if (opCheck(x, SImode, strict))
656 return countReg<MAX_REGS_PER_ADDRESS;
658 return 0;
661 void print_operand (FILE *file, rtx op, int letter)
664 if (letter=='R')
666 print_rtl (file, op);
667 return;
670 switch (GET_CODE (op))
672 case PLUS:
673 print_operand(file, XEXP(op, 0), letter);
674 fprintf(file, "+");
675 print_operand(file, XEXP(op, 1), letter);
676 break;
677 case REG:
678 if (letter=='X')
680 fprintf(file, "%d", REGNO(op)*4);
681 } else
683 fprintf(file, "%s", reg_names[REGNO (op)]);
685 break;
687 case CONST_DOUBLE:
689 if (GET_MODE(op)==SFmode)
691 REAL_VALUE_TYPE r;
692 long l;
694 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
695 REAL_VALUE_TO_TARGET_SINGLE (r, l);
696 asm_fprintf (file, "%I0x%lx", l);
698 #if 0
699 else if (GET_MODE(op)==DFmode)
701 REAL_VALUE_TYPE r;
702 long l[2];
704 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
705 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
706 asm_fprintf (file, "0x%08x%08x", l[0], l[1]);
708 #endif
709 else
711 output_addr_const(file, op);
713 break;
715 case CONST_INT:
716 fprintf(file, "%d", (int)INTVAL (op));
717 break;
719 case LABEL_REF:
720 case SYMBOL_REF:
721 case CODE_LABEL:
722 output_addr_const(file, op);
723 break;
725 case MEM:
726 if (letter!='X')
728 fprintf(file, "(");
730 print_operand(file, XEXP (op, 0), letter);
731 if (letter!='X')
733 fprintf(file, ")");
735 break;
738 default:
739 output_addr_const(file, op);
740 break;
749 static void initGenerate(rtx insn ATTRIBUTE_UNUSED)
751 current_insn=insn;
753 if ((next_insn_saved!=NULL) && (current_insn!=next_insn_saved))
755 rtx t;
756 fprintf(stderr, "ZPU: zpu_next_insn() broken\n");
758 debug_rtx(current_insn_saved);
760 /* for debugging purposes it is useful to look this up again so as
761 * to be able to step through the code
763 t=zpu_next_insn(current_insn_saved);
765 missingOperand();
768 stackOffset=0;
771 static int totalStackOffset(void)
773 int t;
774 /* this is the absolute difference between the ZPU stack
775 * pointer and GCC's concept of a stack pointer
777 t=stackOffset-regStackTop*4;
778 if (t>0)
780 fprintf(stderr, "ZPU: illegal stack offset %d\n", -t);
781 missingOperand();
783 return t;
786 static void zpu_pushspadd(int offset)
788 rtx t;
789 if (TARGET_PUSHSPADD)
791 t=GEN_INT((offset+4)/4);
792 zpu_asm("im %0", &t);
793 zpu_asm("pushspadd", &t);
794 } else
796 t=GEN_INT(offset);
797 zpu_asm("pushsp", &t);
798 if (offset!=0)
800 zpu_asm("im %0", &t);
801 zpu_asm("add", &t);
806 static void zpu_addsp(int offset)
808 rtx t;
809 t=GEN_INT(offset);
810 if (TARGET_ADDSP)
812 zpu_asm("addsp %0", &t);
813 } else
815 zpu_asm("pushsp", NULL);
816 if (offset!=0)
818 zpu_asm("im %0", &t);
819 zpu_asm("add", NULL);
821 zpu_asm("load", NULL);
822 zpu_asm("add", NULL);
826 static void zpu_coreloadsp(int offset)
828 rtx t;
829 if (offset<0)
831 missingOperand();
834 t=GEN_INT(offset);
835 if (TARGET_LOADSP&&(offset/4<32))
837 zpu_asm("loadsp %0", &t);
838 } else
840 zpu_pushspadd(offset);
841 zpu_asm("load", &t);
847 static void zpu_loadsp(int offset)
850 offset-=totalStackOffset();
852 zpu_coreloadsp(offset);
853 stackOffset-=4;
857 static void zpu_storesp(int offset)
859 rtx t;
860 offset-=totalStackOffset();
862 if (offset<0)
864 missingOperand();
867 if (TARGET_STORESP&&(offset/4<32))
869 t=GEN_INT(offset);
870 zpu_asm("storesp %0", &t);
871 } else
873 zpu_pushspadd(offset);
874 zpu_asm("store", &t);
880 static int zpu_stack_change(rtx x)
882 rtx set;
883 set=single_set(x);
884 if (set!=NULL_RTX)
886 rtx dest=SET_DEST(set);
887 rtx src=SET_SRC(set);
888 if ((GET_CODE(dest)==REG)&&(REGNO(dest)==R_SP))
890 return 1;
893 if (GET_CODE(dest)==MEM)
895 if (GET_CODE(XEXP(dest, 0))==PRE_DEC)
897 if (REG_P(XEXP(XEXP(dest, 0), 0))&&REGNO(XEXP(XEXP(dest, 0), 0))==R_SP)
899 return 1;
903 if ((GET_CODE(dest)==REG)&&(REGNO(dest)==R_SP))
905 return 1;
907 if (GET_CODE(src)==MEM)
909 if (GET_CODE(XEXP(src, 0))==POST_INC)
911 if (REG_P(XEXP(XEXP(src, 0), 0))&&REGNO(XEXP(XEXP(src, 0), 0))==R_SP)
913 return 1;
918 return 0;
922 static int isInBasicBlock(rtx insn)
924 if (insn==NULL_RTX)
926 return 0;
928 if (GET_CODE(insn)==INSN)
930 if (!zpu_stack_change(insn))
932 rtx set;
933 set=single_set(insn);
934 if (set!=NULL_RTX)
936 if (GET_CODE(SET_SRC(set))!=ASM_OPERANDS)
938 return 1;
943 return 0;
949 static void cleanupGenerate(void)
951 rtx t;
952 if (stackOffset!=0)
954 fprintf(stderr, "ZPU: stackOffset %d\n", stackOffset);
955 missingOperand();
958 /* purge all dead registers off the stack */
959 while ((regStackTop>0)&&find_regno_note(current_insn, REG_DEAD, REGNO(regStack[regStackTop-1].reg)))
961 popRegStack();
964 /* if we are at the end of the basic block, we must clean up
965 * any unpopped registers
967 t=zpu_next_insn (current_insn);
968 next_insn_saved=NULL_RTX;
969 current_insn_saved=current_insn;
971 if (isInBasicBlock(t))
973 next_insn_saved=t;
974 } else
976 comment("; barrier, purge regstack", &current_insn);
977 while (regStackTop>0)
979 popRegStack();
985 static void push_operand_address(rtx *operand);
986 static void push_operand_value(rtx *operand);
989 static const char *zpu_immediate(rtx *operand)
991 zpu_asm("im %0", operand);
992 stackOffset-=4;
993 return "";
996 static void zpu_neg(rtx *operand)
998 if (TARGET_NEG)
1000 zpu_asm("neg", operand);
1001 } else
1003 /* FIX!!! is this the right sequence? */
1004 zpu_asm("im 1", operand);
1005 zpu_asm("add", operand);
1006 zpu_asm("not", operand);
1011 /* is "find" the first operand to be pushed in "x".
1013 * It is safe to err on the side of caution and say "no", it will
1014 * only potentially make the code ever so slightly less efficient.
1016 static int zpu_first_push(rtx x, rtx find)
1018 int i, j;
1019 enum rtx_code code;
1020 const char *format_ptr;
1021 int count;
1023 if (x==NULL)
1024 return 0;
1026 if (CONSTANT_P(x))
1028 return 0;
1032 code=GET_CODE(x);
1033 switch (code)
1035 case EXPR_LIST:
1036 return 0;
1038 case SET:
1039 return zpu_first_push(SET_SRC(x), find);
1041 case PLUS:
1042 case XOR:
1043 case AND:
1044 case IOR:
1045 return zpu_first_push(XEXP(x, 0), find)||zpu_first_push(XEXP(x, 1), find);
1047 case REG:
1048 return (x==find);
1050 /* these are handled by the generic code below */
1051 case INSN:
1052 break;
1054 default:
1055 /* err on the side of caution */
1056 return 0;
1060 format_ptr = GET_RTX_FORMAT (code);
1061 count = 0;
1063 for (i = 0; i < GET_RTX_LENGTH (code); i++)
1065 switch (*format_ptr++)
1067 case 'e':
1068 return zpu_first_push (XEXP (x, i), find);
1070 case 'E':
1071 for (j = 0; j < XVECLEN (x, i); j++)
1072 return zpu_first_push (XVECEXP (x, i, j), find);
1075 return 0;
1078 static void zpu_call_asm(void)
1080 if (TARGET_CALL)
1082 zpu_asm("call", NULL);
1083 } else
1086 zpu_asm("pushsp ; CALL insn - duplicate top of stack", NULL);
1087 zpu_asm("load", NULL);
1088 zpu_asm("im 6 ; post POPC address", NULL);
1089 zpu_asm("pushpc", NULL);
1090 zpu_asm("add", NULL);
1091 zpu_asm("pushsp", NULL);
1092 zpu_asm("im 4", NULL);
1093 zpu_asm("add", NULL);
1094 zpu_asm("store", NULL);
1095 zpu_asm("poppc ; call function ", NULL);
1101 static void zpu_gen_call(rtx *operand)
1103 comment("/* call %R0 */", operand);
1105 if (GET_CODE(operand[0])!=MEM)
1107 missingOperand();
1110 if (TARGET_CALLPCREL&&CONSTANT_P(XEXP(operand[0], 0)))
1112 zpu_asm("impcrel %0", operand);
1113 zpu_asm("callpcrel", operand);
1114 } else
1116 /* address to call... */
1117 push_operand_address(operand);
1119 if (regStackTop!=0)
1121 fprintf(stderr, "ZPU: regStackTop %d\n", regStackTop);
1122 missingOperand();
1124 zpu_call_asm();
1127 stackOffset+=4;
1132 static int
1133 zpu_count_occurrences (rtx x, rtx find)
1135 int i, j;
1136 enum rtx_code code;
1137 const char *format_ptr;
1138 int count;
1140 if (x==NULL)
1141 return 0;
1143 code=GET_CODE(x);
1144 switch (code)
1146 case EXPR_LIST:
1147 return 0;
1148 default:
1149 break;
1152 if ((GET_CODE(x) == REG)&&(REGNO(x)==REGNO(find)))
1153 return 1;
1156 format_ptr = GET_RTX_FORMAT (code);
1157 count = 0;
1159 for (i = 0; i < GET_RTX_LENGTH (code); i++)
1161 switch (*format_ptr++)
1163 case 'e':
1164 count += zpu_count_occurrences (XEXP (x, i), find);
1165 break;
1167 case 'E':
1168 for (j = 0; j < XVECLEN (x, i); j++)
1169 count += zpu_count_occurrences (XVECEXP (x, i, j), find);
1170 break;
1173 return count;
1176 /* we must err on the side of caution here. */
1177 static int zpu_first_only_push(rtx x, rtx find)
1179 int result=0;
1180 if (zpu_first_push(x, find))
1182 enum rtx_code code;
1183 code=GET_CODE(x);
1184 if (code==SET)
1186 x=SET_SRC(x);
1189 if (zpu_count_occurrences(x, find)==1)
1191 result=1;
1194 return result;
1202 /* if:
1203 * - the GCC-register is REG_DEAD or overwritten
1204 * - the GCC-register is on top of the stack
1205 * - the first push in the instruction is the GCC-register
1206 * - we only use the register once in the operation
1208 * then we can simply remove the instructions that pop/push
1210 static int dead_or_overwritten(rtx insn, rtx op)
1212 int result=0;
1213 if (find_regno_note(insn, REG_DEAD, REGNO (op)))
1215 result=1;
1216 } else
1218 rtx set = single_set (insn);
1219 if (set!=NULL_RTX)
1221 if (SET_DEST(set)==op)
1223 result=1;
1228 return result;
1231 /* Check if the operand on the regStack is one of the operands and
1232 * push it first
1234 static void push_assosiative(rtx operand)
1236 if ((regStackTop>0)&&compareReg(regStack[regStackTop-1].reg, XEXP(operand, 1)))
1238 push_operand_value(&XEXP(operand, 1));
1239 push_operand_value(&XEXP(operand, 0));
1240 } else
1242 /* either this is the other correct way, or it doesn't matter which way we
1243 * do it.
1245 push_operand_value(&XEXP(operand, 0));
1246 push_operand_value(&XEXP(operand, 1));
1251 static int isFreePopPush(rtx *operand)
1253 int freePopPush=0;
1254 if ((GET_CODE(*operand)==REG)&&(REGNO(*operand)<R_NUM)&&(GET_CODE(reg[REGNO(*operand)])==MEM))
1256 /* the GCC-register must be on top of the stack for a free push */
1257 if (stackOffset==0)
1259 if (regStackTop<=0)
1261 fprintf(stderr, "ZPU: regStack corrupted\n");
1262 missingOperand();
1265 if (dead_or_overwritten(current_insn, *operand))
1267 if (zpu_first_only_push(current_insn, *operand))
1269 comment("; stripping regstack until free pop&push is found %0", operand);
1270 /* strip the regstack until we have a free pop */
1271 while (!compareReg(regStack[regStackTop-1].reg, *operand))
1273 popRegStack();
1276 if (regStackTop<=0)
1278 missingOperand();
1280 comment("; eliminated pop&push %0", operand);
1281 if (debug_output)
1283 fprintf(stderr, "ZPU: eliminated poppush!\n");
1284 debug_rtx (current_insn);
1286 freePopPush=1;
1291 return freePopPush;
1294 static int postIncMemSize;
1295 static void push_operand_value(rtx *operand)
1297 if (CONSTANT_P(*operand))
1299 zpu_immediate(operand);
1300 return;
1304 if (GET_CODE(*operand)==REG)
1306 if (REGNO(*operand)==R_PC)
1308 zpu_asm("pushpc", operand);
1309 stackOffset-=4;
1310 } else if (REGNO(*operand)==R_SP)
1312 zpu_asm("pushsp", operand);
1314 if (stackOffset>0)
1316 missingOperand();
1319 if (totalStackOffset()<0)
1321 rtx offset=GEN_INT(-totalStackOffset());
1322 comment("; stack adjustment offset", &offset);
1323 zpu_asm("im %0", &offset);
1324 zpu_asm("add", operand);
1327 stackOffset-=4;
1328 } else if (REGNO(*operand)<R_NUM)
1330 /* push GCC-register */
1331 if (GET_CODE(reg[REGNO(*operand)])==MEM)
1333 if (isFreePopPush(operand))
1335 /* we pretend we pushed it into the stack and clear the top
1336 * stack slot
1338 discardRegStackTop(0);
1339 stackOffset-=4;
1340 } else
1342 comment("; referring to unpopped register %0", operand);
1343 if (debug_output)
1345 fprintf(stderr, "ZPU: unpopped register\n");
1346 debug_rtx (reg[REGNO(*operand)]);
1348 push_operand_value(&reg[REGNO(*operand)]);
1350 } else
1352 pushreg(*operand);
1353 stackOffset-=4;
1355 } else
1357 missingOperand();
1359 return;
1360 } else if (GET_CODE (*operand) == POST_INC)
1362 rtx reg;
1363 rtx size;
1364 reg=XEXP (*operand, 0);
1365 if (GET_CODE(reg)!=REG)
1367 missingOperand();
1370 if (REGNO(reg)>=R_SP)
1372 missingOperand();
1375 push_operand_value(&reg);
1377 zpu_coreloadsp(0);
1378 stackOffset-=4;
1379 size=GEN_INT(postIncMemSize);
1380 zpu_asm("im %0", &size);
1381 zpu_asm("add", operand);
1383 /* we must not leave anything on the stack here */
1384 persistReg(reg);
1385 } else if (GET_CODE (*operand) == MEM)
1387 int found;
1388 int loadsp_offset=loadstoresp_offset(*operand, &found);
1389 if ((GET_CODE(XEXP (*operand, 0))==POST_INC)&&(GET_CODE(XEXP (XEXP (*operand, 0), 0))==REG)&&(REGNO(XEXP (XEXP (*operand, 0), 0))==R_SP))
1391 /* NOTE!!! We pop this off the stack even though it was placed there before we entered
1392 * this tree expansion. */
1393 stackOffset-=4;
1394 } else if (found)
1396 zpu_loadsp(loadsp_offset);
1397 } else
1399 postIncMemSize=GET_MODE_SIZE(GET_MODE(*operand));
1401 push_operand_value(&XEXP (*operand, 0));
1402 switch (GET_MODE(*operand))
1404 case SFmode:
1405 case SImode:
1406 zpu_asm("load", operand);
1407 break;
1408 case HImode:
1409 if (TARGET_SHORTOP)
1411 zpu_asm("loadh", NULL);
1412 } else
1414 zpu_asm("im _loadh", NULL);
1415 zpu_call_asm();
1417 break;
1418 case QImode:
1419 if (TARGET_BYTEOP)
1421 zpu_asm("loadb", NULL);
1422 } else
1424 zpu_asm("im _loadb", NULL);
1425 zpu_call_asm();
1428 break;
1429 default:
1430 fprintf(stderr, "FIX!!!! miissing operand\n");
1431 print_rtl(stderr, *operand);
1432 fprintf(stderr, "\n");
1433 break;
1436 } else if (GET_CODE(*operand)==PLUS)
1438 int found;
1439 int offset;
1440 offset=stackPlusConst(*operand, &found);
1441 if (found&&((offset%4)==0))
1443 offset-=totalStackOffset();
1444 zpu_pushspadd(offset);
1445 stackOffset-=4;
1446 } else
1447 if (isFreePopPush(&XEXP(*operand, 0))||isFreePopPush(&XEXP(*operand, 1)))
1449 push_assosiative(*operand);
1450 zpu_asm("add", operand);
1451 stackOffset+=4;
1452 } else
1454 offset=addSpRange(XEXP(operand[0], 0), &found);
1455 if ((!found)||((offset+4)>MAX_ADDSP))
1457 push_operand_value(&XEXP(operand[0], 0));
1458 offset=addSpRange(XEXP(operand[0], 1), &found);
1459 if (found&&(offset<=MAX_ADDSP))
1461 zpu_addsp(offset);
1462 } else
1464 push_operand_value(&XEXP(operand[0], 1));
1465 zpu_asm("add", NULL);
1466 stackOffset+=4;
1468 } else
1470 push_operand_value(&XEXP(operand[0], 1));
1471 zpu_addsp(offset+4);
1474 } else if ((GET_CODE(*operand)==COMPARE)||(GET_CODE(*operand)==MINUS))
1476 push_operand_value(&XEXP (*operand, 0));
1477 push_operand_value(&XEXP (*operand, 1));
1478 zpu_asm("sub", operand);
1479 stackOffset+=4;
1480 } else if (GET_CODE(*operand)==LABEL_REF)
1482 zpu_immediate(operand);
1483 } else if (GET_CODE(*operand)==SYMBOL_REF)
1485 zpu_immediate(operand);
1486 } else if (GET_CODE(*operand)==CODE_LABEL)
1488 zpu_immediate(operand);
1489 } else if (GET_CODE(*operand)==XOR)
1491 push_assosiative(*operand);
1492 zpu_asm("xor", operand);
1493 stackOffset+=4; /* lost one */
1494 } else if (GET_CODE(*operand)==AND)
1496 push_assosiative(*operand);
1497 zpu_asm("and", operand);
1498 stackOffset+=4; /* lost one */
1499 } else if (GET_CODE(*operand)==IOR)
1501 push_assosiative(*operand);
1502 zpu_asm("or", operand);
1503 stackOffset+=4; /* lost one */
1504 } else if (GET_CODE(*operand)==NOT)
1506 push_operand_value(&XEXP (*operand, 0));
1507 zpu_asm("not", operand);
1508 } else if (GET_CODE(*operand)==NEG)
1510 push_operand_value(&XEXP (*operand, 0));
1511 zpu_neg(operand);
1512 } else if ((GET_CODE(*operand)==EQ)||(GET_CODE(*operand)==NE))
1514 push_operand_value(&XEXP (*operand, 0));
1515 push_operand_value(&XEXP (*operand, 1));
1516 if (TARGET_EQ)
1518 zpu_asm("eq", operand);
1519 } else
1521 zpu_asm("im _eq", NULL);
1522 zpu_call_asm();
1524 if (GET_CODE(*operand)==NE)
1527 zpu_asm("not", operand);
1528 zpu_asm("im 1", operand);
1529 zpu_asm("and", operand);
1531 stackOffset+=4; /* lost one */
1532 } else if ((GET_CODE(*operand)==LE)||(GET_CODE(*operand)==GE)||
1533 (GET_CODE(*operand)==LEU)||(GET_CODE(*operand)==GEU)||
1534 (GET_CODE(*operand)==GT)||(GET_CODE(*operand)==LT)||
1535 (GET_CODE(*operand)==GTU)||(GET_CODE(*operand)==LTU))
1537 int sign;
1538 int flip_args;
1539 int equal;
1540 int code=GET_CODE(*operand);
1542 comment("/* %R0 */", operand);
1544 /* 'less than' is the base case here and then we tweak it into the
1545 * other cases
1547 sign =(code==GE) || (code==LE) || (code==GT) || (code==LT);
1548 flip_args =(code==GT) || (code==GE) || (code==GTU) || (code==GEU);
1549 equal =(code==GE) || (code==LE) || (code==GEU) || (code==LEU);
1551 push_operand_value(&XEXP (*operand, flip_args?0:1)); /* b */
1552 push_operand_value(&XEXP (*operand, flip_args?1:0)); /* a */
1554 if (!sign)
1556 if (equal)
1558 if (TARGET_COMPARE)
1560 zpu_asm("ulessthanorequal", operand);
1561 } else
1563 zpu_asm("im _ulessthanorequal", NULL);
1564 zpu_call_asm();
1566 } else
1568 if (TARGET_COMPARE)
1570 zpu_asm("ulessthan", operand);
1571 } else
1573 zpu_asm("im _ulessthan", NULL);
1574 zpu_call_asm();
1577 } else
1579 if (equal)
1581 if (TARGET_COMPARE)
1583 zpu_asm("lessthanorequal", operand);
1584 } else
1586 zpu_asm("im _lessthanorequal", NULL);
1587 zpu_call_asm();
1589 } else
1591 if (TARGET_COMPARE)
1593 zpu_asm("lessthan", operand);
1594 } else
1596 zpu_asm("im _lessthan", NULL);
1597 zpu_call_asm();
1602 stackOffset+=4; /* lost one */
1603 } else if (GET_CODE(*operand)==LSHIFTRT)
1605 push_operand_value(&XEXP (*operand, 0));
1606 push_operand_value(&XEXP (*operand, 1));
1607 zpu_asm("lshiftright", operand);
1608 stackOffset+=4; /* lost one */
1609 } else if (GET_CODE(*operand)==ASHIFTRT)
1611 push_operand_value(&XEXP (*operand, 0));
1612 push_operand_value(&XEXP (*operand, 1));
1613 zpu_asm("ashiftright", operand);
1614 stackOffset+=4; /* lost one */
1615 } else if (GET_CODE(*operand)==ASHIFT)
1617 if ((GET_CODE(XEXP (*operand, 1))==CONST_INT)&&(INTVAL(XEXP (*operand, 1))==1))
1619 push_operand_value(&XEXP (*operand, 0));
1620 zpu_addsp(0);
1621 } else
1623 push_operand_value(&XEXP (*operand, 0));
1624 push_operand_value(&XEXP (*operand, 1));
1625 zpu_asm("ashiftleft", operand);
1626 stackOffset+=4; /* lost one */
1628 } else if (GET_CODE(operand[0])==MULT)
1630 int mult=1;
1631 /* NOTE! This is a most crucial optimisation as MULT is used in
1632 * address modes.
1634 if ((GET_CODE(XEXP(*operand, 1))==CONST_INT))
1636 int c=INTVAL(XEXP(*operand, 1));
1637 if ((c==0)||(c==1))
1639 missingOperand();
1642 if ((c==2)||((optimize&&!optimize_size)&&((c==4)||(c==8))))
1644 mult=0;
1645 push_operand_value(&XEXP (*operand, 0));
1646 while (c>1)
1648 zpu_addsp(0);
1649 c/=2;
1654 if (mult)
1656 push_operand_value(&XEXP (*operand, 0));
1657 push_operand_value(&XEXP (*operand, 1));
1658 zpu_asm("mult", operand);
1659 stackOffset+=4;
1661 } else if (GET_CODE(operand[0])==DIV)
1663 push_operand_value(&XEXP (*operand, 1));
1664 push_operand_value(&XEXP (*operand, 0));
1665 zpu_asm("div", operand);
1666 stackOffset+=4;
1667 } else if (GET_CODE(operand[0])==MOD)
1669 push_operand_value(&XEXP (*operand, 1));
1670 push_operand_value(&XEXP (*operand, 0));
1671 zpu_asm("mod", operand);
1672 stackOffset+=4;
1673 } else if (GET_CODE(operand[0])==ZERO_EXTEND)
1675 push_operand_value(&XEXP (*operand, 0));
1676 if (GET_CODE(XEXP (*operand, 0))!=MEM)
1678 switch (GET_MODE(XEXP (*operand, 0)))
1680 case VOIDmode:
1681 /* its a bit silly to extend a VOIDmode, i.e. a constant,
1683 * This is a no-op.
1685 break;
1686 case QImode:
1687 zpu_asm("im 0xff", operand);
1688 zpu_asm("and", operand);
1689 break;
1690 case HImode:
1691 zpu_asm("im 0xffff", operand);
1692 zpu_asm("and", operand);
1693 break;
1694 default:
1695 missingOperand();
1698 } else
1700 print_rtl(stderr, *operand);
1701 missingOperand();
1709 /* even registers have addresses on a ZPU that we can push onto the stack */
1710 static void push_operand_address(rtx *operand)
1712 if (GET_CODE (*operand) == MEM)
1714 push_operand_value(&XEXP (*operand, 0));
1715 } else if (GET_CODE(*operand)==SYMBOL_REF)
1717 zpu_immediate(operand);
1718 } else if (GET_CODE (*operand) == REG)
1720 push_operand_value(operand);
1721 } else
1723 missingOperand();
1728 static void store_to_operand(rtx *operand)
1730 if (GET_CODE(*operand)==PC)
1732 zpu_asm("poppc ; jump", operand);
1733 stackOffset+=4;
1734 } else if (GET_CODE(*operand)==REG)
1736 if (REGNO(*operand)==R_SP)
1738 zpu_asm("popsp", operand);
1739 stackOffset+=4;
1740 } else if (REGNO(*operand)==R_PC)
1742 zpu_asm("poppc ; jump", operand);
1743 stackOffset+=4;
1744 } else if (REGNO(*operand)<R_NUM)
1746 if (regStackTop<regStackSize)
1748 /* we always leave the value on the stack, if there is space
1750 * The cleanupGenerate() handles this case.
1752 comment("; left %0 on stack", operand);
1753 pushRegStack(*operand);
1754 stackOffset+=4;
1755 } else
1757 comment("; regStack full", operand);
1758 persistReg(*operand);
1760 } else
1762 missingOperand();
1764 } else if (GET_CODE(operand[0])==MEM)
1766 int found;
1767 int loadsp_offset=loadstoresp_offset(*operand, &found);
1768 if ((GET_MODE(operand[0])!=SFmode)&&(GET_MODE(operand[0])!=SImode)&&(GET_MODE(operand[0])!=HImode)&&(GET_MODE(operand[0])!=QImode))
1770 fprintf(stderr, "\nUnsupported dest\n");
1771 print_rtl (stderr, *operand);
1772 fprintf(stderr, "\n");
1773 abort();
1777 if (GET_CODE(XEXP (operand[0], 0))==PRE_DEC)
1779 rtx reg=XEXP(XEXP(operand[0], 0), 0);
1780 if (!REG_P(reg))
1782 missingOperand();
1784 if (REGNO(reg)==R_SP)
1786 /* we've already pushed the result onto the stack. */
1787 /* we tell a small lie. We change the SP during tree expansion, but we intended to */
1788 stackOffset+=4;
1789 } else
1791 missingOperand();
1793 } else if (found)
1795 zpu_storesp(loadsp_offset);
1796 stackOffset+=4;
1797 } else
1799 postIncMemSize=GET_MODE_SIZE(GET_MODE(*operand));
1801 push_operand_address(operand);
1802 switch (GET_MODE(operand[0]))
1804 case SFmode:
1805 case SImode:
1806 zpu_asm("store", operand);
1807 break;
1808 case HImode:
1809 if (TARGET_SHORTOP)
1811 zpu_asm("storeh", NULL);
1812 } else
1814 zpu_asm("im _storeh", NULL);
1815 zpu_call_asm();
1817 break;
1818 case QImode:
1819 if (TARGET_BYTEOP)
1821 zpu_asm("storeb", NULL);
1822 } else
1824 zpu_asm("im _storeb", NULL);
1825 zpu_call_asm();
1828 break;
1829 default:
1830 fprintf(stderr, "FIX!!!! Missing operand\n");
1831 print_rtl(stderr, *operand);
1832 fprintf(stderr, "\n");
1833 break;
1835 stackOffset+=8;
1837 } else
1839 fprintf(stderr, "\nUnsupported dest\n");
1840 print_rtl (stderr, *operand);
1841 fprintf(stderr, "\n");
1842 abort();
1844 stackOffset+=4;
1850 const char *zpu_generate_move(rtx operands[], rtx insn ATTRIBUTE_UNUSED)
1852 initGenerate(insn);
1854 comment("/* move %R1, %R0 */", operands);
1856 /* first we push the source onto the stack, then we figure out the
1857 * destination
1859 push_operand_value(operands+1);
1861 store_to_operand(operands+0);
1863 cleanupGenerate();
1865 return "";
1868 const char *zpu_generate_set(rtx insn)
1870 rtx set;
1871 initGenerate(insn);
1873 set=single_set(insn);
1874 comment("/* %R0 */", &set);
1876 /* first we push the source onto the stack, then we figure out the
1877 * destination
1879 push_operand_value(&SET_SRC(set));
1881 store_to_operand(&SET_DEST(set));
1883 cleanupGenerate();
1885 return "";
1888 static void zpu_neqbranch(rtx operand)
1891 zpu_asm("impcrel %0", &operand);
1892 if (TARGET_NEQBRANCH)
1895 zpu_asm("neqbranch", NULL);
1896 } else
1898 zpu_asm("im _neqbranch", NULL);
1899 zpu_call_asm();
1904 const char *zpu_generate_if_then_else(rtx operands[], rtx insn ATTRIBUTE_UNUSED)
1906 initGenerate(insn);
1908 comment("/* if_then_else %R0 */", operands);
1910 /* evaluate boolean expression. this RTL contains the two suboperands */
1911 push_operand_value(&operands[0]);
1913 if (regStackTop!=0)
1915 fprintf(stderr, "ZPU: regStackTop %d\n", regStackTop);
1916 missingOperand();
1919 zpu_neqbranch(operands[3]);
1921 stackOffset+=4;
1923 cleanupGenerate();
1925 return "";
1929 const char *zpu_generate_if_not_zero_then_else(rtx operands[], rtx insn ATTRIBUTE_UNUSED)
1931 if ((GET_CODE(operands[2])!=CONST_INT)||INTVAL(operands[2])!=0)
1933 return zpu_generate_if_then_else(operands, insn);
1934 } else
1936 initGenerate(insn);
1938 /* evaluate boolean expression. this RTL contains the two suboperands */
1939 push_operand_value(&operands[0]);
1941 zpu_neqbranch(operands[1]);
1942 stackOffset+=4;
1944 cleanupGenerate();
1947 return "";
1951 static const char *zpu_jump_core(rtx operands[], rtx insn ATTRIBUTE_UNUSED, int table)
1953 initGenerate(insn);
1954 comment("/* jump %R0 */", operands);
1956 /* put address on stack */
1957 push_operand_value(operands+0);
1959 if (table)
1961 comment("/* tablejump */", operands);
1964 zpu_asm("poppc", operands);
1965 stackOffset+=4;
1967 cleanupGenerate();
1969 return "";
1972 const char *zpu_jump(rtx operands[], rtx insn ATTRIBUTE_UNUSED)
1974 return zpu_jump_core(operands, insn, 0);
1977 const char *zpu_table_jump(rtx operands[], rtx insn ATTRIBUTE_UNUSED)
1979 return zpu_jump_core(operands, insn, 1);
1983 const char *zpu_jump_pcrel(rtx operands[], rtx insn ATTRIBUTE_UNUSED)
1985 initGenerate(insn);
1987 if (regStackTop!=0)
1989 fprintf(stderr, "ZPU: regStackTop %d\n", regStackTop);
1990 missingOperand();
1993 /* put address on stack */
1994 if (TARGET_POPPCREL)
1996 zpu_asm("impcrel %0", operands);
1997 zpu_asm("poppcrel", operands);
1998 } else
2000 zpu_asm("im %0", operands);
2001 zpu_asm("poppc", NULL);
2004 cleanupGenerate();
2006 return "";
2010 const char *generate_branch(enum rtx_code code ATTRIBUTE_UNUSED, rtx loc, rtx insn)
2012 return zpu_jump(&loc, insn);
2015 const char *zpu_push(rtx operands[], rtx insn ATTRIBUTE_UNUSED)
2017 initGenerate(insn);
2018 comment("/* push %R0 */", operands);
2019 push_operand_value(operands+0);
2021 /* we tell a small lie. We change the SP during tree expansion, but we intended to */
2022 stackOffset+=4;
2024 cleanupGenerate();
2026 return "";
2030 static int reg_save(int regno)
2032 int result=0;
2033 if (regs_ever_live[regno]&&!call_used_regs[regno])
2035 result=1;
2037 /* FIX!!! how do we check if we've eliminated the argument pointer? */
2038 return result;
2041 static int calcSavedSize(void)
2043 int regno;
2044 int savedSize=0;
2045 for (regno = 0; regno < R_STACK_REG; regno++)
2046 if (reg_save(regno))
2048 savedSize+=4;
2050 return savedSize;
2053 static int calcStackRegSize(void)
2055 int regno;
2056 int savedSize=0;
2057 for (regno = R_STACK_REG; regno < FIRST_PSEUDO_REGISTER; regno++)
2058 if (reg_save(regno))
2060 savedSize+=4;
2062 return savedSize;
2066 /* Define the offset between two registers, one to be eliminated, and the
2067 other its replacement, at the start of a routine. */
2068 int zpu_initial_elimination_offset (int from, int to)
2070 int offset;
2071 /* The difference between the argument pointer and the stack pointer is
2072 * the sum of the size of this function's frame, the callee register save
2073 * area, and the fixed stack space needed for function calls (if any).
2075 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
2077 offset=current_function_outgoing_args_size + calcStackRegSize() + get_frame_size () + calcSavedSize() + 4 ;
2078 } else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
2080 offset=calcSavedSize() + 4;
2081 } else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
2083 offset=current_function_outgoing_args_size + calcStackRegSize() + get_frame_size ();
2084 } else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
2086 offset=0;
2087 } else
2089 abort ();
2091 return offset;
2094 static int allocFrameSize(void)
2096 return current_function_outgoing_args_size+calcStackRegSize()+get_frame_size();
2099 void zpu_expand_prologue (void)
2101 int i;
2102 int regno;
2103 rtx insn;
2104 rtx mem_push_rtx;
2105 HOST_WIDE_INT frameSize;
2106 int mapper=0;
2108 prevImmediate=0;
2109 for (i=R_STACK_REG; i<R_NUM; i++)
2111 regMapper[i-R_STACK_REG]=-1;
2114 for (i=0; i<R_NUM; i++)
2116 if ((i>=R_STACK_REG)&&reg_save(i))
2118 regMapper[i-R_STACK_REG]=mapper++;
2120 reg[i]=gen_rtx_REG(SImode, i);
2122 regStackTop=0;
2125 mem_push_rtx = gen_rtx_MEM (SImode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2127 /* Push each of the registers to save. */
2128 for (regno = 0; regno < R_STACK_REG; regno++)
2129 if (reg_save(regno))
2131 insn = emit_move_insn (mem_push_rtx, gen_rtx_REG (SImode, regno));
2132 RTX_FRAME_RELATED_P (insn) = 1;
2135 /* Set up the frame pointer, if required. */
2136 if (frame_pointer_needed)
2138 insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
2139 RTX_FRAME_RELATED_P (insn) = 1;
2141 /* DANGER!!!! I believe that we can trust the GCC compiler to
2142 * always eliminate the argument pointer register, if not we're
2143 * in trouble, because we do not emit any code here */
2145 frameSize=allocFrameSize();
2146 if (frameSize>0)
2148 insn=emit_move_insn (stack_pointer_rtx,
2149 gen_rtx_PLUS (SImode, stack_pointer_rtx, GEN_INT (-frameSize)));
2150 RTX_FRAME_RELATED_P (insn) = 1;
2155 void zpu_expand_epilogue (void)
2157 rtx mem_pop_rtx, insn;
2158 int regno;
2159 HOST_WIDE_INT frameSize;
2160 rtx mem_push_rtx;
2162 mem_pop_rtx = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2164 frameSize=allocFrameSize();
2165 if (frameSize>0)
2167 insn = emit_move_insn (stack_pointer_rtx,
2168 gen_rtx_PLUS (SImode, stack_pointer_rtx, GEN_INT (frameSize)));
2169 RTX_FRAME_RELATED_P (insn) = 1;
2172 /* Restore any call-saved registers. */
2173 for (regno = R_STACK_REG - 1; regno >= 0; regno--)
2174 if (reg_save(regno))
2176 insn = emit_move_insn (gen_rtx_REG (SImode, regno), mem_pop_rtx);
2179 /* FIX! a single poppc should suffice for no argument fn's */
2180 mem_push_rtx = gen_rtx_MEM (SImode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx));
2181 insn = emit_jump_insn (gen_zpu_return());
2184 rtx zpu_return_addr_rtx(void)
2186 return gen_rtx_MEM (Pmode, plus_constant (virtual_incoming_args_rtx, -4));
2190 const char *zpu_call(rtx operands[], rtx insn ATTRIBUTE_UNUSED)
2192 initGenerate(insn);
2194 zpu_gen_call(operands);
2196 cleanupGenerate();
2197 return "";
2201 const char *zpu_call_value(rtx operands[], rtx insn ATTRIBUTE_UNUSED)
2203 initGenerate(insn);
2205 zpu_gen_call(operands+1);
2207 if ((GET_CODE(operands[0])!=REG)&&(REGNO(operands[0])!=R_R0))
2209 rtx reg=gen_rtx_REG(SImode, 0);
2210 pushreg(reg);
2211 stackOffset-=4;
2213 store_to_operand(operands+0);
2216 cleanupGenerate();
2217 return "";
2220 /* change all QImode and HImode to SImode load's*/
2222 void zpu_expand_set(enum machine_mode mode, rtx operands[])
2224 emit_insn(gen_rtx_SET(mode, operands[0], operands[1]));
2229 static void
2230 zpu_file_start (void)
2232 default_file_start ();
2235 /* Value is the number of bytes of arguments automatically
2236 popped when returning from a subroutine call.
2237 FUNDECL is the declaration node of the function (as a tree),
2238 FUNTYPE is the data type of the function (as a tree),
2239 or for a library call it is an identifier node for the subroutine name.
2240 SIZE is the number of bytes of arguments passed on the stack.
2242 On the ZPU, the RET insn may be used to pop them if the number
2243 of args is fixed, but if the number is variable then the caller
2244 must pop them all.
2245 Use of RET is should be a selectable option, since it is incompatible with
2246 standard Unix calling sequences. If the option is not selected,
2247 the caller must always pop the args.
2252 zpu_return_pops_args (tree fundecl ATTRIBUTE_UNUSED, tree funtype, int size)
2254 if (TREE_CODE (funtype) == IDENTIFIER_NODE)
2255 return size;
2257 if (TYPE_ARG_TYPES (funtype) == NULL_TREE
2258 || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (funtype))) == void_type_node))
2259 return size;
2261 return 0;
2269 move_double_src_operand (rtx op, enum machine_mode mode)
2271 switch (GET_CODE (op))
2273 case CONST_INT :
2274 case CONST_DOUBLE :
2275 return 1;
2277 case SUBREG:
2278 /* FIX! not entirely sure why this isn't
2279 * handled by register_operand
2281 return 1;
2283 case REG :
2284 return register_operand (op, mode);
2286 #if 0
2287 /* (subreg (mem ...) ...) can occur here if the inner part was once a
2288 pseudo-reg and is now a stack slot. */
2289 if (GET_CODE (SUBREG_REG (op)) == MEM)
2290 return move_double_src_operand (SUBREG_REG (op), mode);
2291 else
2292 return register_operand (op, mode);
2293 #endif
2294 case MEM :
2295 /* Disallow auto inc/dec for now. */
2296 if ((GET_CODE (XEXP (op, 0)) == POST_INC)&&
2297 (!REG_P(XEXP (XEXP (op, 0), 0))||
2298 REGNO(XEXP (XEXP (op, 0), 0)))!=R_SP)
2299 return 0;
2300 return memory_operand (op, mode);
2301 default :
2302 return 0;
2306 /* Return true if OP is an acceptable argument for a move destination. */
2309 move_double_dest_operand (rtx op, enum machine_mode mode)
2311 switch (GET_CODE (op))
2313 case REG :
2314 case SUBREG :
2315 return register_operand (op, mode);
2316 #if 0
2317 case SUBREG :
2318 /* (subreg (mem ...) ...) can occur here if the inner part was once a
2319 pseudo-reg and is now a stack slot. */
2320 if (GET_CODE (SUBREG_REG (op)) == MEM)
2321 return address_operand (XEXP (SUBREG_REG (op), 0), mode);
2322 else
2323 return register_operand (op, mode);
2324 #endif
2325 case MEM :
2326 /* Disallow auto inc for now. */
2327 if (GET_CODE (XEXP (op, 0)) == POST_INC)
2328 return 0;
2329 #if 0
2330 /* FIX!!!! a) why isn't this necessary? b) why does it break compilation? */
2331 if ((GET_CODE (XEXP (op, 0)) == PRE_DEC)&&
2332 ((!REG_P(XEXP (XEXP (op, 0), 0))||
2333 REGNO(XEXP (XEXP (op, 0), 0)))!=R_SP))
2334 return 0;
2335 #endif
2336 return memory_operand (op, mode);
2337 default :
2338 return 0;
2343 /* Split a 2 word move (DI or DF) into component parts. */
2346 gen_split_move_double (rtx operands[])
2348 enum machine_mode mode = GET_MODE (operands[0]);
2349 rtx dest = operands[0];
2350 rtx src = operands[1];
2351 rtx val;
2353 /* We might have (SUBREG (MEM)) here, so just get rid of the
2354 subregs to make this code simpler. It is safe to call
2355 alter_subreg any time after reload. */
2356 if (GET_CODE (dest) == SUBREG)
2357 alter_subreg (&dest);
2358 if (GET_CODE (src) == SUBREG)
2359 alter_subreg (&src);
2361 start_sequence ();
2362 if (GET_CODE (dest) == REG)
2364 int dregno = REGNO (dest);
2366 /* Reg = reg. */
2367 if (GET_CODE (src) == REG)
2369 int sregno = REGNO (src);
2371 int reverse = (dregno == sregno + 1);
2373 /* We normally copy the low-numbered register first. However, if
2374 the first register operand 0 is the same as the second register of
2375 operand 1, we must copy in the opposite order. */
2376 emit_insn (gen_rtx_SET (VOIDmode,
2377 operand_subword (dest, reverse, TRUE, mode),
2378 operand_subword (src, reverse, TRUE, mode)));
2380 emit_insn (gen_rtx_SET (VOIDmode,
2381 operand_subword (dest, !reverse, TRUE, mode),
2382 operand_subword (src, !reverse, TRUE, mode)));
2385 /* Reg = constant. */
2386 else if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE)
2388 rtx words[2];
2389 split_double (src, &words[0], &words[1]);
2390 emit_insn (gen_rtx_SET (VOIDmode,
2391 operand_subword (dest, 0, TRUE, mode),
2392 words[0]));
2394 emit_insn (gen_rtx_SET (VOIDmode,
2395 operand_subword (dest, 1, TRUE, mode),
2396 words[1]));
2399 /* Reg = mem. */
2400 else if (GET_CODE (src) == MEM)
2402 /* If the high-address word is used in the address, we must load it
2403 last. Otherwise, load it first. */
2404 int reverse
2405 = (refers_to_regno_p (dregno, dregno + 1, XEXP (src, 0), 0) != 0);
2407 /* We used to optimize loads from single registers as
2409 ld r1,r3+; ld r2,r3
2411 if r3 were not used subsequently. However, the REG_NOTES aren't
2412 propagated correctly by the reload phase, and it can cause bad
2413 code to be generated. We could still try:
2415 ld r1,r3+; ld r2,r3; addi r3,-4
2417 which saves 2 bytes and doesn't force longword alignment. */
2418 emit_insn (gen_rtx_SET (VOIDmode,
2419 operand_subword (dest, reverse, TRUE, mode),
2420 adjust_address (src, SImode,
2421 reverse * UNITS_PER_WORD)));
2423 emit_insn (gen_rtx_SET (VOIDmode,
2424 operand_subword (dest, !reverse, TRUE, mode),
2425 adjust_address (src, SImode,
2426 !reverse * UNITS_PER_WORD)));
2428 else
2429 abort ();
2432 /* Mem = reg. */
2433 /* We used to optimize loads from single registers as
2435 st r1,r3; st r2,+r3
2437 if r3 were not used subsequently. However, the REG_NOTES aren't
2438 propagated correctly by the reload phase, and it can cause bad
2439 code to be generated. We could still try:
2441 st r1,r3; st r2,+r3; addi r3,-4
2443 which saves 2 bytes and doesn't force longword alignment. */
2444 else if (GET_CODE (dest) == MEM && (GET_CODE(XEXP(dest, 0))==PRE_DEC) && GET_CODE (src) == REG)
2446 emit_insn (gen_rtx_SET (VOIDmode,
2447 gen_rtx_MEM(SImode, XEXP(dest, 0)),
2448 operand_subword (src, 1, TRUE, mode)));
2450 emit_insn (gen_rtx_SET (VOIDmode,
2451 gen_rtx_MEM(SImode, XEXP(dest, 0)),
2452 operand_subword (src, 0, TRUE, mode)));
2454 } else if (GET_CODE (dest) == MEM && GET_CODE (src) == REG)
2456 emit_insn (gen_rtx_SET (VOIDmode,
2457 adjust_address (dest, SImode, 0),
2458 operand_subword (src, 0, TRUE, mode)));
2460 emit_insn (gen_rtx_SET (VOIDmode,
2461 adjust_address (dest, SImode, UNITS_PER_WORD),
2462 operand_subword (src, 1, TRUE, mode)));
2465 else
2467 debug_rtx(operands[0]);
2468 debug_rtx(operands[1]);
2469 abort();
2472 val = get_insns ();
2473 end_sequence ();
2474 return val;
2478 const char *zpu_changestackpointer(rtx operands[], rtx insn)
2480 rtx t[2];
2481 rtx set;
2483 set=single_set(insn);
2484 if (set==NULL_RTX)
2486 abort();
2489 t[0]=stack_pointer_rtx;
2490 t[1]=SET_SRC(set);
2492 return zpu_generate_move(t, insn);
2500 #undef TARGET_ASM_FILE_START
2501 #define TARGET_ASM_FILE_START zpu_file_start
2502 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
2503 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
2506 struct gcc_target targetm = TARGET_INITIALIZER;
2509 #include "gt-zpu.h"