assert(reg && "no in register found");
/* in case of a joker register: just return a valid register */
- if (arch_register_type_is(reg, joker)) {
+ if (reg->type & arch_register_type_joker) {
const arch_register_req_t *req = arch_get_register_req(irn, pos);
if (arch_register_req_is(req, limited)) {
return reg;
}
+static void arm_emit_register(const arch_register_t *reg)
+{
+ be_emit_string(arch_register_get_name(reg));
+}
+
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));
+ arm_emit_register(reg);
}
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));
+ arm_emit_register(reg);
}
void arm_emit_offset(const ir_node *node)
void arm_emit_shifter_operand(const ir_node *node)
{
- const arm_shifter_operand_t *attr = get_irn_generic_attr_const(node);
+ const arm_shifter_operand_t *attr = get_arm_shifter_operand_attr_const(node);
switch (attr->shift_modifier) {
case ARM_SHF_REG:
typedef struct sym_or_tv_t {
union {
ir_entity *entity; /**< An entity. */
- tarval *tv; /**< A tarval. */
+ ir_tarval *tv; /**< A tarval. */
const void *generic; /**< For generic compare. */
} u;
unsigned label; /**< the associated label. */
static void emit_arm_FrameAddr(const ir_node *irn)
{
- const arm_SymConst_attr_t *attr = get_irn_generic_attr_const(irn);
+ const arm_SymConst_attr_t *attr = get_arm_SymConst_attr_const(irn);
be_emit_cstring("\tadd ");
arm_emit_dest_register(irn, 0);
*/
static ir_node *sched_next_block(const ir_node *block)
{
- return get_irn_link(block);
+ return (ir_node*)get_irn_link(block);
}
/**
*/
static ir_node *get_cfop_target_block(const ir_node *irn)
{
- return get_irn_link(irn);
+ return (ir_node*)get_irn_link(irn);
}
/**
const ir_node *next_block;
ir_node *op1 = get_irn_n(irn, 0);
const char *suffix;
- pn_Cmp pnc = get_arm_CondJmp_pnc(irn);
- const arm_cmp_attr_t *cmp_attr = get_irn_generic_attr_const(op1);
+ ir_relation relation = get_arm_CondJmp_relation(irn);
+ const arm_cmp_attr_t *cmp_attr = get_arm_cmp_attr_const(op1);
bool is_signed = !cmp_attr->is_unsigned;
assert(is_arm_Cmp(op1) || is_arm_Tst(op1));
}
if (cmp_attr->ins_permuted) {
- pnc = get_mirrored_pnc(pnc);
+ relation = get_inversed_relation(relation);
}
/* for now, the code works for scheduled and non-schedules blocks */
/* we have a block schedule */
next_block = sched_next_block(block);
- assert(pnc != pn_Cmp_False);
- assert(pnc != pn_Cmp_True);
+ assert(relation != ir_relation_false);
+ assert(relation != ir_relation_true);
if (get_cfop_target_block(proj_true) == next_block) {
/* exchange both proj's so the second one can be omitted */
proj_true = proj_false;
proj_false = t;
- pnc = get_negated_pnc(pnc, mode_Iu);
+ relation = get_negated_relation(relation);
}
- switch (pnc) {
- case pn_Cmp_Eq: suffix = "eq"; break;
- case pn_Cmp_Lt: suffix = is_signed ? "lt" : "lo"; break;
- case pn_Cmp_Le: suffix = is_signed ? "le" : "ls"; break;
- case pn_Cmp_Gt: suffix = is_signed ? "gt" : "hi"; break;
- case pn_Cmp_Ge: suffix = is_signed ? "ge" : "hs"; break;
- case pn_Cmp_Lg: suffix = "ne"; break;
- case pn_Cmp_Leg: suffix = "al"; break;
- default: panic("Cmp has unsupported pnc");
+ switch (relation & (ir_relation_less_equal_greater)) {
+ case ir_relation_equal: suffix = "eq"; break;
+ case ir_relation_less: suffix = is_signed ? "lt" : "lo"; break;
+ case ir_relation_less_equal: suffix = is_signed ? "le" : "ls"; break;
+ case ir_relation_greater: suffix = is_signed ? "gt" : "hi"; break;
+ case ir_relation_greater_equal: suffix = is_signed ? "ge" : "hs"; break;
+ case ir_relation_less_greater: suffix = "ne"; break;
+ case ir_relation_less_equal_greater: suffix = "al"; break;
+ default: panic("Cmp has unsupported relation");
}
/* emit the true proj */
/** Sort register in ascending order. */
static int reg_cmp(const void *a, const void *b)
{
- const arch_register_t * const *ra = a;
- const arch_register_t * const *rb = b;
+ const arch_register_t * const *ra = (const arch_register_t**)a;
+ const arch_register_t * const *rb = (const arch_register_t**)b;
return *ra < *rb ? -1 : (*ra != *rb);
}
*/
static void emit_arm_CopyB(const ir_node *irn)
{
- const arm_CopyB_attr_t *attr = get_irn_generic_attr_const(irn);
+ const arm_CopyB_attr_t *attr = get_arm_CopyB_attr_const(irn);
unsigned size = attr->size;
const char *tgt = arch_register_get_name(get_in_reg(irn, 0));
be_emit_cstring(", ");
arm_emit_source_register(irn, 0);
be_emit_irprintf(", #0x%X", offs);
+ be_emit_finish_line_gas(irn);
} else {
/* omitted IncSP(0) */
return;
}
- be_emit_finish_line_gas(irn);
}
static void emit_be_Copy(const ir_node *irn)
assert(sp_change == 0);
}
+static void emit_be_Start(const ir_node *node)
+{
+ ir_graph *irg = get_irn_irg(node);
+ ir_type *frame_type = get_irg_frame_type(irg);
+ unsigned size = get_type_size_bytes(frame_type);
+
+ /* allocate stackframe */
+ if (size > 0) {
+ be_emit_cstring("\tsub ");
+ arm_emit_register(&arm_registers[REG_SP]);
+ be_emit_cstring(", ");
+ arm_emit_register(&arm_registers[REG_SP]);
+ be_emit_irprintf(", #0x%X", size);
+ be_emit_finish_line_gas(node);
+ }
+}
+
static void emit_be_Return(const ir_node *node)
{
+ ir_graph *irg = get_irn_irg(node);
+ ir_type *frame_type = get_irg_frame_type(irg);
+ unsigned size = get_type_size_bytes(frame_type);
+
+ /* deallocate stackframe */
+ if (size > 0) {
+ be_emit_cstring("\tadd ");
+ arm_emit_register(&arm_registers[REG_SP]);
+ be_emit_cstring(", ");
+ arm_emit_register(&arm_registers[REG_SP]);
+ be_emit_irprintf(", #0x%X", size);
+ be_emit_finish_line_gas(node);
+ }
+
be_emit_cstring("\tmov pc, lr");
be_emit_finish_line_gas(node);
}
set_emitter(op_be_MemPerm, emit_be_MemPerm);
set_emitter(op_be_Perm, emit_be_Perm);
set_emitter(op_be_Return, emit_be_Return);
+ set_emitter(op_be_Start, emit_be_Start);
/* no need to emit anything for the following nodes */
set_emitter(op_Phi, emit_nothing);
set_emitter(op_be_Keep, emit_nothing);
- set_emitter(op_be_Start, emit_nothing);
- set_emitter(op_be_Barrier, emit_nothing);
}
/**
*/
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;
+ const sym_or_tv_t *p1 = (const sym_or_tv_t*)elt;
+ const sym_or_tv_t *p2 = (const sym_or_tv_t*)key;
(void) size;
/* as an identifier NEVER can point to a tarval, it's enough
ir_entity *entity = get_irg_entity(irg);
const arch_env_t *arch_env = be_get_irg_arch_env(irg);
ir_node **blk_sched;
- int i, n;
+ size_t i, n;
isa = (arm_isa_t*) arch_env;
sym_or_tv = new_set(cmp_sym_or_tv, 8);
be_emit_cstring("\t.align 2\n");
- foreach_set(sym_or_tv, entry) {
+ foreach_set(sym_or_tv, sym_or_tv_t*, entry) {
emit_constant_name(entry);
be_emit_cstring(":\n");
be_emit_write_line();
be_emit_char('\n');
be_emit_write_line();
} else {
- tarval *tv = entry->u.tv;
+ ir_tarval *tv = entry->u.tv;
int i, size = get_mode_size_bytes(get_tarval_mode(tv));
unsigned v;