Commit 3f0b6e82 authored by Matthias Braun's avatar Matthias Braun
Browse files

- 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]
parent a94528a2
......@@ -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)
......
......@@ -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)
......
......@@ -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 */
......@@ -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.
......
......@@ -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);
......
......@@ -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);
......
......@@ -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,
......
......@@ -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 */
......@@ -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)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment