home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer) / NeXT_Developer-3.3.iso / NextDeveloper / Source / GNU / cc / config / pa / next.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-18  |  7.6 KB  |  315 lines

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