4 * Basic helper routine descriptions for 'sparse'.
6 * Copyright (C) 2003 Transmeta Corp.
9 * Licensed under the Open Software License version 1.1
12 extern unsigned int hexval(unsigned int c
);
28 struct statement_list
;
30 struct expression_list
;
32 struct basic_block_list
;
35 struct instruction_list
;
38 struct token
*skip_to(struct token
*, int);
39 struct token
*expect(struct token
*, int, const char *);
40 extern void warn(struct position
, const char *, ...);
41 extern void error(struct position
, const char *, ...);
43 #define __DECLARE_ALLOCATOR(type, x) \
44 extern type *__alloc_##x(int); \
45 extern void show_##x##_alloc(void); \
46 extern void clear_##x##_alloc(void);
47 #define DECLARE_ALLOCATOR(x) __DECLARE_ALLOCATOR(struct x, x)
49 DECLARE_ALLOCATOR(ident
);
50 DECLARE_ALLOCATOR(token
);
51 DECLARE_ALLOCATOR(symbol
);
52 DECLARE_ALLOCATOR(expression
);
53 DECLARE_ALLOCATOR(statement
);
54 DECLARE_ALLOCATOR(string
);
55 DECLARE_ALLOCATOR(scope
);
56 __DECLARE_ALLOCATOR(void, bytes
);
57 DECLARE_ALLOCATOR(basic_block
);
58 DECLARE_ALLOCATOR(entrypoint
);
59 DECLARE_ALLOCATOR(instruction
);
60 DECLARE_ALLOCATOR(multijmp
);
61 DECLARE_ALLOCATOR(phi
);
64 #define LIST_NODE_NR (29)
68 struct ptr_list
*prev
;
69 struct ptr_list
*next
;
70 void *list
[LIST_NODE_NR
];
73 struct list_iterator
{
74 struct ptr_list
**head
;
75 struct ptr_list
*active
;
80 enum iterator_br_state
{
87 struct terminator_iterator
{
88 struct instruction
*terminator
;
90 struct list_iterator multijmp
;
95 #define ITERATOR_BACKWARDS 1
96 #define ITERATOR_CURRENT 2
98 #define ITERATE_FIRST 1
99 #define ITERATE_LAST 2
101 #define ptr_list_empty(x) ((x) == NULL)
103 void iterate(struct ptr_list
*,void (*callback
)(void *, void *, int), void*);
104 void init_iterator(struct ptr_list
**head
, struct list_iterator
*iterator
, int flags
);
105 void * next_iterator(struct list_iterator
*iterator
);
106 void delete_iterator(struct list_iterator
*iterator
);
107 void init_terminator_iterator(struct instruction
* terminator
, struct terminator_iterator
*iterator
);
108 struct basic_block
* next_terminator_bb(struct terminator_iterator
*iterator
);
109 void replace_terminator_bb(struct terminator_iterator
*iterator
, struct basic_block
* bb
);
110 void * delete_ptr_list_last(struct ptr_list
**head
);
111 int replace_ptr_list(struct ptr_list
**head
, void *old_ptr
, void *new_ptr
);
113 extern void add_ptr_list(struct ptr_list
**, void *);
114 extern void concat_ptr_list(struct ptr_list
*a
, struct ptr_list
**b
);
115 extern void free_ptr_list(struct ptr_list
**);
116 extern int ptr_list_size(struct ptr_list
*);
117 extern char **handle_switch(char *arg
, char **next
);
118 extern void add_pre_buffer(const char *fmt
, ...);
120 extern unsigned int pre_buffer_size
;
121 extern unsigned char pre_buffer
[8192];
122 extern int include_fd
;
123 extern char *include
;
124 extern int preprocess_only
;
126 extern void create_builtin_stream(void);
128 #define symbol_list_size(list) ptr_list_size((struct ptr_list *)(list))
129 #define statement_list_size(list) ptr_list_size((struct ptr_list *)(list))
130 #define expression_list_size(list) ptr_list_size((struct ptr_list *)(list))
131 #define instruction_list_size(list) ptr_list_size((struct ptr_list *)(list))
132 #define bb_list_size(list) ptr_list_size((struct ptr_list *)(list))
135 #define init_multijmp_iterator(list, iterator, flags) init_iterator((struct ptr_list **)(list), (iterator), (flags))
137 #define next_basic_block(iterator) (struct basic_block*) next_iterator(iterator)
138 #define next_multijmp(iterator) (struct multijmp*) next_iterator(iterator)
140 void * next_iterator(struct list_iterator
*iterator
);
142 static inline void init_bb_iterator(struct basic_block_list
**head
, struct list_iterator
*iterator
, int flags
)
144 init_iterator((struct ptr_list
**)head
, iterator
, flags
);
147 static inline struct instruction
* delete_last_instruction(struct instruction_list
**head
)
149 return delete_ptr_list_last((struct ptr_list
**)head
);
152 static inline struct basic_block
* delete_last_basic_block(struct basic_block_list
**head
)
154 return delete_ptr_list_last((struct ptr_list
**)head
);
158 static inline void *first_ptr_list(struct ptr_list
*list
)
162 return list
->list
[0];
165 static inline void *last_ptr_list(struct ptr_list
*list
)
171 return list
->list
[list
->nr
-1];
174 static inline void * current_iterator(struct list_iterator
*iterator
)
176 struct ptr_list
*list
= iterator
->active
;
177 return list
? list
->list
[iterator
->index
] : NULL
;
180 static inline struct basic_block
*first_basic_block(struct basic_block_list
*head
)
182 return last_ptr_list((struct ptr_list
*)head
);
184 static inline struct instruction
*last_instruction(struct instruction_list
*head
)
186 return last_ptr_list((struct ptr_list
*)head
);
189 static inline struct instruction
*first_instruction(struct instruction_list
*head
)
191 return first_ptr_list((struct ptr_list
*)head
);
194 static inline int replace_basic_block_list(struct basic_block_list
**head
, struct basic_block
*from
, struct basic_block
*to
)
196 return replace_ptr_list((struct ptr_list
**)head
, (void*)from
, (void*)to
);
199 static inline void concat_symbol_list(struct symbol_list
*from
, struct symbol_list
**to
)
201 concat_ptr_list((struct ptr_list
*)from
, (struct ptr_list
**)to
);
204 static inline void concat_basic_block_list(struct basic_block_list
*from
, struct basic_block_list
**to
)
206 concat_ptr_list((struct ptr_list
*)from
, (struct ptr_list
**)to
);
209 static inline void concat_instruction_list(struct instruction_list
*from
, struct instruction_list
**to
)
211 concat_ptr_list((struct ptr_list
*)from
, (struct ptr_list
**)to
);
214 static inline void add_symbol(struct symbol_list
**list
, struct symbol
*sym
)
216 add_ptr_list((struct ptr_list
**)list
, sym
);
219 static inline void add_statement(struct statement_list
**list
, struct statement
*stmt
)
221 add_ptr_list((struct ptr_list
**)list
, stmt
);
224 static inline void add_expression(struct expression_list
**list
, struct expression
*expr
)
226 add_ptr_list((struct ptr_list
**)list
, expr
);
229 static inline void symbol_iterate(struct symbol_list
*list
, void (*callback
)(struct symbol
*, void *, int), void *data
)
231 iterate((struct ptr_list
*)list
, (void (*)(void *, void *, int))callback
, data
);
234 static inline void statement_iterate(struct statement_list
*list
, void (*callback
)(struct statement
*, void *, int), void *data
)
236 iterate((struct ptr_list
*)list
, (void (*)(void *, void *, int))callback
, data
);
239 static inline void expression_iterate(struct expression_list
*list
, void (*callback
)(struct expression
*, void *, int), void *data
)
241 iterate((struct ptr_list
*)list
, (void (*)(void *, void *, int))callback
, data
);
244 #define PREPARE_PTR_LIST(head, ptr) \
246 struct ptr_list *__head##ptr = (struct ptr_list *) (head); \
247 struct ptr_list *__list##ptr = __head##ptr; \
249 if (__head##ptr) ptr = (__typeof__(ptr)) __head##ptr->list[0]; \
252 #define NEXT_PTR_LIST(ptr) \
254 if (++__nr##ptr < __list##ptr->nr) { \
255 ptr = (__typeof__(ptr)) __list##ptr->list[__nr##ptr]; \
257 __list##ptr = __list##ptr->next; \
259 if (__list##ptr != __head##ptr) { \
261 ptr = (__typeof__(ptr)) __list##ptr->list[0]; \
266 #define RESET_PTR_LIST(ptr) do { \
268 __list##ptr = __head##ptr; \
269 if (__head##ptr) ptr = (__typeof__(ptr)) __head##ptr->list[0]; \
273 #define FINISH_PTR_LIST(ptr) \
274 (void)(__nr##ptr); /* Sanity-check nesting */ \
277 #define FOR_EACH_PTR(head, ptr) do { \
278 struct ptr_list *__head = (struct ptr_list *) (head); \
279 struct ptr_list *__list = __head; \
280 int __flag = ITERATE_FIRST; \
283 for (__i = 0; __i < __list->nr; __i++) { \
284 if (__i == __list->nr-1 && __list->next == __head) \
285 __flag |= ITERATE_LAST; \
287 ptr = (__typeof__(ptr)) (__list->list[__i]); \
290 #define END_FOR_EACH_PTR } while (0); \
294 } while ((__list = __list->next) != __head); \
298 #define FOR_EACH_PTR_REVERSE(head, ptr) do { \
299 struct ptr_list *__head = (struct ptr_list *) (head); \
300 struct ptr_list *__list = __head; \
301 int __flag = ITERATE_FIRST; \
304 __list = __list->prev; \
306 while (--__i >= 0) { \
307 if (__i == 0 && __list == __head) \
308 __flag |= ITERATE_LAST; \
310 ptr = (__typeof__(ptr)) (__list->list[__i]); \
313 #define END_FOR_EACH_PTR_REVERSE } while (0); \
317 } while (__list != __head); \
321 #define THIS_ADDRESS(x) \
322 ((__typeof__(&(x))) (__list->list + __i))