Commit 7a3b3ea7 authored by Matthias Braun's avatar Matthias Braun
Browse files

use own mode for fpcw, fix constants for shift, xmm const assembler

[r13422]
parent 07a060d7
......@@ -65,6 +65,8 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
/* TODO: ugly */
static set *cur_reg_set = NULL;
ir_mode *mode_fpcw = NULL;
typedef ir_node *(*create_const_node_func) (dbg_info *dbg, ir_graph *irg, ir_node *block);
static INLINE ir_node *create_const(ia32_code_gen_t *cg, ir_node **place,
......@@ -1510,6 +1512,10 @@ static void *ia32_init(FILE *file_handle) {
isa = xmalloc(sizeof(*isa));
memcpy(isa, &ia32_isa_template, sizeof(*isa));
if(mode_fpcw == NULL) {
mode_fpcw = new_ir_mode("Fpcw", irms_int_number, 16, 0, irma_none, 0);
}
ia32_register_init(isa);
ia32_create_opcodes();
ia32_register_copy_attr_func();
......
......@@ -151,6 +151,9 @@ typedef struct _ia32_intrinsic_env_t {
ir_entity *d_ll_conv; /**< entity for converts d -> ll */
} ia32_intrinsic_env_t;
/** mode for the floating point control word */
extern ir_mode *mode_fpcw;
/**
* Returns the unique per irg GP NoReg node.
*/
......
......@@ -27,6 +27,7 @@
#include "../bearch_t.h"
#include "bearch_ia32_t.h"
#include "ia32_nodes_attr.h"
#include "ia32_new_nodes.h"
#include "gen_ia32_regalloc_if.h"
......
......@@ -160,7 +160,7 @@ $arch = "ia32";
],
fp_cw => [ # the floating point control word
{ name => "fpcw", type => 4 | 32},
{ mode => "mode_Hu" }
{ mode => "mode_fpcw" }
],
flags => [
{ name => "eflags", type => 4 },
......@@ -288,6 +288,7 @@ $default_cmp_attr = "return ia32_compare_attr(attr_a, attr_b);";
$mode_xmm = "mode_E";
$mode_gp = "mode_Iu";
$mode_fpcw = "mode_fpcw";
$status_flags = [ "CF", "PF", "AF", "ZF", "SF", "OF" ];
$fpcw_flags = [ "FP_IM", "FP_DM", "FP_ZM", "FP_OM", "FP_UM", "FP_PM",
"FP_PC0", "FP_PC1", "FP_RC0", "FP_RC1", "FP_X" ];
......@@ -568,9 +569,9 @@ if (get_ia32_immop_type(node) == ia32_ImmNone) {
}
} else {
if (get_ia32_op_type(node) == ia32_AddrModeD) {
. shldl $%C, %S4, %AM
. shldl %C, %S4, %AM
} else {
. shldl $%C, %S4, %S3
. shldl %C, %S4, %S3
}
}
',
......@@ -623,9 +624,9 @@ if (get_ia32_immop_type(node) == ia32_ImmNone) {
}
} else {
if (get_ia32_op_type(node) == ia32_AddrModeD) {
. shrdl $%C, %S4, %AM
. shrdl %C, %S4, %AM
} else {
. shrdl $%C, %S4, %S3
. shrdl %C, %S4, %S3
}
}
',
......@@ -871,7 +872,7 @@ ChangeCW => {
irn_flags => "I",
comment => "change floating point control word",
reg_req => { out => [ "fp_cw" ] },
mode => "mode_Hu",
mode => $mode_fpcw,
latency => 3,
units => [ "GP" ],
modified_flags => $fpcw_flags
......@@ -884,7 +885,7 @@ FldCW => {
reg_req => { in => [ "gp", "gp", "none" ], out => [ "fp_cw" ] },
latency => 5,
emit => ". fldcw %AM",
mode => "mode_Hu",
mode => $mode_fpcw,
units => [ "GP" ],
modified_flags => $fpcw_flags
},
......@@ -1178,7 +1179,7 @@ xConst => {
irn_flags => "R",
comment => "represents a SSE constant",
reg_req => { out => [ "xmm" ] },
emit => '. mov%XXM $%C, %D1',
emit => '. mov%XXM %C, %D1',
latency => 2,
units => [ "SSE" ],
mode => "mode_E",
......
......@@ -108,6 +108,14 @@ static ir_node *transform_node(ia32_transform_env_t *env, ir_node *node);
static void duplicate_deps(ia32_transform_env_t *env, ir_node *old_node,
ir_node *new_node);
static INLINE int mode_needs_gp_reg(ir_mode *mode)
{
if(mode == mode_fpcw)
return 0;
return mode_is_int(mode) || mode_is_character(mode) || mode_is_reference(mode);
}
static INLINE void set_new_node(ir_node *old_node, ir_node *new_node)
{
set_irn_link(old_node, new_node);
......@@ -1812,7 +1820,7 @@ static ir_node *gen_Cond(ia32_transform_env_t *env, ir_node *node) {
pnc = get_inversed_pnc(pnc);
}
if ((pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg) && mode_is_int(get_irn_mode(expr))) {
if ((pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg) && mode_needs_gp_reg(get_irn_mode(expr))) {
if (get_ia32_immop_type(cnst) == ia32_ImmConst &&
classify_tarval(get_ia32_Immop_tarval(cnst)) == TV_CLASSIFY_NULL)
{
......@@ -2723,7 +2731,7 @@ static ir_node *gen_Unknown(ia32_transform_env_t *env, ir_node *node) {
return ia32_new_Unknown_xmm(env->cg);
else
return ia32_new_Unknown_vfp(env->cg);
} else if (mode_is_int(mode) || mode_is_reference(mode)) {
} else if (mode_needs_gp_reg(mode)) {
return ia32_new_Unknown_gp(env->cg);
} else {
assert(0 && "unsupported Unknown-Mode");
......@@ -2743,7 +2751,7 @@ static ir_node *gen_Phi(ia32_transform_env_t *env, ir_node *node) {
ir_node *phi;
int i, arity;
if(mode_is_int(mode) || mode_is_reference(mode)) {
if(mode_needs_gp_reg(mode)) {
// we shouldn't have any 64bit stuff around anymore
assert(get_mode_size_bits(mode) <= 32);
// all integer operations are on 32bit registers now
......@@ -3655,7 +3663,7 @@ static ir_node *gen_Proj(ia32_transform_env_t *env, ir_node *node) {
ir_node *new_pred = transform_node(env, pred);
ir_node *block = transform_node(env, get_nodes_block(node));
ir_mode *mode = get_irn_mode(node);
if (mode_is_signed(mode) || mode_is_reference(mode)) {
if (mode_needs_gp_reg(mode)) {
return new_r_Proj(irg, block, new_pred, mode_Iu, get_Proj_proj(node));
}
}
......
......@@ -1671,9 +1671,13 @@ static int sim_Copy(x87_state *state, ir_node *n) {
} else {
/* just a virtual copy */
x87_set_st(state, arch_register_get_index(out), get_unop_op(n), op1_idx);
/* don't remove the node to keep the verifier quiet :),
the emitter won't emit any code for the node */
#if 0
sched_remove(n);
DB((dbg, LEVEL_1, "<<< KILLED %s\n", get_irn_opname(n)));
exchange(n, get_unop_op(n));
#endif
}
}
......
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