home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 6 / FreshFish_September1994.bin / bbs / gnu / gcc-2.6.0-src.lha / GNU / src / amiga / gcc-2.6.0 / config / 1750a / 1750a.c next >
Encoding:
C/C++ Source or Header  |  1994-07-12  |  12.8 KB  |  531 lines

  1. /* Subroutines for insn-output.c for MIL-STD-1750A.
  2.    Copyright (C) 1994 Free Software Foundation, Inc.
  3.    Contributed by O.M.Kellogg, Deutsche Aerospace (okellogg@salyko.cube.net).
  4.  
  5. This file is part of GNU CC.
  6.  
  7. GNU CC is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 1, or (at your option)
  10. any later version.
  11.  
  12. GNU CC is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GNU CC; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. #ifndef FILE
  22. #include <stdio.h>
  23. #endif
  24.  
  25. #define __datalbl
  26. #include "config.h"
  27. #include "rtl.h"
  28. #include "tree.h"
  29. #include "expr.h"
  30. #define HAVE_cc0
  31. #include "conditions.h"
  32. #include "real.h"
  33.  
  34. struct datalabel_array datalbl[DATALBL_ARRSIZ];
  35. int datalbl_ndx = -1;
  36. struct jumplabel_array jmplbl[JMPLBL_ARRSIZ];
  37. int jmplbl_ndx = -1;
  38. int label_pending = 0, program_counter = 0;
  39. enum section  current_section=NREL;
  40. char *sectname[4] = { "NREL","IREL","KREL","SREL" };
  41.  
  42. int notice_update_cc(exp)
  43.   rtx exp;
  44. {
  45.   if (GET_CODE (exp) == SET)
  46.     {
  47.       enum rtx_code src_code = GET_CODE (SET_SRC (exp));
  48.       /* Jumps do not alter the cc's.  */
  49.       if (SET_DEST (exp) == pc_rtx)
  50.     return;
  51.       /* Moving register into memory doesn't alter the cc's.
  52.      It may invalidate the RTX's which we remember the cc's came from.  */
  53.       if (GET_CODE (SET_DEST (exp)) == MEM)
  54.     {
  55.       if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
  56.         cc_status.value1 = 0;
  57.       if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
  58.         cc_status.value2 = 0;
  59.       return;
  60.     }
  61.       /* Function calls clobber the cc's.  */
  62.       else if (src_code == CALL)
  63.     {
  64.       CC_STATUS_INIT;
  65.       return;
  66.     }
  67.       /* Emulated longword bit-ops leave cc's incorrect */
  68.       else if (GET_MODE (SET_DEST (exp)) == HImode ?
  69.                src_code == AND || src_code == IOR ||
  70.                src_code == XOR || src_code == NOT : 0)
  71.     {
  72.       CC_STATUS_INIT;
  73.       return;
  74.     }
  75.       /* Tests and compares set the cc's in predictable ways.  */
  76.       else if (SET_DEST (exp) == cc0_rtx)
  77.     {
  78.       CC_STATUS_INIT;
  79.       cc_status.value1 = SET_SRC (exp);
  80.       return;
  81.     }
  82.       /* Anything that lands in a reg will set cc_status. */
  83.       else if (REG_P (SET_DEST (exp)))
  84.     {
  85.           cc_status.flags = CC_NO_OVERFLOW;
  86.       cc_status.value1 = SET_SRC (exp);
  87.       cc_status.value2 = SET_DEST (exp);
  88.       return;
  89.     }
  90.       else
  91.     {
  92.       CC_STATUS_INIT;
  93.     }
  94.     }
  95.   else if (GET_CODE (exp) == PARALLEL
  96.        && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
  97.     {
  98.       if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
  99.     return;
  100.       if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
  101.     {
  102.       CC_STATUS_INIT;
  103.       cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
  104.       return;
  105.     }
  106.       CC_STATUS_INIT;
  107.     }
  108.   else
  109.     {
  110.       CC_STATUS_INIT;
  111.     }
  112. }
  113.  
  114.  
  115. rtx function_arg(cum,mode,type,named)
  116.   int cum;
  117.   enum machine_mode mode;
  118.   tree type;
  119.   int named;
  120. {
  121.   int size;
  122.   rtx result;
  123.  
  124.   if (MUST_PASS_IN_STACK(mode,type))
  125.     return (rtx) 0;
  126.   if (mode == BLKmode)
  127.     size = int_size_in_bytes(type);
  128.   else
  129.     size = GET_MODE_SIZE (mode);
  130.   if (cum + size < 12) 
  131.     return gen_rtx(REG, mode, cum);
  132.   else
  133.     return (rtx) 0;
  134. }
  135.  
  136.  
  137. char *tekasm_float(exp_char,value)
  138.   char exp_char;
  139.   double value;
  140. {
  141.   extern char *strpbrk();
  142.   int found_letter = 0;
  143.   char *p;
  144.   static char fbuf[20];
  145.     
  146.   sprintf(fbuf,"%g",value);
  147.   if ((p = strpbrk(fbuf,"Ee")) == NULL)
  148.     sprintf(fbuf+strlen(fbuf),"%c0",exp_char);
  149.   else
  150.     *p = exp_char;
  151.   return fbuf;
  152. }
  153.  
  154. char *asm_float_syntax(rtx x)
  155. {
  156.   if (GET_MODE(x) == HFmode)
  157.     {
  158.       union { double d; int i[2]; } du;
  159.       union { float f; int i; } su;
  160.       du.i[0] = CONST_DOUBLE_LOW(x);
  161.       du.i[1] = CONST_DOUBLE_HIGH(x);
  162.       su.f = (float) du.d;
  163.       return tekasm_float('E',su.f);
  164.     }
  165.   else
  166.     {
  167.       union { double d; int i[2]; } du;
  168.       du.i[0] = CONST_DOUBLE_LOW(x);
  169.       du.i[1] = CONST_DOUBLE_HIGH(x);
  170.       return tekasm_float('D',du.d);
  171.     }
  172. }
  173.  
  174. char *float_label(char code,char *fltstr)
  175. {
  176.     int i=1;
  177.     static char label[32];
  178.     
  179.     label[0] = code;
  180.     while (*fltstr)
  181.     {
  182.     label[i] = (*fltstr == '+') ? 'p' :
  183.            (*fltstr == '-') ? 'm' : *fltstr;
  184.     i++;
  185.     fltstr++;
  186.     }
  187.     if (i > 11)
  188.     i = 11;
  189.     label[i] = '\0';
  190.     return label;
  191. }
  192.  
  193.  
  194. char *movcnt_regno_adjust(rtx *op)
  195. {
  196.   static char outstr[40];
  197.   int cntreg = REGNO(op[2]), cntreg_1750 = REGNO(op[0]) + 1;
  198.   int dstreg = REGNO(op[0]), srcreg = REGNO(op[1]);
  199.  
  200.   if (cntreg == cntreg_1750)
  201.     sprintf(outstr,"MOV    R%%0,R%%1");
  202.   else if (dstreg+1 == srcreg && srcreg == cntreg+2)
  203.     sprintf(outstr,"XWR    R%d,R%d\n\tMOV    R%%0,R%%1",cntreg,dstreg);
  204.   else if (dstreg+1 == srcreg && srcreg < cntreg)
  205.     sprintf(outstr,"XWR    R%d,R%d\n\tMOV    R%%0,R%%1",srcreg,cntreg);
  206.   else if (srcreg+1 == cntreg && dstreg > cntreg)
  207.     sprintf(outstr,"XWR    R%d,R%d\n\tMOV    R%%0,R%%1",srcreg,dstreg);
  208.   else
  209.     sprintf(outstr,"XWR    R%d,R%d\n\tMOV    R%%0,%%1\n\tXWR     R%d,R%d",
  210.            cntreg,cntreg_1750,cntreg_1750,cntreg);
  211.   return outstr;
  212. }
  213.  
  214. char *mod_regno_adjust(char *instr,rtx *op)
  215. {
  216.   static char outstr[40];
  217.   char *r = (!strncmp(instr,"DVR",3) ? "R" : "");
  218.   int modregno_gcc = REGNO(op[3]), modregno_1750 = REGNO(op[0]) + 1;
  219.  
  220.   if (modregno_gcc == modregno_1750)
  221.     sprintf(outstr,"%s   R%%0,%s%%2",instr,r);
  222.   else
  223.     sprintf(outstr,"LR     R%d,R%d\n\t%s   R%%0,%s%%2\n\tXWR     R%d,R%d",
  224.         modregno_gcc,modregno_1750,instr,r,modregno_1750,modregno_gcc);
  225.   return outstr;
  226. }
  227.  
  228.  
  229. /* Auxiliary to `nonindirect_operand':
  230.    Check if op is a valid memory operand for 1750A arith./logic (non-move)
  231.    instructions. */
  232. int memop_valid(register rtx op)
  233. {
  234.   if (GET_MODE(op) != Pmode && GET_MODE(op) != VOIDmode)
  235.     return 0;
  236.   switch (GET_CODE(op))
  237.     {
  238.       case MEM:
  239.       case MINUS:
  240.       case MULT:
  241.       case DIV:
  242.     return 0;
  243.       case PLUS:
  244.     if (! memop_valid(XEXP(op,0)))
  245.         return 0;
  246.     return memop_valid(XEXP(op,1));
  247.       case REG:
  248.     if (REGNO(op) > 0)
  249.         return 1;
  250.     return 0;
  251.       case CONST:
  252.       case CONST_INT:
  253.       case SYMBOL_REF:
  254.       case SUBREG:
  255.     return 1;
  256.       default:
  257.     printf("memop_valid: code=%d\n",(int) GET_CODE(op));
  258.     return 1;
  259.     }
  260. }
  261.  
  262. /* extra predicate for recog: */
  263. int nonindirect_operand(register rtx op, enum machine_mode mode)
  264. {
  265.   int retval;
  266.  
  267.   switch (GET_CODE(op))
  268.     {
  269.       case MEM:
  270.     retval = memop_valid(XEXP(op,0));
  271.     return retval;
  272.       case REG:
  273.     return 1;
  274.       default:
  275.     if (! CONSTANT_P(op))
  276.         return 0;
  277.     }
  278.   return 1;
  279. }
  280.  
  281. /* predicate for the STC instruction: */
  282. int small_nonneg_const(register rtx op, enum machine_mode mode)
  283. {
  284.   if (GET_CODE(op) == CONST_INT && INTVAL(op) >= 0 && INTVAL(op) <= 15)
  285.     return 1;
  286.   return 0;
  287. }
  288.  
  289. /* Decide whether to output a conditional jump as a "Jump Conditional"
  290.    or as a "Branch Conditional": */
  291.  
  292. int find_jmplbl(int labelnum)
  293. {
  294.   int i, found = 0;
  295.  
  296.   for (i = 0; i <= jmplbl_ndx; i++)
  297.     if (labelnum == jmplbl[i].num)
  298.       {
  299.     found = 1;
  300.     break;
  301.       }
  302.   if (found)
  303.     return i;
  304.   return -1;
  305. }
  306.  
  307. char *branch_or_jump(char *condition, int targetlabel_number)
  308. {
  309.   static char buf[30];
  310.   int index;
  311.  
  312.   if ((index = find_jmplbl(targetlabel_number)) >= 0)
  313.     if (program_counter - jmplbl[index].pc < 128)
  314.       {
  315.     sprintf(buf,"B%s    %%l0",condition);
  316.     return buf;
  317.       }
  318.   sprintf(buf,"JC     %s,%%l0",condition);
  319.   return buf;
  320. }
  321.  
  322.  
  323.  
  324. /* The PRINT_OPERAND and PRINT_OPERAND_ADDRESS macros have been 
  325.    made functions: */
  326.  
  327. print_operand(file, x, code)
  328.   FILE *file;
  329.   rtx x;
  330.   enum rtx_code code;
  331.   switch (GET_CODE(x))
  332.     {
  333.       case REG:
  334.         fprintf (file, "%d",REGNO (x));
  335.         break;
  336.       case SYMBOL_REF:
  337.         fprintf(file,"%s",XSTR(x,0));
  338.         break;
  339.       case LABEL_REF:
  340.       case CONST:
  341.       case MEM:
  342.         output_address(XEXP(x,0));
  343.         break;
  344.       case CONST_DOUBLE:
  345.         if (code == 'D' || code == 'E')    /* KREL output hack: */
  346.           {        /* make a label out of a floating-point number. */
  347.             char *fltstr = (char *)asm_float_syntax(x);
  348.             int i, found = 0;
  349.             for (i = 0; i <= datalbl_ndx; i++)
  350.           if (strcmp(fltstr,datalbl[i].value) == 0) { found = 1; break; }
  351.             if (! found)
  352.           {
  353.             strcpy(datalbl[i = ++datalbl_ndx].value,fltstr);
  354.                 strcpy(datalbl[i].name,(char *)float_label(code,fltstr));
  355.             datalbl[i].size = (code=='D') ? 3 : 2;
  356.             check_section(KREL);
  357.             fprintf(file,"K%s \tDATAF %s ;p_o\n", datalbl[i].name,fltstr);
  358.             check_section(NREL);
  359.               }
  360.           }
  361.     else if (code == 'F')
  362.       {
  363.             char *fltstr = (char *)asm_float_syntax(x);
  364.             int i, found = 0;
  365.             for (i = 0; i <= datalbl_ndx; i++)
  366.           if (strcmp(fltstr,datalbl[i].value) == 0)
  367.         {
  368.           found = 1;
  369.           break;
  370.         }
  371.             if (! found)
  372.           {
  373.         printf("Aborting: 'F' float label not found in datalbl[].\n");
  374.          abort();
  375.           }
  376.         fprintf(file,"%s ;P_O 'F'",datalbl[i].name);
  377.           }
  378.     else
  379.       fprintf(file,"%s  ;P_O cst_dbl",(char *)asm_float_syntax(x));
  380.     break;
  381.       case CONST_INT:
  382.     if (code == 'J')
  383.       fprintf (file, "%d",-INTVAL(x));
  384.     else if (INTVAL(x) > 0x7FFF)
  385.       fprintf (file, "%d  ; range correction (val>0x7FFF) applied",
  386.               INTVAL(x) - 0x10000);
  387.     else
  388.       fprintf (file, "%d", INTVAL(x));
  389.     break;
  390.       case CODE_LABEL:
  391.     fprintf (file, "L%d", XINT(x,3));
  392.     break;
  393.       case CALL:
  394.     fprintf(file,"CALL nargs=%d, func is either '%s' or '%s'",
  395.                 XEXP(x,1),XSTR(XEXP(XEXP(x,0),1),0),XSTR(XEXP(x,0),1));
  396.     break;
  397.       case PLUS:
  398.         {
  399.       rtx op0 = XEXP(x,0), op1 = XEXP(x,1);
  400.       int op0code=GET_CODE(op0), op1code=GET_CODE(op1);
  401.           if (op1code == CONST_INT)
  402.             switch (op0code)
  403.           {
  404.         case REG:
  405.           fprintf(file,"%d,R%d  ; p_o_PLUS for REG and CONST",
  406.             INTVAL(op1),REGNO(op0));
  407.           break;
  408.         case SYMBOL_REF:
  409.           fprintf(file,"%d+%s",INTVAL(op1),XSTR(op0,0));
  410.           break;
  411.         case MEM:
  412.           fprintf(file,"%d,[mem:",INTVAL(op1));
  413.           output_address(XEXP(op0,0));
  414.           fprintf(file,"] ;P_O plus");
  415.           break;
  416.         default:
  417.           fprintf(file,"p_o_PLUS UFO, code=%d, with CONST=%d",
  418.                 (int)op0code,INTVAL(op1));
  419.           }
  420.       else if (op1code == SYMBOL_REF && op0code == REG)
  421.         fprintf(file,"%s,R%d  ; P_O: (plus reg sym)",
  422.             XSTR(op1,0),REGNO(op0));
  423.           else
  424.             fprintf(file,"p_o_+: op0code=%d, op1code=%d",op0code,op1code);
  425.         }
  426.     break;
  427.       default:
  428.     fprintf (file, "p_o_UFO code=%d", GET_CODE(x));
  429.     }
  430. }
  431.  
  432. print_operand_address(file, addr)
  433.   FILE *file;
  434.   rtx addr;
  435. {
  436.   switch (GET_CODE (addr))
  437.     {
  438.       case REG:
  439.     fprintf (file, "0,R%d ; P_O_A", REGNO (addr));
  440.     break;
  441.       case PLUS:
  442.     {
  443.       register rtx x = XEXP(addr,0), y = XEXP(addr,1);
  444.       switch (GET_CODE(x))
  445.         {
  446.           case REG:
  447.                 switch (GET_CODE(y))
  448.           {
  449.             case CONST:
  450.               output_address(XEXP(y,0));
  451.               fprintf(file, ",R%d ;P_O_A reg + const expr",REGNO(x));
  452.               break;
  453.             case CONST_INT:
  454.               fprintf(file,"%d,R%d  ; P_O_A reg + const_int",
  455.                 INTVAL(y),REGNO(x));
  456.               break;
  457.             case SYMBOL_REF:
  458.               fprintf(file,"%s,R%d  ; P_O_A reg + sym",
  459.                 XSTR(y,0),REGNO(x));
  460.               break;
  461.             default:
  462.               fprintf(file, "[P_O_A reg%d+UFO code=%d]",
  463.                     REGNO(x),GET_CODE(y));
  464.            }
  465.         break;
  466.           case LABEL_REF:
  467.           case SYMBOL_REF:
  468.         switch (GET_CODE(y))
  469.           {
  470.             case CONST_INT:
  471.                fprintf (file,"%d+%s",INTVAL(y),XSTR(x,0));
  472.                break;
  473.             case REG:
  474.               fprintf (file,"%s,R%d ;P_O_A sym + reg",
  475.                  XSTR(x,0),REGNO(y));
  476.               break;
  477.             default:
  478.               fprintf(file, "P_O_A sym/lab+UFO[sym=%s,code(y)=%d]",
  479.                  XSTR(x,0),GET_CODE(y));
  480.           }
  481.          break;
  482.           case CONST:
  483.             output_address(XEXP(x,0));
  484.             if (GET_CODE(y) == REG)
  485.           fprintf(file, ",R%d ;P_O_A const + reg",REGNO(x));
  486.             else
  487.           fprintf(file,"P_O_A const+UFO code(y)=%d]",GET_CODE(y));
  488.             break;
  489.           case MEM:
  490.         output_address(y);
  491.         fprintf(file, ",[mem:");
  492.         output_address(XEXP(x,0));
  493.         fprintf(file, "] ;P_O_A plus");
  494.         break;
  495.           default:
  496.         fprintf(file, "P_O_A plus op1_UFO[code1=%d,code2=%d]",
  497.             GET_CODE(x),GET_CODE(y));
  498.         }
  499.     }
  500.     break;
  501.       case CONST_INT:
  502.     if (INTVAL(addr) < 0x10000 && INTVAL(addr) >= -0x10000)
  503.       fprintf (file, "%d ; p_o_a const addr?!", INTVAL(addr));
  504.     else
  505.       {
  506.         fprintf(file,"[p_o_a=ILLEGAL_CONST]");
  507.         output_addr_const (file, addr);
  508.       }
  509.     break;
  510.       case LABEL_REF:
  511.       case SYMBOL_REF:
  512.     fprintf(file,"%s",XSTR(addr,0));
  513.     break;
  514.       case MEM:
  515.     fprintf(file,"[memUFO:");
  516.     output_address(XEXP(addr,0));
  517.     fprintf(file,"]");
  518.     break;
  519.       case CONST:
  520.     output_address(XEXP(addr,0));
  521.     fprintf(file," ;P_O_A const");
  522.     break;
  523.       default:
  524.     fprintf(file," p_o_a UFO, code=%d val=0x%x",
  525.             (int) GET_CODE(addr),INTVAL(addr));
  526.     break;
  527.     }
  528. }
  529.  
  530.