#include "../benode.h"
-#define BLOCK_PREFIX ".L"
#define SNPRINTF_BUF_LEN 128
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
/**
* Emit the name of the source register at given input position.
*/
-void arm_emit_source_register(const ir_node *node, int pos) {
+void arm_emit_source_register(const ir_node *node, int pos)
+{
const arch_register_t *reg = get_in_reg(node, pos);
be_emit_string(arch_register_get_name(reg));
}
/**
* Emit the name of the destination register at given output position.
*/
-void arm_emit_dest_register(const ir_node *node, int pos) {
+void arm_emit_dest_register(const ir_node *node, int pos)
+{
const arch_register_t *reg = get_out_reg(node, pos);
be_emit_string(arch_register_get_name(reg));
}
/**
* Emit the arm fpa instruction suffix depending on the mode.
*/
-static void arm_emit_fpa_postfix(const ir_mode *mode) {
+static void arm_emit_fpa_postfix(const ir_mode *mode)
+{
int bits = get_mode_size_bits(mode);
char c = 'e';
/**
* Emit the instruction suffix depending on the mode.
*/
-void arm_emit_mode(const ir_node *node) {
+void arm_emit_mode(const ir_node *node)
+{
ir_mode *mode;
if (is_arm_irn(node)) {
/**
* Returns a unique label. This number will not be used a second time.
*/
-static unsigned get_unique_label(void) {
+static unsigned get_unique_label(void)
+{
static unsigned id = 0;
return ++id;
}
sym_or_tv_t key, *entry;
unsigned label;
- set_entity_backend_marked(attr->entity, 1);
-
key.u.id = get_entity_ld_ident(attr->entity);
key.is_ident = 1;
key.label = 0;
/**
* Emit a floating point fpa constant.
*/
-static void emit_arm_fpaConst(const ir_node *irn) {
+static void emit_arm_fpaConst(const ir_node *irn)
+{
sym_or_tv_t key, *entry;
unsigned label;
ir_mode *mode;
/**
* Returns the next block in a block schedule.
*/
-static ir_node *sched_next_block(const ir_node *block) {
+static ir_node *sched_next_block(const ir_node *block)
+{
return get_irn_link(block);
}
/**
* Returns the target block for a control flow node.
*/
-static ir_node *get_cfop_target_block(const ir_node *irn) {
+static ir_node *get_cfop_target_block(const ir_node *irn)
+{
return get_irn_link(irn);
}
-/**
- * Emits a block label for the given block.
- */
-static void arm_emit_block_name(const ir_node *block) {
- if (has_Block_entity(block)) {
- ir_entity *entity = get_Block_entity(block);
- be_gas_emit_entity(entity);
- } else {
- be_emit_cstring(BLOCK_PREFIX);
- be_emit_irprintf("%d", get_irn_node_nr(block));
- }
-}
-
/**
* Emit the target label for a control flow node.
*/
-static void arm_emit_cfop_target(const ir_node *irn) {
+static void arm_emit_cfop_target(const ir_node *irn)
+{
ir_node *block = get_cfop_target_block(irn);
- arm_emit_block_name(block);
+ be_gas_emit_block_name(block);
}
/**
}
/** Sort register in ascending order. */
-static int reg_cmp(const void *a, const void *b) {
+static int reg_cmp(const void *a, const void *b)
+{
const arch_register_t * const *ra = a;
const arch_register_t * const *rb = b;
}
}
-static void emit_arm_SwitchJmp(const ir_node *irn) {
+static void emit_arm_SwitchJmp(const ir_node *irn)
+{
const ir_edge_t *edge;
ir_node *proj;
int i;
static void arm_emit_entity(ir_entity *entity)
{
- set_entity_backend_marked(entity, 1);
be_emit_ident(get_entity_ld_ident(entity));
}
}
/** Emit an IncSP node */
-static void emit_be_IncSP(const ir_node *irn) {
+static void emit_be_IncSP(const ir_node *irn)
+{
int offs = -be_get_IncSP_offset(irn);
if (offs != 0) {
be_emit_finish_line_gas(irn);
}
-static void emit_be_Copy(const ir_node *irn) {
+static void emit_be_Copy(const ir_node *irn)
+{
ir_mode *mode = get_irn_mode(irn);
if (get_in_reg(irn, 0) == get_out_reg(irn, 0)) {
be_emit_finish_line_gas(node);
}
-static void emit_arm_fpaDbl2GP(const ir_node *irn) {
+static void emit_arm_fpaDbl2GP(const ir_node *irn)
+{
be_emit_cstring("\tstfd ");
arm_emit_source_register(irn, 0);
be_emit_cstring(", [sp, #-8]!");
be_emit_finish_line_gas(irn);
}
-static void emit_arm_LdTls(const ir_node *irn) {
+static void emit_arm_LdTls(const ir_node *irn)
+{
(void) irn;
panic("TLS not supported for this target");
/* Er... our gcc does not support it... Install a newer toolchain. */
/**
* Emits code for a node.
*/
-static void arm_emit_node(const ir_node *irn) {
+static void arm_emit_node(const ir_node *irn)
+{
ir_op *op = get_irn_op(irn);
if (op->ops.generic) {
}
if (need_label) {
- arm_emit_block_name(block);
+ be_gas_emit_block_name(block);
be_emit_char(':');
be_emit_pad_comment();
}
} else {
be_emit_cstring("\t/* ");
- arm_emit_block_name(block);
+ be_gas_emit_block_name(block);
be_emit_cstring(": ");
}
if (exec_freq != NULL) {
* Walks over the nodes in a block connected by scheduling edges
* and emits code for each node.
*/
-static void arm_gen_block(ir_node *block, ir_node *prev_block) {
+static void arm_gen_block(ir_node *block, ir_node *prev_block)
+{
ir_node *irn;
arm_emit_block_header(block, prev_block);
}
}
-/**
- * Emits code for function start.
- */
-void arm_func_prolog(ir_graph *irg) {
- ir_entity *ent = get_irg_entity(irg);
- const char *irg_name = get_entity_ld_name(ent);
-
- be_emit_write_line();
- be_gas_emit_switch_section(GAS_SECTION_TEXT);
- be_emit_cstring("\t.align 2\n");
-
- if (get_entity_visibility(ent) == visibility_external_visible)
- be_emit_irprintf("\t.global %s\n", irg_name);
- be_emit_irprintf("%s:\n", irg_name);
-}
-
-/**
- * Emits code for function end
- */
-void arm_emit_end(FILE *F, ir_graph *irg) {
- (void) irg;
- fprintf(F, "\t.ident \"firmcc\"\n");
-}
-
/**
* Block-walker:
* Sets labels for control flow nodes (jump target)
*/
-static void arm_gen_labels(ir_node *block, void *env) {
+static void arm_gen_labels(ir_node *block, void *env)
+{
ir_node *pred;
int n = get_Block_n_cfgpreds(block);
(void)env;
/**
* Compare two entries of the symbol or tarval set.
*/
-static int cmp_sym_or_tv(const void *elt, const void *key, size_t size) {
+static int cmp_sym_or_tv(const void *elt, const void *key, size_t size)
+{
const sym_or_tv_t *p1 = elt;
const sym_or_tv_t *p2 = key;
(void) size;
/**
* Main driver. Emits the code for one routine.
*/
-void arm_gen_routine(const arm_code_gen_t *arm_cg, ir_graph *irg) {
+void arm_gen_routine(const arm_code_gen_t *arm_cg, ir_graph *irg)
+{
ir_node **blk_sched;
int i, n;
ir_node *last_block = NULL;
cg = arm_cg;
sym_or_tv = new_set(cmp_sym_or_tv, 8);
+ be_gas_elf_type_char = '%';
+
arm_register_emitters();
be_dbg_method_begin(entity, be_abi_get_stack_layout(cg->birg->abi));
/* create the block schedule. For now, we don't need it earlier. */
blk_sched = be_create_block_schedule(cg->irg, cg->birg->exec_freq);
- arm_func_prolog(irg);
+ be_gas_emit_function_prolog(entity, 4);
+
irg_block_walk_graph(irg, arm_gen_labels, NULL, NULL);
n = ARR_LEN(blk_sched);
last_block = block;
}
+ be_gas_emit_function_epilog(entity);
be_dbg_method_end();
/* emit SymConst values */