Commit fbf1c649 authored by Matthias Braun's avatar Matthias Braun
Browse files

ia32: simplify 64bit lowering

Use the same style as the SPARC 64bit lowering, making the additional
handle_intrinsics step unnecessary now.
parent 21fe424c
......@@ -85,17 +85,6 @@ static ir_entity *ret_addr_ent = NULL;
static ir_entity *omit_fp_ret_addr_ent = NULL;
static int precise_x87_spills;
/**
* The environment for the intrinsic mapping.
*/
static ia32_intrinsic_env_t intrinsic_env = {
NULL, /* entity for __divdi3 library call */
NULL, /* entity for __moddi3 library call */
NULL, /* entity for __udivdi3 library call */
NULL, /* entity for __umoddi3 library call */
};
typedef ir_node *(*create_const_node_func) (dbg_info *dbgi, ir_node *block);
/**
......@@ -1762,14 +1751,6 @@ static void ia32_lower_for_target(void)
ir_mode *mode_gp = ia32_reg_classes[CLASS_ia32_gp].mode;
size_t n_irgs = get_irp_n_irgs();
/* perform doubleword lowering */
lwrdw_param_t lower_dw_params = {
1, /* little endian */
64, /* doubleword size */
ia32_create_intrinsic_fkt,
&intrinsic_env,
};
/* lower compound param handling
* Note: we lower compound arguments ourself, since on ia32 we don't
* have hidden parameters but know where to find the structs on the stack.
......@@ -1813,8 +1794,7 @@ static void ia32_lower_for_target(void)
lower_switch(irg, 4, 256, mode_gp);
}
ir_prepare_dw_lowering(&lower_dw_params);
ir_lower_dw_ops();
ia32_lower64();
for (size_t i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
......@@ -1930,7 +1910,7 @@ const arch_isa_if_t ia32_isa_if = {
be_new_reload,
ia32_register_saved_by,
ia32_handle_intrinsics,
NULL,
ia32_prepare_graph,
ia32_before_ra, /* before register allocation hook */
ia32_finish_graph, /* called before codegen */
......
......@@ -106,25 +106,7 @@ ir_node *ia32_new_Fpu_truncate(ir_graph *irg);
*/
ir_node *ia32_turn_back_am(ir_node *node);
/**
* Maps all intrinsic calls that the backend support
* and map all instructions the backend did not support
* to runtime calls.
*/
void ia32_handle_intrinsics(void);
/**
* Ia32 implementation.
*
* @param method the method type of the emulation function entity
* @param op the emulated ir_op
* @param imode the input mode of the emulated opcode
* @param omode the output mode of the emulated opcode
* @param context the context parameter
*/
ir_entity *ia32_create_intrinsic_fkt(ir_type *method, const ir_op *op,
const ir_mode *imode, const ir_mode *omode,
void *context);
void ia32_lower64(void);
/**
* Return the stack entity that contains the return address.
......
......@@ -1221,43 +1221,43 @@ static void emit_be_Perm(const ir_node *node)
}
}
/* helper function for emit_ia32_Minus64Bit */
/* helper function for emit_ia32_Minus64 */
static void emit_mov(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
{
ia32_emitf(node, "movl %R, %R", src, dst);
}
/* helper function for emit_ia32_Minus64Bit */
/* helper function for emit_ia32_Minus64 */
static void emit_neg(const ir_node* node, const arch_register_t *reg)
{
ia32_emitf(node, "negl %R", reg);
}
/* helper function for emit_ia32_Minus64Bit */
/* helper function for emit_ia32_Minus64 */
static void emit_sbb0(const ir_node* node, const arch_register_t *reg)
{
ia32_emitf(node, "sbbl $0, %R", reg);
}
/* helper function for emit_ia32_Minus64Bit */
/* helper function for emit_ia32_Minus64 */
static void emit_sbb(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
{
ia32_emitf(node, "sbbl %R, %R", src, dst);
}
/* helper function for emit_ia32_Minus64Bit */
/* helper function for emit_ia32_Minus64 */
static void emit_xchg(const ir_node* node, const arch_register_t *src, const arch_register_t *dst)
{
ia32_emitf(node, "xchgl %R, %R", src, dst);
}
/* helper function for emit_ia32_Minus64Bit */
/* helper function for emit_ia32_Minus64 */
static void emit_zero(const ir_node* node, const arch_register_t *reg)
{
ia32_emitf(node, "xorl %R, %R", reg, reg);
}
static void emit_ia32_Minus64Bit(const ir_node *node)
static void emit_ia32_Minus64(const ir_node *node)
{
const arch_register_t *in_lo = arch_get_irn_register_in(node, 0);
const arch_register_t *in_hi = arch_get_irn_register_in(node, 1);
......@@ -1377,7 +1377,7 @@ static void ia32_register_emitters(void)
IA32_EMIT(IMul);
IA32_EMIT(Jcc);
IA32_EMIT(Setcc);
IA32_EMIT(Minus64Bit);
IA32_EMIT(Minus64);
IA32_EMIT(SwitchJmp);
IA32_EMIT(ClimbFrame);
IA32_EMIT(Jmp);
......@@ -2604,7 +2604,7 @@ static void bemit_helper_zero(const arch_register_t *reg)
bemit_modrr(reg, reg);
}
static void bemit_minus64bit(const ir_node *node)
static void bemit_minus64(const ir_node *node)
{
const arch_register_t *in_lo = arch_get_irn_register_in(node, 0);
const arch_register_t *in_hi = arch_get_irn_register_in(node, 1);
......@@ -3318,7 +3318,7 @@ static void ia32_register_binary_emitters(void)
be_set_emitter(op_ia32_Lea, bemit_lea);
be_set_emitter(op_ia32_Leave, bemit_leave);
be_set_emitter(op_ia32_Load, bemit_load);
be_set_emitter(op_ia32_Minus64Bit, bemit_minus64bit);
be_set_emitter(op_ia32_Minus64, bemit_minus64);
be_set_emitter(op_ia32_Mul, bemit_mul);
be_set_emitter(op_ia32_Neg, bemit_neg);
be_set_emitter(op_ia32_NegMem, bemit_negmem);
......
......@@ -181,7 +181,7 @@ static inline int need_constraint_copy(ir_node *irn)
case iro_ia32_Lea:
case iro_ia32_Conv_I2I:
case iro_ia32_CMovcc:
case iro_ia32_Minus64Bit:
case iro_ia32_Minus64:
return 0;
default:
......
This diff is collapsed.
......@@ -240,6 +240,7 @@ Adc => {
l_Add => {
ins => [ "left", "right" ],
outs => [ "res", "flags" ],
attr_type => "",
dump_func => "NULL",
},
......@@ -443,6 +444,7 @@ Sbb0 => {
l_Sub => {
ins => [ "minuend", "subtrahend" ],
outs => [ "res", "flags" ],
attr_type => "",
dump_func => "NULL",
},
......@@ -641,14 +643,20 @@ NegMem => {
modified_flags => $status_flags
},
Minus64Bit => {
Minus64 => {
irn_flags => [ "rematerializable" ],
reg_req => { in => [ "gp", "gp" ], out => [ "in_r1", "in_r2" ] },
outs => [ "low_res", "high_res" ],
outs => [ "res_low", "res_high" ],
latency => 3,
modified_flags => $status_flags
},
l_Minus64 => {
ins => [ "low", "high" ],
outs => [ "res_low", "res_high" ],
attr_type => "",
dump_func => "NULL",
},
Inc => {
irn_flags => [ "rematerializable" ],
......
......@@ -4010,6 +4010,18 @@ static ir_node *gen_ia32_l_Sbb(ir_node *node)
match_am | match_immediate | match_mode_neutral);
}
static ir_node *gen_ia32_l_Minus64(ir_node *node)
{
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *block = get_nodes_block(node);
ir_node *new_block = be_transform_node(block);
ir_node *low = get_irn_n(node, n_ia32_l_Minus64_low);
ir_node *high = get_irn_n(node, n_ia32_l_Minus64_high);
ir_node *new_low = be_transform_node(low);
ir_node *new_high = be_transform_node(high);
return new_bd_ia32_Minus64(dbgi, new_block, new_low, new_high);
}
static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
{
if (ia32_cg_config.use_sse2) {
......@@ -5320,19 +5332,19 @@ static void register_transformers(void)
be_set_transform_function(op_CopyB, ia32_gen_CopyB);
be_set_transform_function(op_Div, gen_Div);
be_set_transform_function(op_Eor, gen_Eor);
be_set_transform_function(op_ia32_GetEIP, be_duplicate_node);
be_set_transform_function(op_ia32_l_Adc, gen_ia32_l_Adc);
be_set_transform_function(op_ia32_l_Add, gen_ia32_l_Add);
be_set_transform_function(op_ia32_Leave, be_duplicate_node);
be_set_transform_function(op_ia32_l_FloattoLL, gen_ia32_l_FloattoLL);
be_set_transform_function(op_ia32_l_IMul, gen_ia32_l_IMul);
be_set_transform_function(op_ia32_l_LLtoFloat, gen_ia32_l_LLtoFloat);
be_set_transform_function(op_ia32_l_Minus64, gen_ia32_l_Minus64);
be_set_transform_function(op_ia32_l_Mul, gen_ia32_l_Mul);
be_set_transform_function(op_ia32_l_Sbb, gen_ia32_l_Sbb);
be_set_transform_function(op_ia32_l_Sub, gen_ia32_l_Sub);
be_set_transform_function(op_ia32_GetEIP, be_duplicate_node);
be_set_transform_function(op_ia32_Minus64Bit, be_duplicate_node);
be_set_transform_function(op_ia32_NoReg_GP, be_duplicate_node);
be_set_transform_function(op_ia32_NoReg_FP, be_duplicate_node);
be_set_transform_function(op_ia32_NoReg_GP, be_duplicate_node);
be_set_transform_function(op_ia32_NoReg_XMM, be_duplicate_node);
be_set_transform_function(op_ia32_PopEbp, be_duplicate_node);
be_set_transform_function(op_ia32_Push, be_duplicate_node);
......@@ -5371,7 +5383,7 @@ static void register_transformers(void)
be_set_transform_proj_function(op_ia32_l_Mul, gen_Proj_default);
be_set_transform_proj_function(op_ia32_l_Sbb, gen_Proj_default);
be_set_transform_proj_function(op_ia32_l_Sub, gen_Proj_default);
be_set_transform_proj_function(op_ia32_Minus64Bit, gen_Proj_default);
be_set_transform_proj_function(op_ia32_l_Minus64, gen_Proj_default);
be_set_transform_proj_function(op_Load, gen_Proj_Load);
be_set_transform_proj_function(op_Mod, gen_Proj_Mod);
be_set_transform_proj_function(op_Start, gen_Proj_Start);
......
......@@ -738,14 +738,7 @@ static void move(ir_node *node, ir_node *from_bl, ir_node *to_bl)
}
}
/**
* We need a custom version of part_block_edges because during transformation
* not all data-dependencies are explicit yet if a lowered nodes users are not
* lowered yet.
* We can fix this by modifying move to look for such implicit dependencies.
* Additionally we have to keep the proj_2_block map updated
*/
static ir_node *part_block_dw(ir_node *node)
ir_node *part_block_dw(ir_node *node)
{
ir_graph *irg = get_irn_irg(node);
ir_node *old_block = get_nodes_block(node);
......@@ -1554,10 +1547,7 @@ static void lower_Cmp(ir_node *cmp, ir_mode *m)
exchange(cmp, res);
}
/**
* Translate a Conv.
*/
static void lower_Conv(ir_node *node, ir_mode *mode)
void ir_default_lower_dw_Conv(ir_node *node, ir_mode *mode)
{
mode = get_irn_mode(node);
......@@ -2967,7 +2957,7 @@ void ir_prepare_dw_lowering(const lwrdw_param_t *new_param)
ir_register_dw_lower_function(op_Cmp, lower_Cmp);
ir_register_dw_lower_function(op_Cond, lower_Cond);
ir_register_dw_lower_function(op_Const, lower_Const);
ir_register_dw_lower_function(op_Conv, lower_Conv);
ir_register_dw_lower_function(op_Conv, ir_default_lower_dw_Conv);
ir_register_dw_lower_function(op_Div, lower_Div);
ir_register_dw_lower_function(op_Eor, lower_Eor);
ir_register_dw_lower_function(op_Load, lower_Load);
......
......@@ -70,8 +70,7 @@ void ir_register_dw_lower_function(ir_op *op, lower_dw_func func);
* After lowering a node a custom doubleword lowering function has to call this.
* It registers 2 new values for the high and low part of the lowered value.
*/
void ir_set_dw_lowered(ir_node *old, ir_node *new_low,
ir_node *new_high);
void ir_set_dw_lowered(ir_node *old, ir_node *new_low, ir_node *new_high);
/**
* Query lowering results of a node. In a lowering callback you can use this
......@@ -90,6 +89,17 @@ static inline ir_node *get_lowered_high(ir_node *node)
return get_node_entry(node)->high_word;
}
void ir_default_lower_dw_Conv(ir_node *node, ir_mode *mode);
/**
* We need a custom version of part_block_edges because during transformation
* not all data-dependencies are explicit yet if a lowered nodes users are not
* lowered yet.
* We can fix this by modifying move to look for such implicit dependencies.
* Additionally we have to keep the proj_2_block map updated
*/
ir_node *part_block_dw(ir_node *node);
/**
* Return the unsigned variant of the lowered mode
* Note: you must only call this during a dw_lowering (= in a lowering callback)
......
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