2 #include "beasm_asm_gnu.h"
4 static struct obstack *get_obstack_for_segment ( gnuasm_privdata_t *privdata, asm_segment_t segment ) {
7 case ASM_SEGMENT_CONST:
8 return &privdata->rdata_obst;
10 case ASM_SEGMENT_DATA_INIT:
11 return &privdata->data_obst;
13 case ASM_SEGMENT_CODE:
14 return &privdata->code_obst;
16 case ASM_SEGMENT_DATA_UNINIT:
17 return &privdata->common_obst;
20 assert(0 && "unknown segment type");
27 * the dumper callbacks
30 void gnuasm_dump_align( gnuasm_privdata_t *privdata, asm_segment_t segment, int align ) {
31 struct obstack* obst = get_obstack_for_segment ( privdata, segment );
32 obstack_printf(obst, "\t.align %d\n", align);
35 void gnuasm_dump_arith_tarval ( gnuasm_privdata_t *privdata, asm_segment_t segment,
36 tarval *tv, int bytes ) {
38 struct obstack* obst = get_obstack_for_segment ( privdata, segment );
43 obstack_printf(obst, "0x%02x", get_tarval_sub_bits(tv, 0));
46 obstack_printf(obst, "0x%02x%02x", get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
50 obstack_printf(obst, "0x%02x%02x%02x%02x",
51 get_tarval_sub_bits(tv, 3), get_tarval_sub_bits(tv, 2), get_tarval_sub_bits(tv, 1), get_tarval_sub_bits(tv, 0));
55 obstack_printf(obst, "0x%02x%02x%02x%02x%02x%02x%02x%02x",
56 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));
60 fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes);
66 void gnuasm_dump_atomic_decl ( gnuasm_privdata_t *privdata, asm_segment_t segment, int bytes ) {
68 struct obstack* obst = get_obstack_for_segment ( privdata, segment );
73 obstack_printf(obst, "\t.byte\t");
77 obstack_printf(obst, "\t.value\t");
81 obstack_printf(obst, "\t.long\t");
85 obstack_printf(obst, "\t.quad\t");
89 fprintf(stderr, "Try to dump an tarval with %d bytes\n", bytes);
93 // obstack_printf(obst, "\n");
96 void gnuasm_dump_string ( gnuasm_privdata_t *privdata, asm_segment_t segment, entity* ent ) {
100 struct obstack* obst = get_obstack_for_segment ( privdata, segment );
102 obstack_printf(obst, "\t.string \"");
103 n = get_compound_ent_n_values(ent);
105 for (i = 0; i < n-1; ++i) {
109 irn = get_compound_ent_value(ent, i);
110 c = (int) get_tarval_long(get_Const_tarval(irn));
113 case '"' : obstack_printf(obst, "\\\""); break;
114 case '\n': obstack_printf(obst, "\\n"); break;
115 case '\r': obstack_printf(obst, "\\r"); break;
116 case '\t': obstack_printf(obst, "\\t"); break;
119 obstack_printf(obst, "%c", c);
121 obstack_printf(obst, "%O", c);
125 obstack_printf(obst, "\"\n");
130 void gnuasm_dump_declare_initialized_symbol(gnuasm_privdata_t* priv_data, asm_segment_t segment, const char* ld_name, int bytes, int align, ent_visibility visibility) {
132 // get the obstack for the given segment (const, data)
133 struct obstack* obst = get_obstack_for_segment ( priv_data, segment );
135 // if the symbol is externally visibile, declare it so.
136 if (visibility == visibility_external_visible)
137 obstack_printf(obst, ".globl\t%s\n", ld_name);
139 obstack_printf(obst, "\t.type\t%s,@object\n", ld_name);
140 obstack_printf(obst, "\t.size\t%s,%d\n", ld_name, bytes);
141 obstack_printf(obst, "\t.align\t%d\n", align);
142 obstack_printf(obst, "\t%s:\n", ld_name);
145 void gnuasm_dump_declare_uninitialized_symbol(gnuasm_privdata_t* priv_data, asm_segment_t segment, const char* ld_name, int bytes, int align, ent_visibility visibility) {
147 // external symbols are not required to be declared in gnuasm.
148 if(visibility == visibility_external_allocated) return;
150 // declare local, uninitialized symbol to the uninit-obst
151 obstack_printf(&priv_data->common_obst, "\t.comm\t%s,%d,%d\n", ld_name, bytes, align);
155 void gnuasm_dump_zero_padding ( gnuasm_privdata_t *privdata, asm_segment_t segment, int size ) {
157 struct obstack* obst = get_obstack_for_segment ( privdata, segment );
158 obstack_printf(obst, "\t.zero\t%d\n", size);
161 ////////////////////////////////////////////////////////////////////////////
163 void gnuasm_dump_arith_op ( gnuasm_privdata_t *privdata, asm_segment_t segment, asm_arith_operation_t op ) {
164 struct obstack* obst = get_obstack_for_segment ( privdata, segment );
166 case ASM_ARITH_OPERATION_ADD:
167 obstack_printf(obst, "+");
169 case ASM_ARITH_OPERATION_SUB:
170 obstack_printf(obst, "-");
172 case ASM_ARITH_OPERATION_MUL:
173 obstack_printf(obst, "*");
176 //obstack_printf(obst, "+");
179 void gnuasm_dump_symconst ( gnuasm_privdata_t *privdata, asm_segment_t segment, ir_node *init ) {
181 struct obstack* obst = get_obstack_for_segment ( privdata, segment );
182 switch (get_SymConst_kind(init)) {
183 case symconst_addr_name:
184 obstack_printf(obst, "%s", get_id_str(get_SymConst_name(init)));
187 case symconst_addr_ent:
188 obstack_printf(obst, "%s", get_entity_ld_name(get_SymConst_entity(init)));
192 obstack_printf(obst, "%d", get_type_size_bytes(get_SymConst_type(init)));
196 assert(0 && "dump_atomic_init(): don't know how to init from this SymConst");
200 void gnuasm_dump_newline ( gnuasm_privdata_t *privdata, asm_segment_t segment ) {
201 struct obstack* obst = get_obstack_for_segment ( privdata, segment );
202 obstack_printf(obst, "\n");
205 //////////////////////////////////////////////////////////////////////////////
207 void gnuasm_dump_header ( gnuasm_privdata_t *privdata ) {
211 void gnuasm_dump_footer ( gnuasm_privdata_t *privdata ) {
215 void gnuasm_dump_segment_header ( gnuasm_privdata_t *privdata ) {
219 //////////////////////////////////////////////////////////////////////////////
221 assembler_t *gnuasm_create_assembler ( void ) {
223 gnuasm_privdata_t *priv_data = malloc ( sizeof(gnuasm_privdata_t ));
224 assembler_t *assembler = malloc ( sizeof( assembler_t ));
225 memset(assembler, 0, sizeof( assembler_t ));
226 assembler->private_data = priv_data;
228 obstack_init (&priv_data->common_obst);
229 obstack_init (&priv_data->data_obst);
230 obstack_init (&priv_data->rdata_obst);
231 obstack_init (&priv_data->code_obst);
234 assembler->dump_declare_uninitialized_symbol = (dump_declare_uninitialized_symbol_proc) &gnuasm_dump_declare_uninitialized_symbol;
235 assembler->dump_declare_initialized_symbol = (dump_declare_initialized_symbol_proc) &gnuasm_dump_declare_initialized_symbol;
237 // assembler->dump_align = (dump_align_proc) &gnuasm_dump_align;
238 assembler->dump_arith_tarval = (dump_arith_tarval_proc) &gnuasm_dump_arith_tarval;
239 assembler->dump_atomic_decl = (dump_atomic_decl_proc) gnuasm_dump_atomic_decl;
240 assembler->dump_string = (dump_string_proc) &gnuasm_dump_string;
241 assembler->dump_zero_padding = (dump_zero_padding_proc) &gnuasm_dump_zero_padding;
242 assembler->dump_arith_op = (dump_arith_op_proc) &gnuasm_dump_arith_op;
243 assembler->dump_symconst = (dump_symconst_proc) &gnuasm_dump_symconst;
244 assembler->dump_newline = (dump_newline_proc) &gnuasm_dump_newline;
246 assembler->dump_header = (dump_header_proc) &gnuasm_dump_header;
247 assembler->dump_footer = (dump_footer_proc) &gnuasm_dump_footer;
248 assembler->dump_segment_header = (dump_segment_header_proc) &gnuasm_dump_segment_header;
255 static void gnuasm_dump_obst ( struct obstack* obst, FILE* out ) {
257 obstack_grow0 (obst, NULL, 0);
258 void *data = obstack_finish (obst);
259 fprintf(out, "%s", data);
262 void gnuasm_dump ( assembler_t *assembler, FILE* out ) {
264 gnuasm_privdata_t *privdata = assembler->private_data;
266 // fprintf(out, "<COMMON>\n");
267 gnuasm_dump_obst ( &privdata->common_obst, out);
268 fprintf(out, ".data\n");
269 gnuasm_dump_obst ( &privdata->data_obst, out);
270 fprintf(out, ".section .rodata\n");
271 gnuasm_dump_obst ( &privdata->rdata_obst, out);
272 fprintf(out, ".text\n");
273 gnuasm_dump_obst ( &privdata->code_obst, out);
278 void gnuasm_delete_assembler ( assembler_t *assembler ) {
280 free ( assembler->private_data );