Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / gcc / config / i386 / interix.c
1 /* Subroutines for insn-output.c for Windows NT.
2    Copyright (C) 1998, 1999 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "rtl.h"
24 #include "regs.h"
25 #include "hard-reg-set.h"
26 #include "output.h"
27 #include "tree.h"
28 #include "flags.h"
29
30 /* Return string which is the former assembler name modified with a 
31    suffix consisting of an atsign (@) followed by the number of bytes of 
32    arguments */
33
34 char *
35 gen_stdcall_suffix (decl)
36   tree decl;
37 {
38   int total = 0;
39   /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
40      of DECL_ASSEMBLER_NAME.  */
41   char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
42   char *newsym;
43
44   if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
45     if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl)))) 
46         == void_type_node)
47       {
48         tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
49
50         while (TREE_VALUE (formal_type) != void_type_node)
51           {
52             int parm_size
53               = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
54             /* Must round up to include padding.  This is done the same
55                way as in store_one_arg.  */
56             parm_size = ((parm_size + PARM_BOUNDARY - 1)
57                          / PARM_BOUNDARY * PARM_BOUNDARY);
58             total += parm_size;
59             formal_type = TREE_CHAIN (formal_type);
60           }
61       }
62
63   newsym = xmalloc (strlen (asmname) + 10);
64   sprintf (newsym, "%s@%d", asmname, total/BITS_PER_UNIT);
65   return IDENTIFIER_POINTER (get_identifier (newsym));
66 }
67
68 #if 0   
69 /* Turn this back on when the linker is updated to handle grouped
70    .data$ sections correctly. See corresponding note in i386/interix.h. 
71    MK. */
72
73 /* Cover function for UNIQUE_SECTION.  */
74
75 void
76 i386_pe_unique_section (decl, reloc)
77      tree decl;
78      int reloc;
79 {
80   int len;
81   char *name,*string,*prefix;
82
83   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
84   /* Strip off any encoding in fnname.  */
85   STRIP_NAME_ENCODING (name, name);
86
87   /* The object is put in, for example, section .text$foo.
88      The linker will then ultimately place them in .text
89      (everything from the $ on is stripped). Don't put
90      read-only data in .rdata section to avoid a PE linker 
91      bug when .rdata$* grouped sections are used in code
92      without a .rdata section.  */
93   if (TREE_CODE (decl) == FUNCTION_DECL)
94     prefix = ".text$";
95   else if (DECL_READONLY_SECTION (decl, reloc))
96 #ifdef READONLY_DATA_SECTION
97     prefix = ".rdata$";
98 #else
99     prefix = ".text$";
100 #endif
101   else
102     prefix = ".data$";
103   len = strlen (name) + strlen (prefix);
104   string = alloca (len + 1);
105   sprintf (string, "%s%s", prefix, name);
106
107   DECL_SECTION_NAME (decl) = build_string (len, string);
108 }
109
110 #endif /* 0 */