be_emit_string(is_signed ? "s" : "u");
}
-/**
- * emit FP load mode char
- */
-void sparc_emit_fp_load_mode(const ir_node *node)
+static void emit_fp_suffix(const ir_mode *mode)
{
- const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
- ir_mode *mode = attr->load_store_mode;
- int bits = get_mode_size_bits(mode);
-
+ unsigned bits = get_mode_size_bits(mode);
assert(mode_is_float(mode));
if (bits == 32) {
- be_emit_string("f");
+ be_emit_char('s');
} else if (bits == 64) {
- be_emit_string("df");
+ be_emit_char('d');
+ } else if (bits == 128) {
+ be_emit_char('q');
} else {
- panic("FP load mode > 64bits not implemented yet");
+ panic("invalid FP mode");
}
}
-/**
- * emit FP store mode char
- */
-void sparc_emit_fp_store_mode(const ir_node *node)
+void sparc_emit_fp_conv_source(const ir_node *node)
{
- const sparc_load_store_attr_t *attr = get_sparc_load_store_attr_const(node);
- ir_mode *mode = attr->load_store_mode;
- int bits = get_mode_size_bits(mode);
-
- assert(mode_is_float(mode));
+ const sparc_fp_conv_attr_t *attr = get_sparc_fp_conv_attr_const(node);
+ emit_fp_suffix(attr->src_mode);
+}
- if (bits == 32) {
- be_emit_string("f");
- } else if (bits == 64) {
- be_emit_string("df");
- } else {
- panic("FP store mode > 64bits not implemented yet");
- }
+void sparc_emit_fp_conv_destination(const ir_node *node)
+{
+ const sparc_fp_conv_attr_t *attr = get_sparc_fp_conv_attr_const(node);
+ emit_fp_suffix(attr->dest_mode);
}
/**
*/
void sparc_emit_fp_mode_suffix(const ir_node *node)
{
- ir_mode *mode = get_irn_mode(node);
- int bits = get_mode_size_bits(mode);
-
- assert(mode_is_float(mode));
-
- if (bits == 32) {
- be_emit_string("s");
- } else if (bits == 64) {
- be_emit_string("d");
- } else {
- panic("FP mode > 64bits not implemented yet");
- }
+ const sparc_fp_attr_t *attr = get_sparc_fp_attr_const(node);
+ emit_fp_suffix(attr->fp_mode);
}
/**
be_emit_finish_line_gas(irn);
}
-/**
- * emit code for div with the correct sign prefix
- */
-static void emit_sparc_Div(const ir_node *irn)
-{
- be_emit_cstring("\t");
- sparc_emit_mode_sign_prefix(irn);
- be_emit_cstring("div ");
-
- sparc_emit_source_register(irn, 0);
- be_emit_cstring(", ");
- sparc_emit_reg_or_imm(irn, 1);
- be_emit_cstring(", ");
- sparc_emit_dest_register(irn, 0);
- be_emit_finish_line_gas(irn);
-}
-
-/**
- * emit code for mul with the correct sign prefix
- */
-static void emit_sparc_Mul(const ir_node *irn)
-{
- be_emit_cstring("\t");
- sparc_emit_mode_sign_prefix(irn);
- be_emit_cstring("mul ");
-
- sparc_emit_source_register(irn, 0);
- be_emit_cstring(", ");
- sparc_emit_reg_or_imm(irn, 1);
- be_emit_cstring(", ");
- sparc_emit_dest_register(irn, 0);
- be_emit_finish_line_gas(irn);
-}
-
/**
* emits code for mulh
*/
set_emitter(op_be_Return, emit_be_Return);
set_emitter(op_sparc_BXX, emit_sparc_BXX);
set_emitter(op_sparc_Call, emit_sparc_Call);
- set_emitter(op_sparc_Div, emit_sparc_Div);
set_emitter(op_sparc_FrameAddr, emit_sparc_FrameAddr);
set_emitter(op_sparc_HiImm, emit_sparc_HiImm);
set_emitter(op_sparc_Ba, emit_sparc_Ba);
set_emitter(op_sparc_LoImm, emit_sparc_LoImm);
- set_emitter(op_sparc_Mul, emit_sparc_Mul);
set_emitter(op_sparc_Mulh, emit_sparc_Mulh);
set_emitter(op_sparc_Save, emit_sparc_Save);
set_emitter(op_sparc_SymConst, emit_sparc_SymConst);
void sparc_emit_store_mode(const ir_node *node);
void sparc_emit_mode_sign_prefix(const ir_node *node);
void sparc_emit_fp_mode_suffix(const ir_node *node);
-void sparc_emit_fp_load_mode(const ir_node *node);
-void sparc_emit_fp_store_mode(const ir_node *node);
+void sparc_emit_fp_conv_source(const ir_node *node);
+void sparc_emit_fp_conv_destination(const ir_node *node);
void sparc_gen_routine(const sparc_code_gen_t *cg, ir_graph *irg);
return is_sparc_Save(node);
}
+static bool has_fp_attr(const ir_node *node)
+{
+ return is_sparc_fadd(node) || is_sparc_fsub(node)
+ || is_sparc_fmul(node) || is_sparc_fdiv(node)
+ || is_sparc_fftoi(node) || is_sparc_fitof(node)
+ || is_sparc_fneg(node);
+}
+
+static bool has_fp_conv_attr(const ir_node *node)
+{
+ return is_sparc_fftof(node);
+}
+
/**
* Dumper interface for dumping sparc nodes in vcg.
* @param F the output file
fprintf(F, "n projs: %d\n", attr->n_projs);
fprintf(F, "default proj: %ld\n", attr->default_proj_num);
}
+ if (has_fp_attr(n)) {
+ const sparc_fp_attr_t *attr = get_sparc_fp_attr_const(n);
+ ir_fprintf(F, "fp_mode: %+F\n", attr->fp_mode);
+ }
+ if (has_fp_conv_attr(n)) {
+ const sparc_fp_conv_attr_t *attr = get_sparc_fp_conv_attr_const(n);
+ ir_fprintf(F, "conv from: %+F\n", attr->src_mode);
+ ir_fprintf(F, "conv to: %+F\n", attr->dest_mode);
+ }
break;
case dump_node_nodeattr_txt:
return (const sparc_save_attr_t*) get_irn_generic_attr_const(node);
}
+sparc_fp_attr_t *get_sparc_fp_attr(ir_node *node)
+{
+ assert(has_fp_attr(node));
+ return (sparc_fp_attr_t*) get_irn_generic_attr(node);
+}
+
+const sparc_fp_attr_t *get_sparc_fp_attr_const(const ir_node *node)
+{
+ assert(has_fp_attr(node));
+ return (const sparc_fp_attr_t*) get_irn_generic_attr_const(node);
+}
+
+sparc_fp_conv_attr_t *get_sparc_fp_conv_attr(ir_node *node)
+{
+ assert(has_fp_conv_attr(node));
+ return (sparc_fp_conv_attr_t*) get_irn_generic_attr(node);
+}
+
+const sparc_fp_conv_attr_t *get_sparc_fp_conv_attr_const(const ir_node *node)
+{
+ assert(has_fp_conv_attr(node));
+ return (const sparc_fp_conv_attr_t*) get_irn_generic_attr_const(node);
+}
+
/**
* Returns the argument register requirements of a sparc node.
*/
memset(info->out_infos, 0, n_res * sizeof(info->out_infos[0]));
}
-/* CUSTOM ATTRIBUTE INIT FUNCTIONS */
static void init_sparc_load_store_attributes(ir_node *res, ir_mode *ls_mode,
ir_entity *entity,
int entity_sign, long offset,
attr->fp_offset = 0;
}
-static void init_sparc_save_attr(ir_node *res, int initial_stacksize)
+static void init_sparc_save_attributes(ir_node *res, int initial_stacksize)
{
sparc_save_attr_t *attr = get_sparc_save_attr(res);
attr->initial_stacksize = initial_stacksize;
}
+static void init_sparc_fp_attributes(ir_node *res, ir_mode *fp_mode)
+{
+ sparc_fp_attr_t *attr = get_sparc_fp_attr(res);
+ attr->fp_mode = fp_mode;
+}
+
+static void init_sparc_fp_conv_attributes(ir_node *res, ir_mode *src_mode,
+ ir_mode *dest_mode)
+{
+ sparc_fp_conv_attr_t *attr = get_sparc_fp_conv_attr(res);
+ attr->src_mode = src_mode;
+ attr->dest_mode = dest_mode;
+}
+
/**
* copies sparc attributes of node
*/
|| attr_a->is_load_store != attr_b->is_load_store;
}
-
-/* CUSTOM ATTRIBUTE CMP FUNCTIONS */
static int cmp_attr_sparc_load_store(ir_node *a, ir_node *b)
{
const sparc_load_store_attr_t *attr_a = get_sparc_load_store_attr_const(a);
const sparc_load_store_attr_t *attr_b = get_sparc_load_store_attr_const(b);
if (cmp_attr_sparc(a, b))
- return 1;
+ return 1;
return attr_a->entity != attr_b->entity
|| attr_a->entity_sign != attr_b->entity_sign
const sparc_symconst_attr_t *attr_b = get_sparc_symconst_attr_const(b);
if (cmp_attr_sparc(a, b))
- return 1;
+ return 1;
return attr_a->entity != attr_b->entity
|| attr_a->fp_offset != attr_b->fp_offset;
const sparc_jmp_cond_attr_t *attr_b = get_sparc_jmp_cond_attr_const(b);
if (cmp_attr_sparc(a, b))
- return 1;
+ return 1;
return attr_a->proj_num != attr_b->proj_num
|| attr_a->is_unsigned != attr_b->is_unsigned;
const sparc_jmp_switch_attr_t *attr_b = get_sparc_jmp_switch_attr_const(b);
if (cmp_attr_sparc(a, b))
- return 1;
+ return 1;
return attr_a->default_proj_num != attr_b->default_proj_num
|| attr_a->n_projs != attr_b->n_projs;
const sparc_save_attr_t *attr_b = get_sparc_save_attr_const(b);
if (cmp_attr_sparc(a, b))
- return 1;
+ return 1;
return attr_a->initial_stacksize != attr_b->initial_stacksize;
}
+static int cmp_attr_sparc_fp(ir_node *a, ir_node *b)
+{
+ const sparc_fp_attr_t *attr_a = get_sparc_fp_attr_const(a);
+ const sparc_fp_attr_t *attr_b = get_sparc_fp_attr_const(b);
+
+ if (cmp_attr_sparc(a, b))
+ return 1;
+
+ return attr_a->fp_mode != attr_b->fp_mode;
+}
+
+static int cmp_attr_sparc_fp_conv(ir_node *a, ir_node *b)
+{
+ const sparc_fp_conv_attr_t *attr_a = get_sparc_fp_conv_attr_const(a);
+ const sparc_fp_conv_attr_t *attr_b = get_sparc_fp_conv_attr_const(b);
+
+ if (cmp_attr_sparc(a, b))
+ return 1;
+
+ return attr_a->src_mode != attr_b->src_mode
+ || attr_a->dest_mode != attr_b->dest_mode;;
+}
+
/* Include the generated constructor functions */
#include "gen_sparc_new_nodes.c.inl"
sparc_save_attr_t *get_sparc_save_attr(ir_node *node);
const sparc_save_attr_t *get_sparc_save_attr_const(const ir_node *node);
+sparc_fp_attr_t *get_sparc_fp_attr(ir_node *node);
+const sparc_fp_attr_t *get_sparc_fp_attr_const(const ir_node *node);
+
+sparc_fp_conv_attr_t *get_sparc_fp_conv_attr(ir_node *node);
+const sparc_fp_conv_attr_t *get_sparc_fp_conv_attr_const(const ir_node *node);
+
/**
* Returns the argument register requirements of an sparc node.
*/
*/
typedef struct sparc_fp_attr_t sparc_fp_attr_t;
struct sparc_fp_attr_t {
- sparc_attr_t base; /**< generic attribute */
- double fp_immediate; /* the FP immediate value */
+ sparc_attr_t base; /**< generic attribute */
+ ir_mode *fp_mode;
+};
+
+typedef struct sparc_fp_conv_attr_t sparc_fp_conv_attr_t;
+struct sparc_fp_conv_attr_t {
+ sparc_attr_t base;
+ ir_mode *src_mode;
+ ir_mode *dest_mode;
};
/**
IM => "${arch}_emit_immediate(node);",
LM => "${arch}_emit_load_mode(node);",
SM => "${arch}_emit_store_mode(node);",
- EXTPREF => "${arch}_emit_mode_sign_prefix(node);",
FPM => "${arch}_emit_fp_mode_suffix(node);",
- FPLM => "${arch}_emit_fp_load_mode(node);",
- FPSM => "${arch}_emit_fp_store_mode(node);",
- O => "${arch}_emit_offset(node);",
+ FCONVS => "${arch}_emit_fp_conv_source(node);",
+ FCONVD => "${arch}_emit_fp_conv_destination(node);",
+ O => "${arch}_emit_offset(node);",
);
$default_attr_type = "sparc_attr_t";
sparc_jmp_cond_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
sparc_jmp_switch_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
sparc_save_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);",
-
+ sparc_fp_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);\n".
+ "\tinit_sparc_fp_attributes(res, fp_mode);\n",
+ sparc_fp_conv_attr_t => "\tinit_sparc_attributes(res, flags, in_reqs, exec_units, n_res);".
+ "\tinit_sparc_fp_conv_attributes(res, src_mode, dest_mode);\n",
);
%compare_attr = (
sparc_jmp_cond_attr_t => "cmp_attr_sparc_jmp_cond",
sparc_jmp_switch_attr_t => "cmp_attr_sparc_jmp_switch",
sparc_save_attr_t => "cmp_attr_sparc_save",
+ sparc_fp_attr_t => "cmp_attr_sparc_fp",
+ sparc_fp_conv_attr_t => "cmp_attr_sparc_fp_conv",
);
# addressing modes: imm, reg, reg +/- imm, reg + reg
outs => [ "stack", "frame", "mem" ],
attr => "int initial_stacksize",
attr_type => "sparc_save_attr_t",
- init_attr => "\tinit_sparc_save_attr(res, initial_stacksize);",
+ init_attr => "\tinit_sparc_save_attributes(res, initial_stacksize);",
},
SubSP => {
Sll => {
irn_flags => [ "rematerializable" ],
- mode => $mode_gp,
+ mode => $mode_gp,
reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
emit => '. sll %S1, %R2I, %D1',
constructors => \%binop_operand_constructors,
Slr => {
irn_flags => [ "rematerializable" ],
- mode => $mode_gp,
+ mode => $mode_gp,
reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
emit => '. srl %S1, %R2I, %D1',
constructors => \%binop_operand_constructors,
Sra => {
irn_flags => [ "rematerializable" ],
- mode => $mode_gp,
+ mode => $mode_gp,
reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
emit => '. sra %S1, %R2I, %D1',
constructors => \%binop_operand_constructors,
And => {
irn_flags => [ "rematerializable" ],
- mode => $mode_gp,
+ mode => $mode_gp,
reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
emit => '. and %S1, %R2I, %D1',
constructors => \%binop_operand_constructors,
Or => {
irn_flags => [ "rematerializable" ],
- mode => $mode_gp,
+ mode => $mode_gp,
reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
emit => '. or %S1, %R2I, %D1',
constructors => \%binop_operand_constructors,
Xor => {
irn_flags => [ "rematerializable" ],
- mode => $mode_gp,
+ mode => $mode_gp,
reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
emit => '. xor %S1, %R2I, %D1',
constructors => \%binop_operand_constructors,
},
Mul => {
- state => "exc_pinned",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp", "flags" ] },
- outs => [ "low", "high" ],
+ reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
constructors => \%binop_operand_constructors,
- #emit =>'. mul %S1, %R2I, %D1'
+ emit => '. mul %S1, %R2I, %D1',
+ mode => $mode_gp,
},
Mulh => {
- state => "exc_pinned",
reg_req => { in => [ "gp", "gp" ], out => [ "gp", "gp" ] },
outs => [ "low", "high" ],
constructors => \%binop_operand_constructors,
Div => {
irn_flags => [ "rematerializable" ],
state => "exc_pinned",
- reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
- outs => [ "res" ],
+ reg_req => { in => [ "gp", "gp" ], out => [ "gp", "none" ] },
+ outs => [ "res", "M" ],
constructors => \%binop_operand_constructors,
- #mode => $mode_gp,
- #emit =>'. div %S1, %R2I, %D1'
+ emit => '. div %S1, %R2I, %D1',
},
Minus => {
irn_flags => [ "rematerializable" ],
- mode => $mode_gp,
+ mode => $mode_gp,
reg_req => { in => [ "gp" ], out => [ "gp" ] },
emit => ". sub %%g0, %S1, %D1"
},
Not => {
- irn_flags => [ "rematerializable" ],
- mode => $mode_gp,
- reg_req => { in => [ "gp" ], out => [ "gp" ] },
- emit => '. xnor %S1, %%g0, %D1'
+ irn_flags => [ "rematerializable" ],
+ mode => $mode_gp,
+ reg_req => { in => [ "gp" ], out => [ "gp" ] },
+ emit => '. xnor %S1, %%g0, %D1'
},
Nop => {
emit => '. nop',
},
-fAdd => {
+fadd => {
op_flags => [ "commutative" ],
irn_flags => [ "rematerializable" ],
reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
- emit => '. fadd%FPM %S1, %S2, %D1'
+ emit => '. fadd%FPM %S1, %S2, %D1',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ mode => $mode_fp,
},
-fMul => {
- op_flags => [ "commutative" ],
+fsub => {
+ irn_flags => [ "rematerializable" ],
reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
- emit =>'. fmul%FPM %S1, %S2, %D1'
+ emit => '. fsub%FPM %S1, %S2, %D1',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ mode => $mode_fp,
},
-fsMuld => {
+fmul => {
+ irn_flags => [ "rematerializable" ],
op_flags => [ "commutative" ],
reg_req => { in => [ "fp", "fp" ], out => [ "fp" ] },
- emit =>'. fsmuld %S1, %S2, %D1'
+ emit =>'. fmul%FPM %S1, %S2, %D1',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ mode => $mode_fp,
},
-FsTOd => {
+fdiv => {
irn_flags => [ "rematerializable" ],
- reg_req => { in => [ "fp" ], out => [ "fp" ] },
- emit =>'. FsTOd %S1, %D1'
+ reg_req => { in => [ "fp", "fp" ], out => [ "fp", "none" ] },
+ emit => '. fdiv%FPM %S1, %S2, %D1',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ outs => [ "res", "M" ],
},
-FdTOs => {
+fneg => {
irn_flags => [ "rematerializable" ],
reg_req => { in => [ "fp" ], out => [ "fp" ] },
- emit =>'. FdTOs %S1, %D1'
+ emit => '. fneg%FPM %S1, %D1',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ mode => $mode_fp,
},
-FiTOs => {
+"fabs" => {
irn_flags => [ "rematerializable" ],
- reg_req => { in => [ "gp" ], out => [ "fp" ] },
- emit =>'. FiTOs %S1, %D1'
+ reg_req => { in => [ "fp" ], out => [ "fp" ] },
+ emit => '. fabs%FPM %S1, %D1',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ mode => $mode_fp,
},
-FiTOd => {
+fftof => {
irn_flags => [ "rematerializable" ],
- reg_req => { in => [ "gp" ], out => [ "fp" ] },
- emit =>'. FiTOd %S1, %D1'
+ reg_req => { in => [ "fp" ], out => [ "fp" ] },
+ emit => '. f%FCONVS.to%FCONVD %S1, %D1',
+ attr_type => "sparc_fp_conv_attr_t",
+ attr => "ir_mode *src_mode, ir_mode *dest_mode",
+ mode => $mode_fp,
},
-FsTOi => {
+fitof => {
irn_flags => [ "rematerializable" ],
- reg_req => { in => [ "fp" ], out => [ "gp" ] },
- emit =>'. FsTOi %S1, %D1'
+ reg_req => { in => [ "gp" ], out => [ "fp" ] },
+ emit => '. fito%FPM %S1, %D1',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ mode => $mode_fp,
},
-FdTOi => {
+fftoi => {
irn_flags => [ "rematerializable" ],
reg_req => { in => [ "fp" ], out => [ "gp" ] },
- emit =>'. FdTOi %S1, %D1'
+ emit => '. f%FPM.toi %S1, %D1',
+ attr_type => "sparc_fp_attr_t",
+ attr => "ir_mode *fp_mode",
+ mode => $mode_gp,
},
Ldf => {
}
}
-
/**
* Creates a possible DAG for a constant.
*/
return result;
}
-
/**
* Create a DAG constructing a given Const.
*
/**
* helper function for FP binop operations
*/
-static ir_node *gen_helper_binfpop(ir_node *node, new_binop_fp_func new_reg)
+static ir_node *gen_helper_binfpop(ir_node *node, ir_mode *mode,
+ new_binop_fp_func new_func)
{
ir_node *block = be_transform_node(get_nodes_block(node));
ir_node *op1 = get_binop_left(node);
- ir_node *new_op1;
+ ir_node *new_op1 = be_transform_node(op1);
ir_node *op2 = get_binop_right(node);
- ir_node *new_op2;
+ ir_node *new_op2 = be_transform_node(op2);
dbg_info *dbgi = get_irn_dbg_info(node);
- new_op2 = be_transform_node(op2);
- new_op1 = be_transform_node(op1);
- return new_reg(dbgi, block, new_op1, new_op2, get_irn_mode(node));
+ return new_func(dbgi, block, new_op1, new_op2, mode);
}
/**
{
ir_mode *mode = get_irn_mode(node);
- if (mode_is_float(mode))
- panic("FP not implemented yet");
+ if (mode_is_float(mode)) {
+ return gen_helper_binfpop(node, mode, new_bd_sparc_fadd);
+ }
return gen_helper_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, new_bd_sparc_Add_reg, new_bd_sparc_Add_imm);
}
-
/**
* Creates an sparc Sub.
*
static ir_node *gen_Sub(ir_node *node)
{
ir_mode *mode = get_irn_mode(node);
- if (mode_is_float(mode))
- panic("FP not implemented yet");
+
+ if (mode_is_float(mode)) {
+ return gen_helper_binfpop(node, mode, new_bd_sparc_fsub);
+ }
return gen_helper_binop(node, MATCH_SIZE_NEUTRAL, new_bd_sparc_Sub_reg, new_bd_sparc_Sub_imm);
}
-
/**
* Transforms a Load.
*
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *new_load = NULL;
- if (mode_is_float(mode))
- panic("SPARC: no fp implementation yet");
-
- new_load = new_bd_sparc_Ld(dbgi, block, new_ptr, new_mem, mode, NULL, 0, 0, false);
+ if (mode_is_float(mode)) {
+ new_load = new_bd_sparc_Ldf(dbgi, block, new_ptr, new_mem, mode, NULL, 0, 0, false);
+ } else {
+ new_load = new_bd_sparc_Ld(dbgi, block, new_ptr, new_mem, mode, NULL, 0, 0, false);
+ }
set_irn_pinned(new_load, get_irn_pinned(node));
return new_load;
}
-
-
/**
* Transforms a Store.
*
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *new_store = NULL;
- if (mode_is_float(mode))
- panic("SPARC: no fp implementation yet");
-
- new_store = new_bd_sparc_St(dbgi, block, new_ptr, new_val, new_mem, mode, NULL, 0, 0, false);
+ if (mode_is_float(mode)) {
+ new_store = new_bd_sparc_Stf(dbgi, block, new_ptr, new_val, new_mem, mode, NULL, 0, 0, false);
+ } else {
+ new_store = new_bd_sparc_St(dbgi, block, new_ptr, new_val, new_mem, mode, NULL, 0, 0, false);
+ }
+ set_irn_pinned(new_store, get_irn_pinned(node));
return new_store;
}
*
* @return the created sparc Mul node
*/
-static ir_node *gen_Mul(ir_node *node) {
- ir_mode *mode = get_irn_mode(node);
- ir_node *mul;
- ir_node *proj_res_low;
-
+static ir_node *gen_Mul(ir_node *node)
+{
+ ir_mode *mode = get_irn_mode(node);
if (mode_is_float(mode)) {
- mul = gen_helper_binfpop(node, new_bd_sparc_fMul);
- return mul;
+ return gen_helper_binfpop(node, mode, new_bd_sparc_fmul);
}
assert(mode_is_data(mode));
- mul = gen_helper_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, new_bd_sparc_Mul_reg, new_bd_sparc_Mul_imm);
- arch_irn_add_flags(mul, arch_irn_flags_modify_flags);
-
- proj_res_low = new_r_Proj(mul, mode_gp, pn_sparc_Mul_low);
- return proj_res_low;
+ return gen_helper_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL,
+ new_bd_sparc_Mul_reg, new_bd_sparc_Mul_imm);
}
/**
*
* @return the created sparc Mulh node
*/
-static ir_node *gen_Mulh(ir_node *node) {
+static ir_node *gen_Mulh(ir_node *node)
+{
ir_mode *mode = get_irn_mode(node);
ir_node *mul;
ir_node *proj_res_hi;
*
* @return the created sparc Div node
*/
-static ir_node *gen_Div(ir_node *node) {
-
- ir_mode *mode = get_irn_mode(node);
-
- ir_node *div;
-
- if (mode_is_float(mode))
- panic("FP not supported yet");
-
- //assert(mode_is_data(mode));
- div = gen_helper_binop(node, MATCH_SIZE_NEUTRAL, new_bd_sparc_Div_reg, new_bd_sparc_Div_imm);
- return div;
+static ir_node *gen_Div(ir_node *node)
+{
+ ir_mode *mode = get_Div_resmode(node);
+ assert(!mode_is_float(mode));
+ return gen_helper_binop(node, MATCH_SIZE_NEUTRAL, new_bd_sparc_Div_reg, new_bd_sparc_Div_imm);
}
+static ir_node *gen_Quot(ir_node *node)
+{
+ ir_mode *mode = get_Quot_resmode(node);
+ assert(mode_is_float(mode));
+ return gen_helper_binfpop(node, mode, new_bd_sparc_fdiv);
+}
/**
* transform abs node:
return gen_helper_binop(node, MATCH_SIZE_NEUTRAL, new_bd_sparc_Sra_reg, new_bd_sparc_Sra_imm);
}
-/****** TRANSFORM GENERAL BACKEND NODES ********/
-
/**
* Transforms a Minus node.
- *
*/
static ir_node *gen_Minus(ir_node *node)
{
- ir_node *block = be_transform_node(get_nodes_block(node));
- ir_node *op = get_Minus_op(node);
- ir_node *new_op = be_transform_node(op);
- dbg_info *dbgi = get_irn_dbg_info(node);
- ir_mode *mode = get_irn_mode(node);
+ ir_node *block = be_transform_node(get_nodes_block(node));
+ ir_node *op = get_Minus_op(node);
+ ir_node *new_op = be_transform_node(op);
+ dbg_info *dbgi = get_irn_dbg_info(node);
+ ir_mode *mode = get_irn_mode(node);
if (mode_is_float(mode)) {
- panic("FP not implemented yet");
+ return new_bd_sparc_fneg(dbgi, block, new_op, mode);
}
- assert(mode_is_data(mode));
return new_bd_sparc_Minus(dbgi, block, new_op);
}
return new_op;
}
-
/**
* SubSP
* @param node the ir SubSP node
if (mode_is_float(src_mode)) {
if (mode_is_float(dst_mode)) {
/* float -> float conv */
- if (src_bits > dst_bits) {
- return new_bd_sparc_FsTOd(dbg, block, new_op, dst_mode);
- } else {
- return new_bd_sparc_FdTOs(dbg, block, new_op, dst_mode);
- }
+ return new_bd_sparc_fftof(dbg, block, new_op, src_mode, dst_mode);
} else {
/* float -> int conv */
- switch (dst_bits) {
- case 32:
- return new_bd_sparc_FsTOi(dbg, block, new_op, dst_mode);
- case 64:
- return new_bd_sparc_FdTOi(dbg, block, new_op, dst_mode);
- default:
- panic("quad FP not implemented");
- }
+ if (!mode_is_signed(dst_mode))
+ panic("float to unsigned not implemented yet");
+ return new_bd_sparc_fftoi(dbg, block, new_op, src_mode);
}
} else {
/* int -> float conv */
- switch (dst_bits) {
- case 32:
- return new_bd_sparc_FiTOs(dbg, block, new_op, src_mode);
- case 64:
- return new_bd_sparc_FiTOd(dbg, block, new_op, src_mode);
- default:
- panic("quad FP not implemented");
- }
+ if (!mode_is_signed(src_mode))
+ panic("unsigned to float not implemented yet");
+ return new_bd_sparc_fitof(dbg, block, new_op, dst_mode);
}
} else { /* complete in gp registers */
int min_bits;
return phi;
}
-
/**
* Transform a Proj from a Load.
*/
ir_node *load = get_Proj_pred(node);
ir_node *new_load = be_transform_node(load);
dbg_info *dbgi = get_irn_dbg_info(node);
- long proj = get_Proj_proj(node);
+ long pn = get_Proj_proj(node);
/* renumber the proj */
switch (get_sparc_irn_opcode(new_load)) {
- case iro_sparc_Ld:
- /* handle all gp loads equal: they have the same proj numbers. */
- if (proj == pn_Load_res) {
- return new_rd_Proj(dbgi, new_load, mode_gp, pn_sparc_Ld_res);
- } else if (proj == pn_Load_M) {
- return new_rd_Proj(dbgi, new_load, mode_M, pn_sparc_Ld_M);
- }
- break;
- default:
- panic("Unsupported Proj from Load");
+ case iro_sparc_Ld:
+ /* handle all gp loads equal: they have the same proj numbers. */
+ if (pn == pn_Load_res) {
+ return new_rd_Proj(dbgi, new_load, mode_gp, pn_sparc_Ld_res);
+ } else if (pn == pn_Load_M) {
+ return new_rd_Proj(dbgi, new_load, mode_M, pn_sparc_Ld_M);
+ }
+ break;
+ case iro_sparc_Ldf:
+ if (pn == pn_Load_res) {
+ return new_rd_Proj(dbgi, new_load, mode_fp, pn_sparc_Ldf_res);
+ } else if (pn == pn_Load_M) {
+ return new_rd_Proj(dbgi, new_load, mode_M, pn_sparc_Ld_M);
+ }
+ break;
+ default:
+ break;
}
+ panic("Unsupported Proj from Load");
+}
- return be_duplicate_node(node);
+static ir_node *gen_Proj_Store(ir_node *node)
+{
+ ir_node *store = get_Proj_pred(node);
+ ir_node *new_store = be_transform_node(store);
+ long pn = get_Proj_proj(node);
+
+ /* renumber the proj */
+ switch (get_sparc_irn_opcode(new_store)) {
+ case iro_sparc_St:
+ if (pn == pn_Store_M) {
+ return new_store;
+ }
+ break;
+ case iro_sparc_Stf:
+ if (pn == pn_Store_M) {
+ return new_store;
+ }
+ break;
+ default:
+ break;
+ }
+ panic("Unsupported Proj from Store");
}
/**
{
ir_node *pred = get_Proj_pred(node);
ir_node *new_pred = be_transform_node(pred);
- long proj = get_Proj_proj(node);
+ long pn = get_Proj_proj(node);
- switch (proj) {
+ assert(is_sparc_Div(new_pred));
+ switch (pn) {
case pn_Div_res:
- if (is_sparc_Div(new_pred)) {
- return new_r_Proj(new_pred, mode_gp, pn_sparc_Div_res);
- }
- break;
+ return new_r_Proj(new_pred, mode_gp, pn_sparc_Div_res);
+ case pn_Div_M:
+ return new_r_Proj(new_pred, mode_gp, pn_sparc_Div_M);
default:
break;
}
panic("Unsupported Proj from Div");
}
+static ir_node *gen_Proj_Quot(ir_node *node)
+{
+ ir_node *pred = get_Proj_pred(node);
+ ir_node *new_pred = be_transform_node(pred);
+ long pn = get_Proj_proj(node);
+
+ assert(is_sparc_fdiv(new_pred));
+ switch (pn) {
+ case pn_Quot_res:
+ return new_r_Proj(new_pred, mode_gp, pn_sparc_fdiv_res);
+ case pn_Quot_M:
+ return new_r_Proj(new_pred, mode_gp, pn_sparc_fdiv_M);
+ default:
+ break;
+ }
+ panic("Unsupported Proj from Quot");
+}
+
static ir_node *gen_Proj_Start(ir_node *node)
{
ir_node *block = get_nodes_block(node);
static ir_node *gen_Proj(ir_node *node)
{
ir_node *pred = get_Proj_pred(node);
- long pn = get_Proj_proj(node);
switch (get_irn_opcode(pred)) {
case iro_Store:
- if (pn == pn_Store_M) {
- return be_transform_node(pred);
- } else {
- panic("Unsupported Proj from Store");
- }
- break;
+ return gen_Proj_Store(node);
case iro_Load:
return gen_Proj_Load(node);
case iro_Call:
return be_duplicate_node(node);
case iro_Div:
return gen_Proj_Div(node);
+ case iro_Quot:
+ return gen_Proj_Quot(node);
case iro_Start:
return gen_Proj_Start(node);
case iro_Proj: {
}
}
-
/**
* transform a Jmp
*/
be_set_transform_function(op_Or, gen_Or);
be_set_transform_function(op_Phi, gen_Phi);
be_set_transform_function(op_Proj, gen_Proj);
+ be_set_transform_function(op_Quot, gen_Quot);
be_set_transform_function(op_Return, gen_Return);
be_set_transform_function(op_Sel, gen_Sel);
be_set_transform_function(op_Shl, gen_Shl);