in register we need. */
op = get_irn_n(irn, pos);
- reg = arch_get_irn_register(arch_env, op);
+ reg = arch_get_irn_register(op);
assert(reg && "no in register found");
/* in case of unknown register: just return a valid register */
if (reg == &ia32_gp_regs[REG_GP_UKNWN]) {
- const arch_register_req_t *req;
-
- /* ask for the requirements */
- req = arch_get_register_req(arch_env, irn, pos);
+ const arch_register_req_t *req = arch_get_register_req(irn, pos);
if (arch_register_req_is(req, limited)) {
/* in case of limited requirements: get the first allowed register */
if (get_irn_mode(irn) != mode_T) {
assert(pos == 0);
- reg = arch_get_irn_register(arch_env, irn);
+ reg = arch_get_irn_register(irn);
} else if (is_ia32_irn(irn)) {
reg = get_ia32_out_reg(irn, pos);
} else {
proj = get_edge_src_irn(edge);
assert(is_Proj(proj) && "non-Proj from mode_T node");
if (get_Proj_proj(proj) == pos) {
- reg = arch_get_irn_register(arch_env, proj);
+ reg = arch_get_irn_register(proj);
break;
}
}
emit_register(reg, NULL);
}
-static void emit_ia32_Immediate(const ir_node *node);
+static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
+{
+ ident *id;
+
+ set_entity_backend_marked(entity, 1);
+ id = get_entity_ld_ident(entity);
+ be_emit_ident(id);
+
+ if (get_entity_owner(entity) == get_tls_type()) {
+ if (get_entity_visibility(entity) == visibility_external_allocated) {
+ be_emit_cstring("@INDNTPOFF");
+ } else {
+ be_emit_cstring("@NTPOFF");
+ }
+ }
+
+ if (!no_pic_adjust && do_pic) {
+ /* TODO: only do this when necessary */
+ be_emit_char('-');
+ be_emit_string(pic_base_label);
+ }
+}
+
+static void emit_ia32_Immediate_no_prefix(const ir_node *node)
+{
+ const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
+
+ if (attr->symconst != NULL) {
+ if (attr->sc_sign)
+ be_emit_char('-');
+ ia32_emit_entity(attr->symconst, 0);
+ }
+ if (attr->symconst == NULL || attr->offset != 0) {
+ if (attr->symconst != NULL) {
+ be_emit_irprintf("%+d", attr->offset);
+ } else {
+ be_emit_irprintf("0x%X", attr->offset);
+ }
+ }
+}
+
+static void emit_ia32_Immediate(const ir_node *node)
+{
+ be_emit_char('$');
+ emit_ia32_Immediate_no_prefix(node);
+}
void ia32_emit_8bit_source_register_or_immediate(const ir_node *node, int pos)
{
be_emit_string(str);
}
+typedef enum ia32_emit_mod_t {
+ EMIT_RESPECT_LS = 1U << 0,
+ EMIT_ALTERNATE_AM = 1U << 1
+} ia32_emit_mod_t;
+
/**
* fmt parameter output
* ---- ---------------------- ---------------------------------------------
*
* x starts at 0
* # modifier for %ASx, %D and %S uses ls mode of node to alter register width
+ * * modifier does not prefix immediates with $, but AM with *
*/
static void ia32_emitf(const ir_node *node, const char *fmt, ...)
{
va_start(ap, fmt);
for (;;) {
- const char *start = fmt;
- const ir_mode *mode = NULL;
+ const char *start = fmt;
+ ia32_emit_mod_t mod = 0;
while (*fmt != '%' && *fmt != '\n' && *fmt != '\0')
++fmt;
break;
++fmt;
+ if (*fmt == '*') {
+ mod |= EMIT_ALTERNATE_AM;
+ ++fmt;
+ }
+
if (*fmt == '#') {
- mode = get_ia32_ls_mode(node);
+ mod |= EMIT_RESPECT_LS;
++fmt;
}
case 'A': {
switch (*fmt++) {
case 'M':
+ if (mod & EMIT_ALTERNATE_AM)
+ be_emit_char('*');
ia32_emit_am(node);
break;
case 'R': {
const arch_register_t *reg = va_arg(ap, const arch_register_t*);
+ if (mod & EMIT_ALTERNATE_AM)
+ be_emit_char('*');
if (get_ia32_op_type(node) == ia32_AddrModeS) {
ia32_emit_am(node);
} else {
case 'S':
if (get_ia32_op_type(node) == ia32_AddrModeS) {
+ if (mod & EMIT_ALTERNATE_AM)
+ be_emit_char('*');
ia32_emit_am(node);
++fmt;
} else {
pos = *fmt++ - '0';
reg = get_out_reg(node, pos);
- emit_register(reg, mode);
+ emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
break;
}
case 'I':
- emit_ia32_Immediate(node);
+ if (!(mod & EMIT_ALTERNATE_AM))
+ be_emit_char('$');
+ emit_ia32_Immediate_no_prefix(node);
break;
case 'L':
pos = *fmt++ - '0';
in = get_irn_n(node, pos);
if (is_ia32_Immediate(in)) {
- emit_ia32_Immediate(in);
+ if (!(mod & EMIT_ALTERNATE_AM))
+ be_emit_char('$');
+ emit_ia32_Immediate_no_prefix(in);
} else {
+ if (mod & EMIT_ALTERNATE_AM)
+ be_emit_char('*');
const arch_register_t *reg = get_in_reg(node, pos);
- emit_register(reg, mode);
+ emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
}
break;
}
ia32_emitf(node, fmt);
}
-static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
-{
- ident *id;
-
- set_entity_backend_marked(entity, 1);
- id = get_entity_ld_ident(entity);
- be_emit_ident(id);
-
- if (get_entity_owner(entity) == get_tls_type()) {
- if (get_entity_visibility(entity) == visibility_external_allocated) {
- be_emit_cstring("@INDNTPOFF");
- } else {
- be_emit_cstring("@NTPOFF");
- }
- }
-
- if (!no_pic_adjust && do_pic) {
- /* TODO: only do this when necessary */
- be_emit_char('-');
- be_emit_string(pic_base_label);
- }
-}
-
/**
* Emits address mode.
*/
{
const ia32_attr_t *attr = get_ia32_attr_const(node);
int ins_permuted = attr->data.ins_permuted;
- const arch_register_t *out = arch_get_irn_register(arch_env, node);
+ const arch_register_t *out = arch_get_irn_register(node);
pn_Cmp pnc = get_ia32_condcode(node);
const arch_register_t *in_true;
const arch_register_t *in_false;
pnc = determine_final_pnc(node, n_ia32_CMov_eflags, pnc);
- in_true = arch_get_irn_register(arch_env,
- get_irn_n(node, n_ia32_CMov_val_true));
- in_false = arch_get_irn_register(arch_env,
- get_irn_n(node, n_ia32_CMov_val_false));
+ in_true = arch_get_irn_register(get_irn_n(node, n_ia32_CMov_val_true));
+ in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMov_val_false));
/* should be same constraint fullfilled? */
if (out == in_false) {
}
}
-static void emit_ia32_Immediate(const ir_node *node)
-{
- const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
-
- be_emit_char('$');
- if (attr->symconst != NULL) {
- if (attr->sc_sign)
- be_emit_char('-');
- ia32_emit_entity(attr->symconst, 0);
- }
- if (attr->symconst == NULL || attr->offset != 0) {
- if (attr->symconst != NULL) {
- be_emit_irprintf("%+d", attr->offset);
- } else {
- be_emit_irprintf("0x%X", attr->offset);
- }
- }
-}
-
/**
* Emit an inline assembler operand.
*
if (signed_mode &&
smaller_bits == 16 &&
&ia32_gp_regs[REG_EAX] == get_out_reg(node, 0) &&
- &ia32_gp_regs[REG_EAX] == arch_get_irn_register(arch_env, get_irn_n(node, n_ia32_unary_op))) {
+ &ia32_gp_regs[REG_EAX] == arch_get_irn_register(get_irn_n(node, n_ia32_unary_op))) {
/* argument and result are both in EAX and signedness is ok: use the
* smaller cwtl opcode */
ia32_emitf(node, "\tcwtl\n");
}
}
+/**
+ * Emits a call
+ */
+static void emit_ia32_Call(const ir_node *node)
+{
+ /* Special case: Call must not have its immediates prefixed by $, instead
+ * address mode is prefixed by *. */
+ ia32_emitf(node, "\tcall %*AS3\n");
+}
+
/*******************************************
* _ _
*
*******************************************/
-/**
- * Emits a backend call
- */
-static void emit_be_Call(const ir_node *node)
-{
- ir_entity *ent = be_Call_get_entity(node);
-
- be_emit_cstring("\tcall ");
- if (ent) {
- ia32_emit_entity(ent, 1);
- } else {
- const arch_register_t *reg = get_in_reg(node, be_pos_Call_ptr);
- be_emit_char('*');
- emit_register(reg, NULL);
- }
- be_emit_finish_line_gas(node);
-}
-
/**
* Emits code to increase stack pointer.
*/
*/
static void Copy_emitter(const ir_node *node, const ir_node *op)
{
- const arch_register_t *in = arch_get_irn_register(arch_env, op);
- const arch_register_t *out = arch_get_irn_register(arch_env, node);
+ const arch_register_t *in = arch_get_irn_register(op);
+ const arch_register_t *out = arch_get_irn_register(node);
if (in == out) {
return;
const arch_register_t *in0, *in1;
const arch_register_class_t *cls0, *cls1;
- in0 = arch_get_irn_register(arch_env, get_irn_n(node, 0));
- in1 = arch_get_irn_register(arch_env, get_irn_n(node, 1));
+ in0 = arch_get_irn_register(get_irn_n(node, 0));
+ in1 = arch_get_irn_register(get_irn_n(node, 1));
cls0 = arch_register_get_class(in0);
cls1 = arch_register_get_class(in1);
IA32_EMIT2(Conv_I2I8Bit, Conv_I2I);
IA32_EMIT(Asm);
IA32_EMIT(CMov);
+ IA32_EMIT(Call);
IA32_EMIT(Const);
IA32_EMIT(Conv_FP2FP);
IA32_EMIT(Conv_FP2I);
IA32_EMIT(SwitchJmp);
/* benode emitter */
- BE_EMIT(Call);
BE_EMIT(Copy);
BE_EMIT(CopyKeep);
BE_EMIT(IncSP);
/* firm emitter */
EMIT(Jmp);
IGN(Phi);
- IGN(Proj);
IGN(Start);
#undef BE_EMIT