Commit c1126287 authored by Michael Beck's avatar Michael Beck
Browse files

- implemented __builtin_prefetch in ia32 BE

- add athlon_old for athlons WITHOUT SSE

[r24829]
parent 81d44459
......@@ -108,6 +108,7 @@ enum cpu_support {
cpu_k6 = arch_k6 | arch_mmx_insn,
cpu_k6_PLUS = arch_k6 | arch_3DNow_insn,
cpu_geode = arch_geode | arch_sse1_insn | arch_3DNowE_insn,
cpu_athlon_old = arch_athlon | arch_3DNowE_insn | arch_feature_p6_insn,
cpu_athlon = arch_athlon | arch_sse1_insn | arch_3DNowE_insn | arch_feature_p6_insn,
cpu_athlon64 = arch_athlon | arch_sse2_insn | arch_3DNowE_insn | arch_feature_p6_insn | arch_64bit_insn,
cpu_k8 = arch_k8 | arch_3DNowE_insn | arch_feature_p6_insn | arch_64bit_insn,
......@@ -156,7 +157,7 @@ static const lc_opt_enum_int_items_t arch_items[] = {
{ "k6-2", cpu_k6_PLUS },
{ "k6-3", cpu_k6_PLUS },
{ "geode", cpu_geode },
{ "athlon", cpu_athlon },
{ "athlon", cpu_athlon_old },
{ "athlon-tbird", cpu_athlon },
{ "athlon-4", cpu_athlon },
{ "athlon-xp", cpu_athlon },
......@@ -497,6 +498,8 @@ void ia32_setup_cg_config(void)
c->use_pad_return = FLAGS(opt_arch, arch_athlon_plus | arch_core2 | arch_generic32) && !opt_size;
c->use_bt = FLAGS(opt_arch, arch_core2 | arch_athlon_plus) || opt_size;
c->use_fisttp = FLAGS(opt_arch & arch, arch_feature_sse3);
c->use_sse_prefetch = FLAGS(arch, (arch_feature_3DNowE | arch_feature_sse1));
c->use_3dnow_prefetch = FLAGS(arch, arch_feature_3DNow);
c->optimize_cc = opt_cc;
c->use_unsafe_floatconv = opt_unsafe_floatconv;
......
......@@ -70,8 +70,12 @@ typedef struct {
unsigned use_pad_return:1;
/** use the bt instruction */
unsigned use_bt:1;
/** use fisttp instruction (requieres SSE3) */
/** use fisttp instruction (requires SSE3) */
unsigned use_fisttp:1;
/** use SSE prefetch instructions */
unsigned use_sse_prefetch:1;
/** use 3DNow! prefetch instructions */
unsigned use_3dnow_prefetch:1;
/** optimize calling convention where possible */
unsigned optimize_cc:1;
/**
......
......@@ -1519,6 +1519,78 @@ ClimbFrame => {
mode => $mode_gp
},
#
# Intel style prefetching
#
Prefetch0 => {
op_flags => "L|F",
state => "exc_pinned",
reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
ins => [ "base", "index", "mem" ],
outs => [ "M" ],
latency => 0,
emit => ". prefetch0 %AM",
units => [ "GP" ],
},
Prefetch1 => {
op_flags => "L|F",
state => "exc_pinned",
reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
ins => [ "base", "index", "mem" ],
outs => [ "M" ],
latency => 0,
emit => ". prefetch1 %AM",
units => [ "GP" ],
},
Prefetch2 => {
op_flags => "L|F",
state => "exc_pinned",
reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
ins => [ "base", "index", "mem" ],
outs => [ "M" ],
latency => 0,
emit => ". prefetch2 %AM",
units => [ "GP" ],
},
PrefetchNTA => {
op_flags => "L|F",
state => "exc_pinned",
reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
ins => [ "base", "index", "mem" ],
outs => [ "M" ],
latency => 0,
emit => ". prefetchnta %AM",
units => [ "GP" ],
},
#
# 3DNow! prefetch instructions
#
Prefetch => {
op_flags => "L|F",
state => "exc_pinned",
reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
ins => [ "base", "index", "mem" ],
outs => [ "M" ],
latency => 0,
emit => ". prefetch %AM",
units => [ "GP" ],
},
PrefetchW => {
op_flags => "L|F",
state => "exc_pinned",
reg_req => { in => [ "gp", "gp", "none" ], out => [ "none" ] },
ins => [ "base", "index", "mem" ],
outs => [ "M" ],
latency => 0,
emit => ". prefetchw %AM",
units => [ "GP" ],
},
#-----------------------------------------------------------------------------#
# _____ _____ ______ __ _ _ _ #
# / ____/ ____| ____| / _| | | | | | #
......
......@@ -4558,7 +4558,7 @@ static ir_node *gen_return_address(ir_node *node) {
}
SET_IA32_ORIG_NODE(load, node);
return new_rd_Proj(dbgi, current_ir_graph, block, load, mode_Iu, pn_ia32_Load_res);
return new_r_Proj(current_ir_graph, block, load, mode_Iu, pn_ia32_Load_res);
}
/**
......@@ -4608,7 +4608,96 @@ static ir_node *gen_frame_address(ir_node *node) {
}
SET_IA32_ORIG_NODE(load, node);
return new_rd_Proj(dbgi, current_ir_graph, block, load, mode_Iu, pn_ia32_Load_res);
return new_r_Proj(current_ir_graph, block, load, mode_Iu, pn_ia32_Load_res);
}
/**
* Transform Builtin frame_address
*/
static ir_node *gen_prefetch(ir_node *node) {
dbg_info *dbgi;
ir_node *ptr, *block, *mem, *noreg, *base, *index;
ir_node *param, *new_node;
long rw, locality;
tarval *tv;
ia32_address_t addr;
if (!ia32_cg_config.use_sse_prefetch && !ia32_cg_config.use_3dnow_prefetch) {
/* no prefetch at all, route memory */
return be_transform_node(get_Builtin_mem(node));
}
param = get_Builtin_param(node, 1);
tv = get_Const_tarval(param);
rw = get_tarval_long(tv);
if (rw == 1 && !ia32_cg_config.use_3dnow_prefetch) {
/* only 3DNow! has prefetchw */
return be_transform_node(get_Builtin_mem(node));
}
/* construct load address */
memset(&addr, 0, sizeof(addr));
ptr = get_Builtin_param(node, 0);
ia32_create_address_mode(&addr, ptr, 0);
base = addr.base;
index = addr.index;
noreg = ia32_new_NoReg_gp(env_cg);
if (base == NULL) {
base = noreg;
} else {
base = be_transform_node(base);
}
if (index == NULL) {
index = noreg;
} else {
index = be_transform_node(index);
}
dbgi = get_irn_dbg_info(node);
block = be_transform_node(get_nodes_block(node));
mem = be_transform_node(get_Builtin_mem(node));
if (rw == 1) {
/* we have 3DNow!, this was already checked above */
new_node = new_bd_ia32_PrefetchW(dbgi, block, base, index, mem);
} else if (ia32_cg_config.use_sse_prefetch) {
param = get_Builtin_param(node, 2);
tv = get_Const_tarval(param);
locality = get_tarval_long(tv);
/* SSE style prefetch */
switch (locality) {
case 0:
new_node = new_bd_ia32_PrefetchNTA(dbgi, block, base, index, mem);
break;
case 1:
new_node = new_bd_ia32_Prefetch2(dbgi, block, base, index, mem);
break;
case 2:
new_node = new_bd_ia32_Prefetch1(dbgi, block, base, index, mem);
break;
default:
new_node = new_bd_ia32_Prefetch0(dbgi, block, base, index, mem);
break;
}
} else {
assert(ia32_cg_config.use_3dnow_prefetch);
/* 3DNow! style prefetch */
new_node = new_bd_ia32_Prefetch(dbgi, block, base, index, mem);
}
set_irn_pinned(new_node, get_irn_pinned(node));
set_ia32_op_type(new_node, ia32_AddrModeS);
set_ia32_ls_mode(new_node, mode_Bu);
set_address(new_node, &addr);
SET_IA32_ORIG_NODE(new_node, node);
be_dep_on_frame(new_node);
return new_r_Proj(current_ir_graph, block, new_node, mode_M, pn_ia32_Prefetch_M);
}
/**
......@@ -4623,7 +4712,7 @@ static ir_node *gen_Builtin(ir_node *node) {
case ir_bk_frame_addess:
return gen_frame_address(node);
case ir_bk_prefetch:
break;
return gen_prefetch(node);
}
panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
}
......@@ -4642,7 +4731,8 @@ static ir_node *gen_Proj_Builtin(ir_node *proj) {
assert(get_Proj_proj(proj) == pn_Builtin_1_result);
return new_node;
case ir_bk_prefetch:
break;
assert(get_Proj_proj(proj) == pn_Builtin_M);
return new_node;
}
panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
}
......
Supports Markdown
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