10 #include "beasm_asm_gnu.h"
12 static struct obstack *get_obstack_for_segment ( gnuasm_privdata_t *privdata, asm_segment_t segment ) {
15 case ASM_SEGMENT_CONST:
16 return &privdata->rdata_obst;
18 case ASM_SEGMENT_DATA_INIT:
19 return &privdata->data_obst;
21 case ASM_SEGMENT_CODE:
22 return &privdata->code_obst;
24 case ASM_SEGMENT_DATA_UNINIT:
25 return &privdata->common_obst;
28 assert(0 && "unknown segment type");
36 * the dumper callbacks
39 static void gnuasm_dump_align(void *data, asm_segment_t segment, int align) {
40 gnuasm_privdata_t *privdata = data;
41 struct obstack* obst = get_obstack_for_segment( privdata, segment );
42 obstack_printf(obst, "\t.align %d\n", align);
46 static void gnuasm_dump_arith_tarval(void *data, asm_segment_t segment, tarval *tv, int bytes)
48 gnuasm_privdata_t *privdata = data;
49 struct obstack* obst = get_obstack_for_segment ( privdata, segment );
54 obstack_printf(obst, "0x%02x", get_tarval_sub_bits(tv, 0));
57 obstack_printf(obst, "0x%02x%02x", get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
61 obstack_printf(obst, "0x%02x%02x%02x%02x",
62 get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
66 obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x",
67 get_tarval_sub_bits(tv, 7), get_tarval_sub_bits(tv, 6), get_tarval_sub_bits(tv, 5), get_tarval_sub_bits(tv, 4), get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
71 fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes);
77 static void gnuasm_dump_atomic_decl(void *data, asm_segment_t segment, int bytes)
79 gnuasm_privdata_t *privdata = data;
80 struct obstack* obst = get_obstack_for_segment( privdata, segment );
85 obstack_printf(obst, "\t.byte\t");
89 obstack_printf(obst, "\t.value\t");
93 obstack_printf(obst, "\t.long\t");
97 obstack_printf(obst, "\t.quad\t");
101 fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes);
105 // obstack_printf(obst, "\n");
108 static void gnuasm_dump_string(void *data, asm_segment_t segment, entity *ent)
110 gnuasm_privdata_t *privdata = data;
113 struct obstack* obst = get_obstack_for_segment ( privdata, segment );
115 obstack_printf(obst, "\t.string \"");
116 n = get_compound_ent_n_values(ent);
118 for (i = 0; i < n-1; ++i) {
122 irn = get_compound_ent_value(ent, i);
123 c = (int) get_tarval_long(get_Const_tarval(irn));
126 case '"' : obstack_printf(obst, "\\\""); break;
127 case '\n': obstack_printf(obst, "\\n"); break;
128 case '\r': obstack_printf(obst, "\\r"); break;
129 case '\t': obstack_printf(obst, "\\t"); break;
132 obstack_printf(obst, "%c", c);
134 obstack_printf(obst, "%O", c);
138 obstack_printf(obst, "\"\n");
142 static void gnuasm_dump_declare_initialized_symbol(void *data, asm_segment_t segment, const char* ld_name, int bytes, int align, ent_visibility visibility)
144 gnuasm_privdata_t* priv_data = data;
146 /* get the obstack for the given segment (const, data) */
147 struct obstack* obst = get_obstack_for_segment ( priv_data, segment );
149 /* if the symbol is externally visible, declare it so. */
150 if (visibility == visibility_external_visible)
151 obstack_printf(obst, ".globl\t%s\n", ld_name);
153 obstack_printf(obst, "\t.type\t%s,@object\n", ld_name);
154 obstack_printf(obst, "\t.size\t%s,%d\n", ld_name, bytes);
155 obstack_printf(obst, "\t.align\t%d\n", align);
156 obstack_printf(obst, "\t%s:\n", ld_name);
159 static void gnuasm_dump_declare_uninitialized_symbol(void *data, asm_segment_t segment, const char* ld_name, int bytes, int align, ent_visibility visibility)
161 gnuasm_privdata_t *priv_data = data;
163 /* external symbols are not required to be declared in gnuasm. */
164 if(visibility == visibility_external_allocated) return;
166 /* declare local, uninitialized symbol to the uninit-obst */
167 obstack_printf(&priv_data->common_obst, "\t.comm\t%s,%d,%d\n", ld_name, bytes, align);
170 static void gnuasm_dump_zero_padding(void *data, asm_segment_t segment, int size)
172 gnuasm_privdata_t *privdata = data;
173 struct obstack* obst = get_obstack_for_segment ( privdata, segment );
174 obstack_printf(obst, "\t.zero\t%d\n", size);
177 ////////////////////////////////////////////////////////////////////////////
179 static void gnuasm_dump_arith_op(void *data, asm_segment_t segment, asm_arith_operation_t op)
181 gnuasm_privdata_t *privdata = data;
182 struct obstack* obst = get_obstack_for_segment ( privdata, segment );
184 case ASM_ARITH_OPERATION_ADD:
185 obstack_printf(obst, "+");
187 case ASM_ARITH_OPERATION_SUB:
188 obstack_printf(obst, "-");
190 case ASM_ARITH_OPERATION_MUL:
191 obstack_printf(obst, "*");
194 //obstack_printf(obst, "+");
197 static void gnuasm_dump_symconst(void *data, asm_segment_t segment, ir_node *init)
199 gnuasm_privdata_t *privdata = data;
200 struct obstack* obst = get_obstack_for_segment ( privdata, segment );
201 switch (get_SymConst_kind(init)) {
202 case symconst_addr_name:
203 obstack_printf(obst, "%s", get_id_str(get_SymConst_name(init)));
206 case symconst_addr_ent:
207 obstack_printf(obst, "%s", get_entity_ld_name(get_SymConst_entity(init)));
211 obstack_printf(obst, "%d", get_type_size_bytes(get_SymConst_type(init)));
215 assert(0 && "dump_atomic_init(): don't know how to init from this SymConst");
219 static void gnuasm_dump_newline(void *data, asm_segment_t segment)
221 gnuasm_privdata_t *privdata = data;
222 struct obstack* obst = get_obstack_for_segment ( privdata, segment );
223 obstack_printf(obst, "\n");
226 //////////////////////////////////////////////////////////////////////////////
228 static void gnuasm_dump_header(void *data) {
229 /*gnuasm_privdata_t *privdata = data;*/
232 static void gnuasm_dump_footer(void *data) {
233 /*gnuasm_privdata_t *privdata = data;*/
236 static void gnuasm_dump_segment_header(void *data) {
237 /*gnuasm_privdata_t *privdata = data;*/
240 //////////////////////////////////////////////////////////////////////////////
242 assembler_t *gnuasm_create_assembler ( void ) {
244 gnuasm_privdata_t *priv_data = malloc ( sizeof(gnuasm_privdata_t ));
245 assembler_t *assembler = malloc ( sizeof( assembler_t ));
246 memset(assembler, 0, sizeof( assembler_t ));
247 assembler->private_data = priv_data;
249 obstack_init (&priv_data->common_obst);
250 obstack_init (&priv_data->data_obst);
251 obstack_init (&priv_data->rdata_obst);
252 obstack_init (&priv_data->code_obst);
255 assembler->dump_declare_uninitialized_symbol = gnuasm_dump_declare_uninitialized_symbol;
256 assembler->dump_declare_initialized_symbol = gnuasm_dump_declare_initialized_symbol;
258 // assembler->dump_align = (dump_align_proc) &gnuasm_dump_align;
259 assembler->dump_arith_tarval = gnuasm_dump_arith_tarval;
260 assembler->dump_atomic_decl = gnuasm_dump_atomic_decl;
261 assembler->dump_string = gnuasm_dump_string;
262 assembler->dump_zero_padding = gnuasm_dump_zero_padding;
263 assembler->dump_arith_op = gnuasm_dump_arith_op;
264 assembler->dump_symconst = gnuasm_dump_symconst;
265 assembler->dump_newline = gnuasm_dump_newline;
267 assembler->dump_header = gnuasm_dump_header;
268 assembler->dump_footer = gnuasm_dump_footer;
269 assembler->dump_segment_header = gnuasm_dump_segment_header;
276 static void gnuasm_dump_obst(struct obstack *obst, FILE *out) {
277 obstack_grow0 (obst, NULL, 0);
278 fprintf(out, "%s", (char *)obstack_finish(obst));
281 void gnuasm_dump( assembler_t *assembler, FILE *out ) {
283 gnuasm_privdata_t *privdata = assembler->private_data;
285 // fprintf(out, "<COMMON>\n");
286 gnuasm_dump_obst ( &privdata->common_obst, out);
287 fprintf(out, ".data\n");
288 gnuasm_dump_obst ( &privdata->data_obst, out);
289 fprintf(out, ".section .rodata\n");
290 gnuasm_dump_obst ( &privdata->rdata_obst, out);
291 fprintf(out, ".text\n");
292 gnuasm_dump_obst ( &privdata->code_obst, out);
296 void gnuasm_delete_assembler( assembler_t *assembler ) {
297 free( assembler->private_data );