From 5297678b46a3f2610756dc4c4ff62bc989334dc0 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Mon, 28 Jan 2008 14:00:12 +0000 Subject: [PATCH] implement/fix assembler clobbers [r17554] --- ir/be/ia32/ia32_transform.c | 67 ++++++++++++++++++++++++++++++++----- ir/ir/ircons.c | 1 + 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index f1ca54c62..27f6ff5d0 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -3241,7 +3241,7 @@ static void parse_asm_constraint(int pos, constraint_t *constraint, const char * /* a memory constraint: no need to do anything in backend about it * (the dependencies are already respected by the memory edge of * the node) */ - constraint->req = &no_register_req; + constraint->req = &no_register_req; return; } @@ -3470,13 +3470,54 @@ static void parse_asm_constraint(int pos, constraint_t *constraint, const char * } static void parse_clobber(ir_node *node, int pos, constraint_t *constraint, - const char *c) + const char *clobber) { - (void) node; + ir_graph *irg = get_irn_irg(node); + struct obstack *obst = get_irg_obstack(irg); + const arch_register_t *reg = NULL; + int c; + size_t r; + arch_register_req_t *req; + const arch_register_class_t *cls; + (void) pos; - (void) constraint; - (void) c; - panic("Clobbers not supported yet"); + + fprintf(stderr, "Clobber: %s\n", clobber); + + /* TODO: construct a hashmap instead of doing linear search for clobber + * register */ + for(c = 0; c < N_CLASSES; ++c) { + cls = & ia32_reg_classes[c]; + for(r = 0; r < cls->n_regs; ++r) { + const arch_register_t *temp_reg = arch_register_for_index(cls, r); + if(strcmp(temp_reg->name, clobber) == 0 + || (c == CLASS_ia32_gp && strcmp(temp_reg->name+1, clobber) == 0)) { + reg = temp_reg; + break; + } + } + if(reg != NULL) + break; + } + if(reg == NULL) { + panic("Register '%s' mentioned in asm clobber is unknown\n", clobber); + return; + } + + assert(reg->index < 32); + + unsigned *limited = obstack_alloc(obst, sizeof(limited[0])); + *limited = 1 << reg->index; + + req = obstack_alloc(obst, sizeof(req[0])); + memset(req, 0, sizeof(req[0])); + req->type = arch_register_req_type_limited; + req->cls = cls; + req->limited = limited; + + constraint->req = req; + constraint->immediate_possible = 0; + constraint->immediate_type = 0; } static int is_memory_op(const ir_asm_constraint *constraint) @@ -3525,6 +3566,9 @@ static ir_node *gen_ASM(ir_node *node) n_out_constraints = get_ASM_n_output_constraints(node); n_clobbers = get_ASM_n_clobbers(node); out_arity = n_out_constraints + n_clobbers; + /* hack to keep space for mem proj */ + if(n_clobbers > 0) + out_arity += 1; in_constraints = get_ASM_input_constraints(node); out_constraints = get_ASM_output_constraints(node); @@ -3547,14 +3591,19 @@ static ir_node *gen_ASM(ir_node *node) if(constraint->pos > reg_map_size) reg_map_size = constraint->pos; - } else { + + out_reg_reqs[i] = parsed_constraint.req; + } else if(i < out_arity - 1) { ident *glob_id = clobbers [i - n_out_constraints]; + assert(glob_id != NULL); c = get_id_str(glob_id); parse_clobber(node, i, &parsed_constraint, c); - } - out_reg_reqs[i] = parsed_constraint.req; + out_reg_reqs[i+1] = parsed_constraint.req; + } } + if(n_clobbers > 1) + out_reg_reqs[n_out_constraints] = &no_register_req; /* construct input constraints */ in_reg_reqs = obstack_alloc(obst, arity * sizeof(in_reg_reqs[0])); diff --git a/ir/ir/ircons.c b/ir/ir/ircons.c index 0e9fb62ec..31155a42c 100644 --- a/ir/ir/ircons.c +++ b/ir/ir/ircons.c @@ -847,6 +847,7 @@ new_bd_ASM(dbg_info *db, ir_node *block, int arity, ir_node *in[], ir_asm_constr memcpy(res->attr.assem.inputs, inputs, sizeof(inputs[0]) * arity); memcpy(res->attr.assem.outputs, outputs, sizeof(outputs[0]) * n_outs); + memcpy(res->attr.assem.clobber, clobber, sizeof(clobber[0]) * n_clobber); res = optimize_node(res); IRN_VRFY_IRG(res, irg); -- 2.20.1