return 1;
}
+static void exchange_left_right(ir_node *node)
+{
+ ir_node *tmp = get_irn_n(node, 3);
+ set_irn_n(node, 3, get_irn_n(node, 2));
+ set_irn_n(node, 2, tmp);
+
+ set_ia32_pncode(node, get_inversed_pnc(get_ia32_pncode(node)));
+}
+
static void ia32_perform_memory_operand(const void *self, ir_node *irn, ir_node *spill, unsigned int i) {
const ia32_irn_ops_t *ops = self;
ia32_code_gen_t *cg = ops->cg;
assert(ia32_possible_memory_operand(self, irn, i) && "Cannot perform memory operand change");
if (i == 2) {
- ir_node *tmp = get_irn_n(irn, 3);
- set_irn_n(irn, 3, get_irn_n(irn, 2));
- set_irn_n(irn, 2, tmp);
+ exchange_left_right(irn);
}
set_ia32_op_type(irn, ia32_AddrModeS);
set_irn_n(irn, 3, ia32_get_admissible_noreg(cg, irn, 3));
set_irn_n(irn, 4, spill);
- //FIXME DBG_OPT_AM_S(reload, irn);
+ /* immediates are only allowed on the right side */
+ if(i == 2 && is_ia32_Immediate(get_irn_n(irn, 2))) {
+ exchange_left_right(irn);
+ }
}
static const be_abi_callbacks_t ia32_abi_callbacks = {
*/
void ia32_emit_binop(ia32_emit_env_t *env, const ir_node *node) {
int right_pos;
- const ir_node *right_op;
+ const ir_node *right_op = get_irn_n(node, 3);
switch(get_ia32_op_type(node)) {
case ia32_Normal:
- right_op = get_irn_n(node, 3);
if(is_ia32_Immediate(right_op)) {
emit_ia32_Immediate(env, right_op);
be_emit_cstring(env, ", ");
}
break;
case ia32_AddrModeS:
- ia32_emit_am(env, node);
- be_emit_cstring(env, ", ");
if (is_ia32_ImmConst(node) || is_ia32_ImmSymConst(node)) {
- assert(!produces_result(node) && "Source AM with Const must not produce result");
+ assert(!produces_result(node) &&
+ "Source AM with Const must not produce result");
ia32_emit_immediate(env, node);
+ be_emit_cstring(env, ", ");
+ ia32_emit_am(env, node);
+ } else if(is_ia32_Immediate(right_op)) {
+ assert(!produces_result(node) &&
+ "Source AM with Const must not produce result");
+
+ emit_ia32_Immediate(env, right_op);
+ be_emit_cstring(env, ", ");
+ ia32_emit_am(env, node);
} else if (produces_result(node)) {
+ ia32_emit_am(env, node);
+ be_emit_cstring(env, ", ");
ia32_emit_dest_register(env, node, 0);
} else {
+ ia32_emit_am(env, node);
+ be_emit_cstring(env, ", ");
ia32_emit_source_register(env, node, 2);
}
break;
case ia32_AddrModeD:
- right_pos = get_irn_arity(node) == 5 ? 3 : 2;
+ right_pos = get_irn_arity(node) >= 5 ? 3 : 2;
right_op = get_irn_n(node, right_pos);
if(is_ia32_Immediate(right_op)) {
emit_ia32_Immediate(env, right_op);
*/
static
void CondJmp_emitter(ia32_emit_env_t *env, const ir_node *node) {
- be_emit_cstring(env, "\tcmp ");
+ be_emit_cstring(env, "\tcmp");
+ ia32_emit_mode_suffix(env, node);
+ be_emit_char(env, ' ');
ia32_emit_binop(env, node);
be_emit_finish_line_gas(env, node);
*/
static
void TestJmp_emitter(ia32_emit_env_t *env, const ir_node *node) {
- be_emit_cstring(env, "\ttest ");
+ be_emit_cstring(env, "\ttest");
+ ia32_emit_mode_suffix(env, node);
+ be_emit_char(env, ' ');
+
ia32_emit_binop(env, node);
be_emit_finish_line_gas(env, node);
* Sets new_right index of irn to right and new_left index to left.
* Also exchange left and right
*/
-static void exchange_left_right(ir_node *irn, ir_node **left, ir_node **right, int new_left, int new_right) {
+static void exchange_left_right(ir_node *irn, ir_node **left, ir_node **right,
+ int new_left, int new_right)
+{
ir_node *temp;
set_irn_n(irn, new_right, *right);
DB((dbg, LEVEL_1, "transformed into %+F\n", res));
else
DB((dbg, LEVEL_1, "not transformed\n"));
- } else if (is_ia32_Ld(irn) || is_ia32_St(irn) || is_ia32_Store8Bit(irn)) {
+ } else if (is_ia32_Ld(irn) || is_ia32_St(irn)) {
/* - Load -> LEA into Load } TODO: If the LEA is used by more than one Load/Store */
/* - Store -> LEA into Store } it might be better to keep the LEA */
ir_node *left = get_irn_n(irn, 0);
foreach_out_edge_safe(left, edge, ne) {
src = get_edge_src_irn(edge);
- if (src && (get_edge_src_pos(edge) == 0) && (is_ia32_Ld(src) || is_ia32_St(src) || is_ia32_Store8Bit(src))) {
+ if (src && (get_edge_src_pos(edge) == 0) && (is_ia32_Ld(src) || is_ia32_St(src))) {
DBG((dbg, LEVEL_1, "\nmerging %+F into %+F\n", left, irn));
if (! is_ia32_got_lea(src))
merge_loadstore_lea(src, left);
&dest_out_reg_req_0
};
- if (!is_ia32_irn(irn) || is_ia32_Ld(irn) || is_ia32_St(irn) || is_ia32_Store8Bit(irn))
+ if (!is_ia32_irn(irn) || is_ia32_Ld(irn) || is_ia32_St(irn))
return;
if (is_ia32_Lea(irn))
return;
}
need_exchange_on_fail = 0;
+ /* immediates are only allowed on the right side */
+ if(is_ia32_Immediate(left)) {
+ exchange_left_right(irn, &left, &right, 3, 2);
+ }
+
DB((dbg, LEVEL_1, "merged with %+F into source AM\n", load));
}
res = new_rd_ia32_TestJmp(dbgi, current_ir_graph, block, noreg, noreg,
new_cmp_a, new_cmp_b, nomem, pnc);
+ set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);
SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
return res;
set_ia32_commutative(res);
}
- // Matze: disabled for now, because the default collect_spills_walker
- // is not able to detect the mode of the spilled value
- // moreover, the lea optimize phase freely exchanges left/right
- // without updating the pnc
- //set_ia32_am_support(res, ia32_am_Source | ia32_am_binary);
+ set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);
SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));