home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / gcc / config / pa / next.c < prev    next >
C/C++ Source or Header  |  1996-06-12  |  9KB  |  332 lines

  1.  
  2. /* next.c:  Functions for NeXT as target machine for GNU C compiler.  */
  3.  
  4. #include "pa/pa.c"
  5. #include "next/nextstep.c"
  6. #include "next/machopic.h"
  7.  
  8. void add_vararg_func PROTO((char *, char));
  9. int check_vararg_func PROTO((char *));
  10. int check_duplicate_entry PROTO((char *));
  11.  
  12. #define STUB_LABEL_NAME(STUB)     TREE_VALUE (STUB)
  13. #define STUB_FUNCTION_NAME(STUB)  TREE_PURPOSE (STUB)
  14. #define STUB_LINE_NUMBER(STUB)    TREE_INT_CST_LOW (TREE_TYPE (STUB))
  15.  
  16. static tree stub_list = 0;
  17.  
  18. /* Following function adds the compiler generated stub for handling 
  19.    procedure calls to the linked list.
  20. */
  21.  
  22. void 
  23. add_compiler_stub(label_name, function_name, line_number)
  24.      tree label_name;
  25.      tree function_name;
  26.      int line_number;
  27. {
  28.   tree stub;
  29.   
  30.   stub = build_tree_list (function_name, label_name);
  31.   TREE_TYPE (stub) = build_int_2 (line_number, 0);
  32.   TREE_CHAIN (stub) = stub_list;
  33.   stub_list = stub;
  34. }
  35.  
  36. /* Following function outputs the compiler generated stub for handling 
  37.    procedure calls from the linked list and initialises the linked list.
  38. */
  39. void output_compiler_stub()
  40. {
  41.   char tmp_buf[256];
  42.   char label_buf[256];
  43.   char *label;
  44.   tree tmp_stub, stub;
  45.   
  46.   for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
  47.     {
  48.      fprintf (asm_out_file, "%s:\n", IDENTIFIER_POINTER(STUB_LABEL_NAME(stub)));
  49. #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
  50.       if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
  51.     fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub));
  52. #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
  53.  
  54.       if (flag_pic == 2)
  55.     {
  56.       char *local = IDENTIFIER_POINTER (STUB_LABEL_NAME (stub));
  57.       label = machopic_stub_name (IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub)));
  58.     
  59.           machopic_validate_stub (label);
  60.       if (label[0] == '*') label += 1;
  61.  
  62.       sprintf (tmp_buf, "bl L$%s,%%%%r19\n\tnop\nL$%s:", local, local);
  63.       output_asm_insn (tmp_buf, 0);
  64.  
  65.       output_asm_insn ("depi 0,31,2,%%r19", 0);
  66.  
  67.       sprintf (tmp_buf, "addil L`%s-L$%s,%%%%r19", label, local);
  68.       output_asm_insn (tmp_buf, 0);
  69.  
  70.       sprintf (tmp_buf, "ldo R`%s-L$%s(%%%%r1),%%%%r19", label, local);
  71.       output_asm_insn (tmp_buf, 0);
  72.  
  73.       output_asm_insn ("be,n 0(4,%%r19)", 0);
  74.     }
  75.       else
  76.     {
  77.             if (IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))[0] == '*')
  78.               {
  79.                 strcpy (label_buf, IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))+1);
  80.               }
  81.             else
  82.               {
  83.                   label_buf[0] = '_';
  84.                   strcpy (label_buf+1, IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub)));
  85.               }
  86.  
  87.             strcpy (tmp_buf, "ldil L%'");
  88.             strcat (tmp_buf, label_buf);
  89.     
  90.             strcat (tmp_buf, ",%%r1\n\tble,n R%'");
  91.             strcat (tmp_buf, label_buf);
  92.     
  93.             strcat (tmp_buf, "(4,%%r1)");
  94.  
  95.             output_asm_insn (tmp_buf, 0);
  96.     }
  97.  
  98. #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
  99.     if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
  100.       fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub));
  101. #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
  102.   } 
  103.   
  104.   stub_list = 0;
  105. }
  106.  
  107. /* Following function checks in the link list whether the function name is
  108.    already there or not.  
  109. */
  110. int no_previous_def(function_name)
  111.      tree function_name;
  112. {
  113.   tree stub;
  114.   for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
  115.     {
  116.       if (function_name == STUB_FUNCTION_NAME (stub))
  117.     return 0;
  118.     }
  119.   return 1;
  120. }
  121.  
  122. /* Following function gets the label name from the previous definition of
  123.    the function
  124. */
  125. tree get_prev_label(function_name)
  126.      tree function_name;
  127. {
  128.   tree stub;
  129.   for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
  130.     {
  131.       if (function_name == STUB_FUNCTION_NAME (stub))
  132.     return STUB_LABEL_NAME (stub);
  133.     }
  134.   return 0;
  135. }
  136.  
  137. struct vararg_list
  138. {
  139.   char function_name[256];
  140.   char flag;
  141.   struct vararg_list *next_stub;
  142. };
  143.  
  144. struct vararg_list *startvararg, *currvararg;
  145.  
  146. /* Following function adds the function name to the linked list.
  147.    If function is a  variable argument function make flag = 1 else 0;
  148. */
  149. void add_vararg_func(function_name, flag)
  150. char *function_name;
  151. char flag;
  152. {
  153.   struct vararg_list *temppointer;
  154.  
  155.   if (check_duplicate_entry(function_name))
  156.   {
  157.     return;
  158.   }
  159.  
  160.   temppointer = (struct vararg_list *)calloc(sizeof(struct vararg_list), 1);
  161.   strcpy(temppointer->function_name, function_name);
  162.   temppointer->flag = flag;
  163.   if (startvararg == NULL)
  164.   {
  165.     startvararg = temppointer;
  166.   }
  167.   else
  168.   {
  169.     currvararg->next_stub = temppointer;
  170.   }
  171.  
  172.   currvararg  = temppointer;
  173.   currvararg->next_stub = NULL;
  174. }
  175.  
  176. /* Following function checks in the link list whether the function name is
  177.    already there or not for vararg functions
  178. */
  179.  int check_vararg_func(function_name)
  180. char *function_name;
  181. {
  182.   struct vararg_list *temppointer;
  183.  
  184.   temppointer = startvararg;
  185.   while (temppointer)
  186.   {
  187.    if (!strcmp(temppointer->function_name, function_name))
  188.    {
  189.       if (temppointer->flag == '1')
  190.          return 1;
  191.       else
  192.          return 0;
  193.    }
  194.     temppointer = temppointer->next_stub;
  195.   }
  196.   return 1;
  197. }
  198. /* Following function checks in the link list whether the function name is
  199.    already there or not for all functions
  200. */
  201.  int check_duplicate_entry(function_name)
  202. char *function_name;
  203. {
  204.   struct vararg_list *temppointer;
  205.  
  206.   temppointer = startvararg;
  207.   while (temppointer)
  208.   {
  209.    if (!strcmp(temppointer->function_name, function_name))
  210.    {
  211.          return 1;
  212.    }
  213.     temppointer = temppointer->next_stub;
  214.   }
  215.   return 0;
  216. }
  217.  
  218. add_profiler_info(insn, label_buf, line_number)
  219. rtx insn;
  220. char *label_buf;
  221. int line_number;
  222. {
  223.   tree labelname;
  224.   tree funcname;
  225.  
  226.   labelname = get_identifier(label_buf);
  227.   funcname = get_identifier("*mcount");
  228.       
  229.   add_compiler_stub(labelname, funcname, line_number);
  230. }
  231.  
  232. char*
  233. output_profile_call (rtx insn, rtx* operands)
  234. {
  235.   rtx label_rtx = gen_label_rtx ();
  236.   static char buf[256];
  237.   static char temp_buf[300];
  238.   char *the_label;
  239.   int i;
  240.   rtx prev_insn;
  241.   int line_number;
  242.  
  243.   ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
  244.                    CODE_LABEL_NUMBER (label_rtx));
  245.  
  246.   if (temp_buf[0] == '*')
  247.     the_label = temp_buf+1;
  248.  
  249.   else
  250.     the_label = temp_buf;
  251.  
  252.   strcpy(buf, "jbsr mcount,%%r2,");
  253.   strcat(buf, the_label);
  254.   output_asm_insn (buf, operands);
  255.   prev_insn = insn;
  256.   while (prev_insn && GET_CODE(prev_insn) != NOTE)
  257.     {
  258.       prev_insn = PREV_INSN (prev_insn);
  259.     };
  260.   line_number = prev_insn ? NOTE_LINE_NUMBER(prev_insn) : 0;
  261.   add_profiler_info(insn, the_label, line_number);
  262.   return "ldo %0(%%r2),%%r25";
  263. }
  264.  
  265. void
  266. machopic_output_stub (file, symb, stub)
  267.      FILE *file;
  268.      const char *symb, *stub;
  269. {
  270.   unsigned int length;
  271.   char *binder_name, *symbol_name, *lazy_ptr_name;
  272.   static int label = 0;
  273.  
  274.   label += 1;
  275.  
  276.   length = strlen(stub);
  277.   binder_name = alloca(length + 32);
  278.   GEN_BINDER_NAME_FOR_STUB(binder_name, stub, length);
  279.  
  280.   length = strlen(symb);
  281.   symbol_name = alloca(length + 32);
  282.   GEN_SYMBOL_NAME_FOR_SYMBOL(symbol_name, symb, length);
  283.  
  284.   lazy_ptr_name = alloca(length + 32);
  285.   GEN_LAZY_PTR_NAME_FOR_SYMBOL(lazy_ptr_name, symb, length);
  286.  
  287.   if (MACHOPIC_PURE)
  288.     machopic_picsymbol_stub_section ();
  289.   else
  290.     machopic_symbol_stub_section ();
  291.  
  292.   fprintf (file, "%s:\n", stub);
  293.   fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
  294.  
  295.   if (MACHOPIC_PURE)
  296.     {
  297.       fprintf (file, "\taddil L`%s-%s,%%r19\n", lazy_ptr_name, stub);
  298.       fprintf (file, "\tldw R`%s-%s(%%r1),%%r19\n", lazy_ptr_name, stub);
  299.       fprintf (file, "\tbe,n 0(4,%%r19)\n");
  300.     }
  301.   else
  302.     {
  303.       fprintf (file, "\tjmp *%s\n", lazy_ptr_name);
  304.     }
  305.   
  306.   fprintf (file, "%s:\n", binder_name);
  307.   
  308.   if (MACHOPIC_PURE)
  309.     {
  310.       char *binder = machopic_non_lazy_ptr_name ("*dyld_stub_binding_helper");
  311.       machopic_validate_non_lazy_ptr (binder);
  312.       if (binder[0] == '*') binder += 1;
  313.       fprintf (file, "\taddil L`%s-%s,%%r19\n", lazy_ptr_name, binder_name);
  314.       fprintf (file, "\tldo R`%s-%s(%%r1),%%r21\n", lazy_ptr_name,
  315.            binder_name);
  316.       fprintf (file, "\taddil L`%s-%s,%%r19\n", binder, binder_name);
  317.       fprintf (file, "\tldw R`%s-%s(%%r1),%%r19\n", binder, binder_name);
  318.       fprintf (file, "\tbe,n 0(4,%%r19)\n");
  319.     }
  320.   else
  321.     {
  322.       fprintf (file, "\t pushl $%s\n", lazy_ptr_name);
  323.       fprintf (file, "\tjmp dyld_stub_binding_helper\n");
  324.     }
  325.  
  326.   machopic_lazy_symbol_ptr_section ();
  327.   fprintf (file, "%s:\n", lazy_ptr_name);
  328.   fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
  329.   fprintf (file, "\t.long %s\n", binder_name);
  330. }
  331.  
  332.