From 3f0b6e8217576d23654d406170c543a791edac56 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Mon, 28 Jul 2008 09:13:28 +0000 Subject: [PATCH] - handle parsing of assembler constraints in backends. Provide functions for frontend to determine what is input/output/memory operand - prefix some globally visible ia32 functions with ia32_ [r20725] --- ir/be/TEMPLATE/bearch_TEMPLATE.c | 18 ++++- ir/be/arm/bearch_arm.c | 17 +++++ ir/be/be_t.h | 5 ++ ir/be/bearch_t.h | 15 ++++ ir/be/bemain.c | 118 +++++++++++++++++++++++++++++++ ir/be/ia32/bearch_ia32.c | 67 ++++++++++++++++++ ir/be/ia32/ia32_transform.c | 62 +++++++++------- ir/be/ia32/ia32_transform.h | 10 ++- ir/be/ppc32/bearch_ppc32.c | 18 +++++ 9 files changed, 300 insertions(+), 30 deletions(-) diff --git a/ir/be/TEMPLATE/bearch_TEMPLATE.c b/ir/be/TEMPLATE/bearch_TEMPLATE.c index ee1b14f82..08f28e50a 100644 --- a/ir/be/TEMPLATE/bearch_TEMPLATE.c +++ b/ir/be/TEMPLATE/bearch_TEMPLATE.c @@ -670,6 +670,20 @@ static ir_graph **TEMPLATE_get_backend_irg_list(const void *self, return NULL; } +static asm_constraint_flags_t TEMPLATE_parse_asm_constraint(const void *self, + const char **c) +{ + (void) self; + (void) c; + return ASM_CONSTRAINT_FLAG_INVALID; +} + +static bool TEMPLATE_is_valid_clobber(const void *self, const char *clobber) +{ + (void) self; + (void) clobber; + return false; +} const arch_isa_if_t TEMPLATE_isa_if = { TEMPLATE_init, @@ -685,7 +699,9 @@ const arch_isa_if_t TEMPLATE_isa_if = { TEMPLATE_get_backend_params, TEMPLATE_get_allowed_execution_units, TEMPLATE_get_machine, - TEMPLATE_get_backend_irg_list + TEMPLATE_get_backend_irg_list, + TEMPLATE_parse_asm_constraint, + TEMPLATE_is_valid_clobber }; void be_init_arch_TEMPLATE(void) diff --git a/ir/be/arm/bearch_arm.c b/ir/be/arm/bearch_arm.c index 0047ab1e2..6338f67cd 100644 --- a/ir/be/arm/bearch_arm.c +++ b/ir/be/arm/bearch_arm.c @@ -1204,6 +1204,21 @@ static int arm_is_psi_allowed(ir_node *sel, ir_node *phi_list, int i, int j) { return 1; } +static asm_constraint_flags_t arm_parse_asm_constraint(const void *self, const char **c) +{ + /* asm not supported */ + (void) self; + (void) c; + return ASM_CONSTRAINT_FLAG_INVALID; +} + +static bool arm_is_valid_clobber(const void *self, const char *clobber) +{ + (void) self; + (void) clobber; + return false; +} + /** * Returns the libFirm configuration parameter for this backend. */ @@ -1274,6 +1289,8 @@ const arch_isa_if_t arm_isa_if = { arm_get_allowed_execution_units, arm_get_machine, arm_get_irg_list, + arm_parse_asm_constraint, + arm_is_valid_clobber }; void be_init_arch_arm(void) diff --git a/ir/be/be_t.h b/ir/be/be_t.h index 7e77a11db..a9ab833b2 100644 --- a/ir/be/be_t.h +++ b/ir/be/be_t.h @@ -91,6 +91,10 @@ struct be_main_env_t { ir_type *pic_symbols_type; }; +extern unsigned short asm_constraint_flags[256]; + +void be_init_default_asm_constraint_flags(void); + /** * Put the registers to be ignored in this IRG into a bitset. * @param birg The backend IRG data structure. @@ -146,4 +150,5 @@ extern ir_timer_t *t_ra_copymin; /**< timer for copy minimization */ extern ir_timer_t *t_ra_ssa; /**< timer for ssa destruction */ extern ir_timer_t *t_ra_other; /**< timer for remaining stuff */ + #endif /* FIRM_BE_BE_T_H */ diff --git a/ir/be/bearch_t.h b/ir/be/bearch_t.h index 3709b7ea6..6a1909642 100644 --- a/ir/be/bearch_t.h +++ b/ir/be/bearch_t.h @@ -522,6 +522,19 @@ struct arch_isa_if_t { * @return A flexible array ARR_F containing all desired irgs in the desired order. */ ir_graph **(*get_backend_irg_list)(const void *self, ir_graph ***irgs); + + /** + * parse an assembler constraint part and set flags according to its nature + * advances the *c pointer to point to the last parsed character (so if you + * parse a single character don't advance c) + */ + asm_constraint_flags_t (*parse_asm_constraint)(const void *self, const char **c); + + /** + * returns true if the string is a valid clobbered (register) in this + * backend + */ + bool (*is_valid_clobber)(const void *self, const char *clobber); }; #define arch_env_done(env) ((env)->impl->done(env)) @@ -537,6 +550,8 @@ struct arch_isa_if_t { #define arch_env_get_allowed_execution_units(env,irn) ((env)->impl->get_allowed_execution_units((env), (irn))) #define arch_env_get_machine(env) ((env)->impl->get_machine(env)) #define arch_env_get_backend_irg_list(env,irgs) ((env)->impl->get_backend_irg_list((env), (irgs))) +#define arch_env_parse_asm_constraint(env,c) ((env)->impl->parse_asm_constraint((env), (c)) +#define arch_env_is_valid_clobber(env,clobber) ((env)->impl->is_valid_clobber((env), (clobber)) /** * ISA base class. diff --git a/ir/be/bemain.c b/ir/be/bemain.c index b4ccce504..cb3bbb714 100644 --- a/ir/be/bemain.c +++ b/ir/be/bemain.c @@ -176,6 +176,123 @@ static const lc_opt_table_entry_t be_main_options[] = { static be_module_list_entry_t *isa_ifs = NULL; + +unsigned short asm_constraint_flags[256]; + +void be_init_default_asm_constraint_flags(void) +{ + asm_constraint_flags['?'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + asm_constraint_flags['!'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + asm_constraint_flags['&'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT + | ASM_CONSTRAINT_FLAG_MODIFIER_EARLYCLOBBER; + asm_constraint_flags['%'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT + | ASM_CONSTRAINT_FLAG_MODIFIER_COMMUTATIVE; + asm_constraint_flags['!'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + + asm_constraint_flags['='] = ASM_CONSTRAINT_FLAG_MODIFIER_WRITE + | ASM_CONSTRAINT_FLAG_MODIFIER_NO_READ; + asm_constraint_flags['+'] = ASM_CONSTRAINT_FLAG_MODIFIER_READ + | ASM_CONSTRAINT_FLAG_MODIFIER_WRITE; + + asm_constraint_flags['i'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + asm_constraint_flags['s'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + asm_constraint_flags['E'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + asm_constraint_flags['F'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + asm_constraint_flags['G'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + asm_constraint_flags['H'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + asm_constraint_flags['I'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + asm_constraint_flags['J'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + asm_constraint_flags['K'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + asm_constraint_flags['L'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + asm_constraint_flags['M'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + asm_constraint_flags['N'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + asm_constraint_flags['O'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + asm_constraint_flags['P'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + + asm_constraint_flags['m'] = ASM_CONSTRAINT_FLAG_SUPPORTS_MEMOP; + asm_constraint_flags['o'] = ASM_CONSTRAINT_FLAG_SUPPORTS_MEMOP; + asm_constraint_flags['V'] = ASM_CONSTRAINT_FLAG_SUPPORTS_MEMOP; + asm_constraint_flags['<'] = ASM_CONSTRAINT_FLAG_SUPPORTS_MEMOP; + asm_constraint_flags['>'] = ASM_CONSTRAINT_FLAG_SUPPORTS_MEMOP; + + asm_constraint_flags['p'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['0'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['1'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['2'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['3'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['4'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['5'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['6'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['7'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['8'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['9'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + + asm_constraint_flags['X'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER + | ASM_CONSTRAINT_FLAG_SUPPORTS_MEMOP + | ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + + /* these should have been catched by the parsing code already */ + asm_constraint_flags['#'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + asm_constraint_flags['*'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + asm_constraint_flags[' '] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + asm_constraint_flags['\t'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + asm_constraint_flags['\n'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + asm_constraint_flags['\r'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; +} + +asm_constraint_flags_t parse_asm_constraints(const char *constraint) +{ + const char *c; + asm_constraint_flags_t flags; + asm_constraint_flags_t tflags; + + for (c = constraint; *c != '\0'; ++c) { + switch (*c) { + case '#': + /* 'comment' stuff */ + while(*c != 0 && *c != ',') + ++c; + break; + case '*': + /* 'comment' character */ + ++c; + break; + case ' ': + case '\t': + case '\n': + case '\r': + break; + default: + tflags = asm_constraint_flags[(int) *c]; + if (tflags != 0) { + flags |= tflags; + } else { + flags |= isa_if->parse_asm_constraint(isa_if, &c); + } + break; + } + } + + if ( ((flags & ASM_CONSTRAINT_FLAG_MODIFIER_WRITE) + && (flags & ASM_CONSTRAINT_FLAG_MODIFIER_NO_WRITE)) + || ((flags & ASM_CONSTRAINT_FLAG_MODIFIER_READ + && (flags & ASM_CONSTRAINT_FLAG_MODIFIER_NO_READ)))) { + flags |= ASM_CONSTRAINT_FLAG_INVALID; + } + + return flags; +} + +bool is_valid_clobber(const char *clobber) +{ + /* memory is a valid clobber. (the frontend has to detect this case too, + * because it has to add memory edges to the asm) */ + if (strcmp(clobber, "memory") == 0) + return true; + + return isa_if->is_valid_clobber(isa_if, clobber); +} + void be_register_isa_if(const char *name, const arch_isa_if_t *isa) { if (isa_if == NULL) @@ -269,6 +386,7 @@ static be_main_env_t *be_init_env(be_main_env_t *env, FILE *file_handle) remove_irp_type(env->pic_symbols_type); set_class_final(env->pic_trampolines_type, 1); + memset(asm_constraint_flags, 0, sizeof(asm_constraint_flags)); env->arch_env = arch_env_init(isa_if, file_handle, env); be_phi_handler_new(env); diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 3b9c06f61..5ddc2704e 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -1651,6 +1651,53 @@ static ia32_isa_t ia32_isa_template = { #endif }; +static void init_asm_constraints(void) +{ + be_init_default_asm_constraint_flags(); + + asm_constraint_flags['a'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['b'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['c'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['d'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['D'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['S'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['Q'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['q'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['A'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['l'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['R'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['r'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['p'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['f'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['t'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['u'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['Y'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['X'] = ASM_CONSTRAINT_FLAG_SUPPORTS_REGISTER; + asm_constraint_flags['n'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + asm_constraint_flags['g'] = ASM_CONSTRAINT_FLAG_SUPPORTS_IMMEDIATE; + + /* no support for autodecrement/autoincrement */ + asm_constraint_flags['<'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + asm_constraint_flags['>'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + /* no float consts */ + asm_constraint_flags['E'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + asm_constraint_flags['F'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + /* makes no sense on x86 */ + asm_constraint_flags['s'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + /* no support for sse consts yet */ + asm_constraint_flags['C'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + /* no support for x87 consts yet */ + asm_constraint_flags['G'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + /* no support for mmx registers yet */ + asm_constraint_flags['y'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + /* not available in 32bit mode */ + asm_constraint_flags['Z'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + asm_constraint_flags['e'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; + + /* no code yet to determine register class needed... */ + asm_constraint_flags['X'] = ASM_CONSTRAINT_FLAG_NO_SUPPORT; +} + /** * Initializes the backend ISA. */ @@ -1662,6 +1709,7 @@ static arch_env_t *ia32_init(FILE *file_handle) { return NULL; inited = 1; + init_asm_constraints(); set_tarval_output_modes(); isa = xmalloc(sizeof(*isa)); @@ -2157,6 +2205,23 @@ static int ia32_is_psi_allowed(ir_node *sel, ir_node *phi_list, int i, int j) return 0; } +static asm_constraint_flags_t ia32_parse_asm_constraint(const void *self, const char **c) +{ + (void) self; + (void) c; + + /* we already added all our simple flags to the flags modifier list in + * init, so this flag we don't know. */ + return ASM_CONSTRAINT_FLAG_INVALID; +} + +static bool ia32_is_valid_clobber(const void *self, const char *clobber) +{ + (void) self; + + return ia32_get_clobber_register(clobber) != NULL; +} + /** * Returns the libFirm configuration parameter for this backend. */ @@ -2228,6 +2293,8 @@ const arch_isa_if_t ia32_isa_if = { ia32_get_allowed_execution_units, ia32_get_machine, ia32_get_irg_list, + ia32_parse_asm_constraint, + ia32_is_valid_clobber }; void ia32_init_emitter(void); diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index 301763e57..ddb761aa6 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -138,7 +138,7 @@ static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode, /** * Return true if a mode can be stored in the GP register set */ -INLINE int mode_needs_gp_reg(ir_mode *mode) { +int ia32_mode_needs_gp_reg(ir_mode *mode) { if(mode == mode_fpcw) return 0; if(get_mode_size_bits(mode) > 32) @@ -164,7 +164,7 @@ static ident *unique_id(const char *tag) /** * Get a primitive type for a mode. */ -ir_type *get_prim_type(pmap *types, ir_mode *mode) +ir_type *ia32_get_prim_type(pmap *types, ir_mode *mode) { pmap_entry *e = pmap_find(types, mode); ir_type *res; @@ -237,9 +237,9 @@ static ir_entity *create_float_const_entity(ir_node *cnst) /* mode was not changed */ tp = get_Const_type(cnst); if (tp == firm_unknown_type) - tp = get_prim_type(isa->types, mode); + tp = ia32_get_prim_type(isa->types, mode); } else - tp = get_prim_type(isa->types, mode); + tp = ia32_get_prim_type(isa->types, mode); res = new_entity(get_glob_type(), unique_id(".LC%u"), tp); @@ -752,8 +752,8 @@ static int is_downconv(const ir_node *node) src_mode = get_irn_mode(get_Conv_op(node)); dest_mode = get_irn_mode(node); - return mode_needs_gp_reg(src_mode) - && mode_needs_gp_reg(dest_mode) + return ia32_mode_needs_gp_reg(src_mode) + && ia32_mode_needs_gp_reg(dest_mode) && get_mode_size_bits(dest_mode) < get_mode_size_bits(src_mode); } @@ -2233,7 +2233,7 @@ static ir_node *try_create_dest_am(ir_node *node) { ir_node *new_node; /* handle only GP modes for now... */ - if(!mode_needs_gp_reg(mode)) + if(!ia32_mode_needs_gp_reg(mode)) return NULL; while(1) { @@ -2372,7 +2372,7 @@ static int is_float_to_int32_conv(const ir_node *node) ir_node *conv_op; ir_mode *conv_mode; - if(get_mode_size_bits(mode) != 32 || !mode_needs_gp_reg(mode)) + if(get_mode_size_bits(mode) != 32 || !ia32_mode_needs_gp_reg(mode)) return 0; if(!is_Conv(node)) @@ -2737,7 +2737,7 @@ static ir_node *gen_be_Copy(ir_node *node) ir_node *new_node = be_duplicate_node(node); ir_mode *mode = get_irn_mode(new_node); - if (mode_needs_gp_reg(mode)) { + if (ia32_mode_needs_gp_reg(mode)) { set_irn_mode(new_node, mode_Iu); } @@ -2854,7 +2854,7 @@ static ir_node *gen_Cmp(ir_node *node) } } - assert(mode_needs_gp_reg(cmp_mode)); + assert(ia32_mode_needs_gp_reg(cmp_mode)); /* we prefer the Test instruction where possible except cases where * we can use SourceAM */ @@ -2958,7 +2958,7 @@ static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags, ia32_address_t *addr; assert(ia32_cg_config.use_cmov); - assert(mode_needs_gp_reg(get_irn_mode(val_true))); + assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true))); addr = &am.addr; @@ -3095,7 +3095,7 @@ static ir_node *gen_Psi(ir_node *node) ir_node *flags; ir_node *new_node; - assert(mode_needs_gp_reg(mode)); + assert(ia32_mode_needs_gp_reg(mode)); if (is_Proj(cond)) { ir_node *cmp = get_Proj_pred(cond); @@ -3814,6 +3814,8 @@ static void parse_asm_constraint(int pos, constraint_t *constraint, const char * break; case 'm': + case 'o': + case 'V': /* memory constraint no need to do anything in backend about it * (the dependencies are already respected by the memory edge of * the node) */ @@ -3824,8 +3826,6 @@ static void parse_asm_constraint(int pos, constraint_t *constraint, const char * case 'F': /* no float consts yet */ case 's': /* makes no sense on x86 */ case 'X': /* we can't support that in firm */ - case 'o': - case 'V': case '<': /* no autodecrement on x86 */ case '>': /* no autoincrement on x86 */ case 'C': /* sse constant not supported yet */ @@ -3905,19 +3905,12 @@ static void parse_asm_constraint(int pos, constraint_t *constraint, const char * constraint->immediate_type = immediate_type; } -static void parse_clobber(ir_node *node, int pos, constraint_t *constraint, - const char *clobber) +const arch_register_t *ia32_get_clobber_register(const char *clobber) { - ir_graph *irg = get_irn_irg(node); - struct obstack *obst = get_irg_obstack(irg); - const arch_register_t *reg = NULL; + const arch_register_t *reg = NULL; int c; size_t r; - arch_register_req_t *req; const arch_register_class_t *cls; - unsigned *limited; - - (void) pos; /* TODO: construct a hashmap instead of doing linear search for clobber * register */ @@ -3934,6 +3927,21 @@ static void parse_clobber(ir_node *node, int pos, constraint_t *constraint, if(reg != NULL) break; } + + return reg; +} + +static void parse_clobber(ir_node *node, int pos, constraint_t *constraint, + const char *clobber) +{ + ir_graph *irg = get_irn_irg(node); + struct obstack *obst = get_irg_obstack(irg); + const arch_register_t *reg = ia32_get_clobber_register(clobber); + arch_register_req_t *req; + unsigned *limited; + + (void) pos; + if(reg == NULL) { panic("Register '%s' mentioned in asm clobber is unknown\n", clobber); return; @@ -3947,7 +3955,7 @@ static void parse_clobber(ir_node *node, int pos, constraint_t *constraint, req = obstack_alloc(obst, sizeof(req[0])); memset(req, 0, sizeof(req[0])); req->type = arch_register_req_type_limited; - req->cls = cls; + req->cls = arch_register_get_class(reg); req->limited = limited; constraint->req = req; @@ -4284,7 +4292,7 @@ static ir_node *gen_Unknown(ir_node *node) { add_irn_dep(ret, get_irg_frame(irg)); return ret; } - } else if (mode_needs_gp_reg(mode)) { + } else if (ia32_mode_needs_gp_reg(mode)) { return ia32_new_Unknown_gp(env_cg); } else { panic("unsupported Unknown-Mode"); @@ -4302,7 +4310,7 @@ static ir_node *gen_Phi(ir_node *node) { ir_mode *mode = get_irn_mode(node); ir_node *phi; - if(mode_needs_gp_reg(mode)) { + if(ia32_mode_needs_gp_reg(mode)) { /* we shouldn't have any 64bit stuff around anymore */ assert(get_mode_size_bits(mode) <= 32); /* all integer operations are on 32bit registers now */ @@ -5293,7 +5301,7 @@ static ir_node *gen_Proj(ir_node *node) { } else { #endif ir_mode *mode = get_irn_mode(node); - if (mode_needs_gp_reg(mode)) { + if (ia32_mode_needs_gp_reg(mode)) { ir_node *new_pred = be_transform_node(pred); ir_node *block = be_transform_node(get_nodes_block(node)); ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred, diff --git a/ir/be/ia32/ia32_transform.h b/ir/be/ia32/ia32_transform.h index 9ae5659da..88e364b0a 100644 --- a/ir/be/ia32/ia32_transform.h +++ b/ir/be/ia32/ia32_transform.h @@ -69,11 +69,17 @@ ir_node *ia32_skip_downconv(ir_node *node); /** * Get a primitive type for a mode. */ -ir_type *get_prim_type(pmap *types, ir_mode *mode); +ir_type *ia32_get_prim_type(pmap *types, ir_mode *mode); /** * Return true if a mode can be stored in the GP register set */ -INLINE int mode_needs_gp_reg(ir_mode *mode); +int ia32_mode_needs_gp_reg(ir_mode *mode); + +/** + * returns register by name (used for determining clobber specifications in + * asm instructions) + */ +const arch_register_t *ia32_get_clobber_register(const char *clobber); #endif /* FIRM_BE_IA32_IA32_TRANSFORM_H */ diff --git a/ir/be/ppc32/bearch_ppc32.c b/ir/be/ppc32/bearch_ppc32.c index 40644a02c..8fb45a3d8 100644 --- a/ir/be/ppc32/bearch_ppc32.c +++ b/ir/be/ppc32/bearch_ppc32.c @@ -926,6 +926,22 @@ static const backend_params *ppc32_get_libfirm_params(void) { return &p; } +static asm_constraint_flags_t ppc32_parse_asm_constraint(const void *self, const char **c) +{ + /* no asm support yet */ + (void) self; + (void) c; + return ASM_CONSTRAINT_FLAG_INVALID; +} + +static bool ppc32_is_valid_clobber(const void *self, const char *clobber) +{ + /* no asm support yet */ + (void) self; + (void) clobber; + return false; +} + const arch_isa_if_t ppc32_isa_if = { ppc32_init, ppc32_done, @@ -941,6 +957,8 @@ const arch_isa_if_t ppc32_isa_if = { ppc32_get_allowed_execution_units, ppc32_get_machine, ppc32_get_irg_list, + ppc32_parse_asm_constraint, + ppc32_is_valid_clobber }; void be_init_arch_ppc32(void) -- 2.20.1