if (is_ia32_irn(irn)) {
irn_req = (pos >= 0) ? get_ia32_in_req(irn, pos) : get_ia32_out_req(irn, node_pos);
+ if (irn_req == NULL) {
+ /* no requirements */
+ return NULL;
+ }
DB((mod, LEVEL_1, "returning reqs for %+F at pos %d\n", irn, pos));
}
if (is_ia32_irn(irn)) {
- /* retrieve "real" x87 register */
- if (ia32_has_x87_register(irn))
- reg = get_ia32_attr(irn)->x87[pos + 2];
- else {
- const arch_register_t **slots;
- slots = get_ia32_slots(irn);
- reg = slots[pos];
- }
+ const arch_register_t **slots;
+ slots = get_ia32_slots(irn);
+ reg = slots[pos];
}
else {
reg = ia32_get_firm_reg(irn, cur_reg_set);
}
static arch_irn_flags_t ia32_get_flags(const void *self, const ir_node *irn) {
+ arch_irn_flags_t flags;
+ ir_node *pred = is_Proj(irn) && mode_is_datab(get_irn_mode(irn)) ? get_Proj_pred(irn) : NULL;
- if(is_Proj(irn)) {
- ir_node *pred = get_Proj_pred(irn);
- int ia32_op = get_ia32_irn_opcode(pred);
- long proj = get_Proj_proj(irn);
- if (iro_ia32_Push == ia32_op && proj == pn_ia32_Push_stack) {
- /* Push modifies always ESP, this cannot be changed */
- return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
- }
- if (iro_ia32_Pop == ia32_op && proj == pn_ia32_Pop_stack) {
- /* Pop modifies always ESP, this cannot be changed */
- return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
- }
- if (iro_ia32_AddSP == ia32_op && proj == pn_ia32_AddSP_stack) {
- /* AddSP modifies always ESP, this cannot be changed */
- return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
- }
- if (iro_ia32_SubSP == ia32_op && proj == pn_ia32_SubSP_stack) {
- /* SubSP modifies always ESP, this cannot be changed */
- return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
- }
- }
-
- irn = skip_Proj(irn);
- if (is_ia32_irn(irn))
- return get_ia32_flags(irn);
+ if (is_Unknown(irn))
+ flags = arch_irn_flags_ignore;
else {
- if (is_Unknown(irn))
- return arch_irn_flags_ignore;
- return 0;
+ /* pred is only set, if we have a Proj */
+ flags = pred && is_ia32_irn(pred) ? get_ia32_out_flags(pred, get_Proj_proj(irn)) : arch_irn_flags_none;
+
+ irn = skip_Proj(irn);
+ if (is_ia32_irn(irn))
+ flags |= get_ia32_flags(irn);
}
+
+ return flags;
}
/**