bool x86_match_immediate(x86_imm32_t *immediate, const ir_node *node, char const constraint) { ir_mode *const mode = get_irn_mode(node); if (get_mode_arithmetic(mode) != irma_twos_complement) return false; ir_tarval *offset; ir_entity *entity; if (!be_match_immediate(node, &offset, &entity)) return false; long val = 0; if (offset) { if (!tarval_is_long(offset)) { be_warningf(node, "tarval is not long"); return false; } val = get_tarval_long(offset); if (!check_immediate_constraint(val, constraint)) return false; } if (entity != NULL) { /* we need full 32bits for entities */ if (constraint != 'i' && constraint != 'g') return false; } /* we are fine */ immediate->entity = entity; immediate->offset = (int32_t)val; return true; }
/** * Try to place a Shl into an address mode. * * @param addr the address mode data so far * @param node the node to place * @return true on success */ static bool eat_shl(x86_address_t *addr, ir_node *node) { /* we can only eat a shl if we don't have a scale or index set yet */ if (addr->scale != 0 || addr->index != NULL) return false; ir_node *shifted_val; long val; if (is_Shl(node)) { /* we can use shl with 0,1,2 or 3 shift */ ir_node *right = get_Shl_right(node); if (!is_Const(right)) return false; ir_tarval *tv = get_Const_tarval(right); if (!tarval_is_long(tv)) return false; val = get_tarval_long(tv); if (val < 0 || val > 3) return false; if (val == 0) be_warningf(node, "found unoptimized Shl x,0"); shifted_val = get_Shl_left(node); } else if (is_Add(node)) { /* might be an add x, x */ ir_node *left = get_Add_left(node); ir_node *right = get_Add_right(node); if (left != right) return false; if (is_Const(left)) return false; val = 1; shifted_val = left; } else { return false; } if (x86_is_non_address_mode_node(node)) return false; addr->scale = val; addr->index = shifted_val; return true; }