+
+/*
+ _____ _____ _ _ _ _ _ _
+ |_ _| __ \| \ | | | | | | | | |
+ | | | |__) | \| | | |__| | __ _ _ __ __| | | ___ _ __
+ | | | _ /| . ` | | __ |/ _` | '_ \ / _` | |/ _ \ '__|
+ _| |_| | \ \| |\ | | | | | (_| | | | | (_| | | __/ |
+ |_____|_| \_\_| \_| |_| |_|\__,_|_| |_|\__,_|_|\___|_|
+
+ for Phi nodes which are created due to stack modifying nodes
+ such as IncSP, AddSP and SetSP.
+
+ These Phis are always to be ignored by the reg alloc and are
+ fixed on the SP register of the ISA.
+*/
+
+static const void *abi_get_irn_ops(const arch_irn_handler_t *handler, const ir_node *irn)
+{
+ const be_abi_irg_t *abi = get_abi_from_handler(handler);
+ const void *res = NULL;
+
+ if(is_Phi(irn) && pset_find_ptr(abi->stack_phis, (void *) irn))
+ res = &abi->irn_ops;
+
+ return res;
+}
+
+static void be_abi_limited(void *data, bitset_t *bs)
+{
+ be_abi_irg_t *abi = data;
+ bitset_clear_all(bs);
+ bitset_set(bs, abi->isa->sp->index);
+}
+
+static const arch_register_req_t *abi_get_irn_reg_req(const void *self, arch_register_req_t *req, const ir_node *irn, int pos)
+{
+ be_abi_irg_t *abi = get_abi_from_ops(self);
+ const arch_register_t *reg = abi->isa->sp;
+
+ memset(req, 0, sizeof(req[0]));
+
+ if(pos == BE_OUT_POS(0)) {
+ req->cls = reg->reg_class;
+ req->type = arch_register_req_type_limited;
+ req->limited = be_abi_limited;
+ req->limited_env = abi;
+ }
+
+ else if(pos >= 0 && pos < get_irn_arity(irn)) {
+ req->cls = reg->reg_class;
+ req->type = arch_register_req_type_normal;
+ }
+
+ return req;
+}
+
+static void abi_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg)
+{
+}
+
+static const arch_register_t *abi_get_irn_reg(const void *self, const ir_node *irn)
+{
+ const be_abi_irg_t *abi = get_abi_from_ops(self);
+ return abi->isa->sp;
+}
+
+static arch_irn_class_t abi_classify(const void *_self, const ir_node *irn)
+{
+ return arch_irn_class_normal;
+}
+
+static arch_irn_flags_t abi_get_flags(const void *_self, const ir_node *irn)
+{
+ return arch_irn_flags_ignore;
+}
+
+static entity *abi_get_frame_entity(const void *_self, const ir_node *irn)
+{
+ return NULL;
+}
+
+static void abi_set_stack_bias(const void *_self, ir_node *irn, int bias)
+{
+}
+
+static const arch_irn_ops_if_t abi_irn_ops = {
+ abi_get_irn_reg_req,
+ abi_set_irn_reg,
+ abi_get_irn_reg,
+ abi_classify,
+ abi_get_flags,
+ abi_get_frame_entity,
+ abi_set_stack_bias
+};
+
+static const arch_irn_handler_t abi_irn_handler = {
+ abi_get_irn_ops
+};