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)
const ir_node *next_block;
ir_node *op1 = get_irn_n(irn, 0);
const char *suffix;
- pn_Cmp pnc = get_arm_CondJmp_pnc(irn);
+ 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;
}
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 */
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);
}
/**
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);