#include "heights.h"
#include "betranshlp.h"
-#include "beirg.h"
#include "beabi.h"
#include "ia32_architecture.h"
static int check_immediate_constraint(long val, char immediate_constraint_type)
{
switch (immediate_constraint_type) {
- case 0:
case 'i': return 1;
case 'I': return 0 <= val && val <= 31;
return res;
}
-ir_node *ia32_create_Immediate(ir_entity *symconst, int symconst_sign, long val)
+ir_node *ia32_create_Immediate(ir_graph *const irg, ir_entity *const symconst, int const symconst_sign, long const val)
{
- ir_graph *irg = current_ir_graph;
ir_node *start_block = get_irg_start_block(irg);
ir_node *immediate = new_bd_ia32_Immediate(NULL, start_block, symconst,
symconst_sign, ia32_no_pic_adjust, val);
case 't':
case 'u':
/* TODO: mark values so the x87 simulator knows about t and u */
- if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_vfp])
+ if (cls != NULL && cls != &ia32_reg_classes[CLASS_ia32_fp])
panic("multiple register classes not supported");
- cls = &ia32_reg_classes[CLASS_ia32_vfp];
+ cls = &ia32_reg_classes[CLASS_ia32_fp];
all_registers_allowed = 1;
break;
{
if (in->cls != out->cls)
return false;
- if ( (in->type & arch_register_req_type_limited) == 0
- || (out->type & arch_register_req_type_limited) == 0 )
+ if (!arch_register_req_is(in, limited) ||
+ !arch_register_req_is(out, limited))
return true;
return (*in->limited & *out->limited) != 0;
#endif
}
+static arch_register_req_t const *ia32_make_register_req(ir_graph *irg, constraint_t const *constraint, int n_outs, arch_register_req_t const **out_reqs, int pos);
+
ir_node *ia32_gen_ASM(ir_node *node)
{
ir_node *block = get_nodes_block(node);
const char *c = get_id_str(constraint->constraint);
unsigned pos = constraint->pos;
parse_asm_constraints(&parsed_constraint, c, true);
- const arch_register_req_t *req
- = ia32_make_register_req(&parsed_constraint, n_out_constraints,
- out_reg_reqs, out_idx);
+ arch_register_req_t const *const req = ia32_make_register_req(irg, &parsed_constraint, n_out_constraints, out_reg_reqs, out_idx);
out_reg_reqs[out_idx] = req;
/* multiple constraints for same pos. This can happen for example when
}
}
- const arch_register_req_t *req
- = ia32_make_register_req(&parsed_constraint, n_out_constraints,
- out_reg_reqs, i);
+ arch_register_req_t const *const req = ia32_make_register_req(irg, &parsed_constraint, n_out_constraints, out_reg_reqs, i);
in_reg_reqs[i] = req;
if (parsed_constraint.immediate_type != '\0') {
}
/* add a new (dummy) input which occupies the register */
- assert(outreq->type & arch_register_req_type_limited);
+ assert(arch_register_req_is(outreq, limited));
in_reg_reqs[n_ins] = outreq;
in[n_ins] = new_bd_ia32_ProduceVal(NULL, block);
++n_ins;
}
/* add a new (dummy) output which occupies the register */
- assert(inreq->type & arch_register_req_type_limited);
+ assert(arch_register_req_is(inreq, limited));
out_reg_reqs[out_arity] = inreq;
++out_arity;
}
if (ia32_cg_config.use_sse2) {
res = new_bd_ia32_xUnknown(dbgi, block);
} else {
- res = new_bd_ia32_vfldz(dbgi, block);
+ res = new_bd_ia32_fldz(dbgi, block);
}
} else if (ia32_mode_needs_gp_reg(mode)) {
res = new_bd_ia32_Unknown(dbgi, block);
return res;
}
-const arch_register_req_t *ia32_make_register_req(
- const constraint_t *constraint, int n_outs,
- const arch_register_req_t **out_reqs, int pos)
+static arch_register_req_t const *ia32_make_register_req(ir_graph *const irg, constraint_t const *const c, int const n_outs, arch_register_req_t const **const out_reqs, int const pos)
{
- struct obstack *obst = get_irg_obstack(current_ir_graph);
- int same_as = constraint->same_as;
- arch_register_req_t *req;
-
+ int const same_as = c->same_as;
if (same_as >= 0) {
- const arch_register_req_t *other_constr;
-
if (same_as >= n_outs)
panic("invalid output number in same_as constraint");
- other_constr = out_reqs[same_as];
-
- req = OALLOC(obst, arch_register_req_t);
- *req = *other_constr;
- req->type |= arch_register_req_type_should_be_same;
- req->other_same = 1U << pos;
- req->width = 1;
+ struct obstack *const obst = get_irg_obstack(irg);
+ arch_register_req_t *const req = OALLOC(obst, arch_register_req_t);
+ arch_register_req_t const *const other = out_reqs[same_as];
+ *req = *other;
+ req->type |= arch_register_req_type_should_be_same;
+ req->other_same = 1U << pos;
- /* switch constraints. This is because in firm we have same_as
+ /* Switch constraints. This is because in firm we have same_as
* constraints on the output constraints while in the gcc asm syntax
- * they are specified on the input constraints */
+ * they are specified on the input constraints. */
out_reqs[same_as] = req;
- return other_constr;
+ return other;
}
- /* pure memory ops */
- if (constraint->cls == NULL) {
+ /* Pure memory ops. */
+ if (!c->cls)
return arch_no_register_req;
- }
-
- if (constraint->allowed_registers != 0
- && !constraint->all_registers_allowed) {
- unsigned *limited_ptr;
- req = (arch_register_req_t*)obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
- memset(req, 0, sizeof(req[0]));
- limited_ptr = (unsigned*) (req+1);
+ if (c->allowed_registers == 0 || c->all_registers_allowed)
+ return c->cls->class_req;
- req->type = arch_register_req_type_limited;
- *limited_ptr = constraint->allowed_registers;
- req->limited = limited_ptr;
- } else {
- req = OALLOCZ(obst, arch_register_req_t);
- req->type = arch_register_req_type_normal;
- }
- req->cls = constraint->cls;
- req->width = 1;
+ struct obstack *const obst = get_irg_obstack(irg);
+ arch_register_req_t *const req = (arch_register_req_t*)obstack_alloc(obst, sizeof(req[0]) + sizeof(unsigned));
+ unsigned *const limited = (unsigned*)(req + 1);
+ *limited = c->allowed_registers;
+ memset(req, 0, sizeof(req[0]));
+ req->type = arch_register_req_type_limited;
+ req->cls = c->cls;
+ req->limited = limited;
+ req->width = 1;
return req;
}
if (strcmp(clobber, "memory") == 0 || strcmp(clobber, "cc") == 0)
return NULL;
- struct obstack *obst = get_irg_obstack(current_ir_graph);
- const arch_register_t *reg = ia32_get_clobber_register(clobber);
- arch_register_req_t *req;
- unsigned *limited;
-
- if (reg == NULL) {
+ arch_register_t const *const reg = ia32_get_clobber_register(clobber);
+ if (!reg)
panic("Register '%s' mentioned in asm clobber is unknown", clobber);
- }
-
- assert(reg->index < 32);
- limited = OALLOC(obst, unsigned);
- *limited = 1 << reg->index;
-
- req = OALLOCZ(obst, arch_register_req_t);
- req->type = arch_register_req_type_limited;
- req->cls = reg->reg_class;
- req->limited = limited;
- req->width = 1;
-
- return req;
+ return reg->single_req;
}
ir_node *ia32_try_create_Immediate(ir_node *node, char immediate_constraint_type)
{
- long val = 0;
- ir_entity *symconst_ent = NULL;
- ir_mode *mode;
- ir_node *cnst = NULL;
- ir_node *symconst = NULL;
- ir_node *new_node;
-
- mode = get_irn_mode(node);
- if (!mode_is_int(mode) && !mode_is_reference(mode)) {
+ ir_mode *const mode = get_irn_mode(node);
+ if (!mode_is_int(mode) && !mode_is_reference(mode))
return NULL;
- }
+ ir_node *cnst;
+ ir_node *symconst;
if (is_Const(node)) {
cnst = node;
symconst = NULL;
} else if (is_SymConst_addr_ent(left) && is_Const(right)) {
cnst = right;
symconst = left;
+ } else {
+ return NULL;
}
} else {
return NULL;
}
+ long val = 0;
if (cnst != NULL) {
ir_tarval *offset = get_Const_tarval(cnst);
if (!tarval_is_long(offset)) {
if (!check_immediate_constraint(val, immediate_constraint_type))
return NULL;
}
+
+ ir_entity *symconst_ent = NULL;
if (symconst != NULL) {
- if (immediate_constraint_type != 0) {
- /* we need full 32bits for symconsts */
+ /* we need full 32bits for symconsts */
+ if (immediate_constraint_type != 'i')
return NULL;
- }
symconst_ent = get_SymConst_entity(symconst);
}
- if (cnst == NULL && symconst == NULL)
- return NULL;
- new_node = ia32_create_Immediate(symconst_ent, 0, val);
- return new_node;
+ ir_graph *const irg = get_irn_irg(node);
+ return ia32_create_Immediate(irg, symconst_ent, 0, val);
}