1 /* file "positioning.cc" */
3 /* Copyright (c) 1995 Stanford University
7 This software is provided under the terms described in
8 the "suif_copyright.h" include file. */
10 #include <suif_copyright.h>
13 * This is the implementation of variable positioning routines for the
14 * SUIF library of miscellaneous useful routines.
17 #define _MODULE_ "libuseful.a"
19 #pragma implementation "basic.h"
21 #define RCS_BASE_FILE positioning_cc
23 #include "useful_internal.h"
27 "$Id: positioning.cc,v 1.1.1.1 1998/06/16 15:15:36 brm Exp $")
30 #define COMBO_NAME_PREFIX "__suif_combo_"
33 static char *generate_combination_name(void);
36 extern boolean
set_relative_positions(var_sym
*var1
, var_sym
*var2
,
38 offset_kind which_offset
)
40 base_symtab
*parent
= var1
->parent();
41 if (parent
!= var2
->parent())
43 if (var1
->is_param() || var2
->is_param())
45 if (var1
->is_auto() != var2
->is_auto())
47 if (var1
->is_reg() != var2
->is_reg())
49 var_sym
*root1
= var1
->root_ancestor();
50 var_sym
*root2
= var2
->root_ancestor();
51 if (parent
->kind() == SYMTAB_GLOBAL
)
53 if ((!root1
->has_var_def()) || (!root2
->has_var_def()))
56 i_integer start_to_start_offset
;
59 case OFFSET_START_TO_START
:
60 start_to_start_offset
= offset
;
62 case OFFSET_START_TO_END
:
63 start_to_start_offset
= offset
- var2
->type()->size();
65 case OFFSET_END_TO_START
:
66 start_to_start_offset
= offset
+ var1
->type()->size();
68 case OFFSET_END_TO_END
:
69 start_to_start_offset
=
70 (offset
+ var1
->type()->size()) - var2
->type()->size();
75 start_to_start_offset
=
76 (start_to_start_offset
+ var1
->root_offset()) -
79 return (start_to_start_offset
== 0);
80 if (start_to_start_offset
< 0)
82 start_to_start_offset
= -start_to_start_offset
;
83 var_sym
*temp_root
= root1
;
87 base_init_struct_list
*initialization
= NULL
;
88 if (root1
->has_var_def())
90 assert(root2
->has_var_def());
91 var_def
*def1
= root1
->definition();
92 var_def
*def2
= root2
->definition();
93 assert((def1
!= NULL
) && (def2
!= NULL
));
94 base_init_struct_list
*init1
= read_init_data(def1
);
95 base_init_struct_list
*init2
= read_init_data(def2
);
96 base_init_struct_list
*leftovers
;
98 split_init_data(init1
, start_to_start_offset
.c_int(),
99 &initialization
, &leftovers
);
102 deallocate_init_data(init1
);
103 deallocate_init_data(init2
);
106 if (!leftovers
->is_empty())
108 deallocate_init_data(initialization
);
109 deallocate_init_data(leftovers
);
110 deallocate_init_data(init2
);
113 deallocate_init_data(leftovers
);
114 i_integer skip_total
= 0;
115 base_init_struct_list_iter
init_iter(initialization
);
116 while (!init_iter
.is_empty())
118 base_init_struct
*this_init_struct
= init_iter
.step();
119 skip_total
+= this_init_struct
->total_size();
121 assert(skip_total
<= start_to_start_offset
);
122 if (skip_total
< start_to_start_offset
)
124 int fill_size
= (start_to_start_offset
- skip_total
).c_int();
125 initialization
->append(new fill_init_struct(fill_size
, 0));
127 initialization
->append(init2
);
130 i_integer alignment1
= get_alignment(root1
->type());
131 i_integer alignment2
= get_alignment(root2
->type());
134 i_integer gcd
= ii_gcd(alignment1
, alignment2
, &coeff_n
, &coeff_m
);
135 i_integer lcm
= (alignment1
/ gcd
) * alignment2
;
136 if ((start_to_start_offset
% gcd
) != 0)
139 "set_relative_positions(): requested relative offset "
140 "violates alignment restrictions");
142 i_integer first_offset
=
143 (- alignment1
* coeff_n
* (start_to_start_offset
/ gcd
)) % lcm
;
144 if (first_offset
< 0)
146 i_integer second_offset
= first_offset
+ start_to_start_offset
;
147 assert(first_offset
>= 0);
148 assert(second_offset
>= 0);
149 i_integer end1
= first_offset
+ root1
->type()->size();
150 i_integer end2
= second_offset
+ root2
->type()->size();
151 i_integer total_size
;
156 assert(total_size
>= 0);
157 if (!total_size
.is_c_int())
160 "set_relative_positions(): overflow in total size of "
161 "requested combined entity");
163 assert(first_offset
.is_c_int());
164 assert(second_offset
.is_c_int());
165 char *new_name
= generate_combination_name();
166 struct_type
*new_type
=
167 new struct_type(TYPE_GROUP
, total_size
.c_int(), new_name
, 2);
168 new_type
->set_field_name(0, root1
->name());
169 new_type
->set_field_type(0, root1
->type());
170 new_type
->set_offset(0, first_offset
.c_int());
171 new_type
->set_field_name(1, root2
->name());
172 new_type
->set_field_type(1, root2
->type());
173 new_type
->set_offset(1, second_offset
.c_int());
174 new_type
= (struct_type
*)(parent
->install_type(new_type
));
176 var_sym
*combined_var
= parent
->new_var(new_type
, new_name
);
178 if (root1
->has_var_def())
180 assert(root2
->has_var_def());
181 var_def
*def1
= root1
->definition();
182 var_def
*def2
= root2
->definition();
183 assert((def1
!= NULL
) && (def2
!= NULL
));
187 "set_relative_positions(): overflow in alignment of "
188 "requested combined entity");
191 def1
->parent()->define_var(combined_var
, lcm
.c_int());
192 def1
->parent()->remove_def(def1
);
193 def2
->parent()->remove_def(def2
);
196 if (initialization
!= NULL
)
198 if (first_offset
> 0)
200 int fill_size
= first_offset
.c_int();
201 initialization
->push(new fill_init_struct(fill_size
, 0));
203 write_init_data(new_def
, initialization
);
204 deallocate_init_data(initialization
);
208 if (root1
->is_addr_taken() || root2
->is_addr_taken())
209 combined_var
->set_addr_taken();
211 combined_var
->reset_addr_taken();
212 combined_var
->add_child(root1
, first_offset
.c_int());
213 combined_var
->add_child(root2
, second_offset
.c_int());
218 static char *generate_combination_name(void)
220 static i_integer
*counter
= NULL
;
221 static char *buffer
= NULL
;
222 static unsigned long buffer_size
= 0;
226 buffer_size
= (strlen(COMBO_NAME_PREFIX
) + 20);
227 buffer
= new char[buffer_size
];
228 strcpy(buffer
, COMBO_NAME_PREFIX
);
231 counter
= new i_integer(0);
232 if (counter
->written_length() + (unsigned int)(strlen(COMBO_NAME_PREFIX
) + 1) >
237 buffer
= new char[buffer_size
];
238 strcpy(buffer
, COMBO_NAME_PREFIX
);
240 counter
->write(&(buffer
[strlen(COMBO_NAME_PREFIX
)]));