}
}
-
/**
* 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");
+static ir_node *gen_Div(ir_node *node)
+{
+ ir_mode *mode = get_Div_resmode(node);
+ ir_node *res;
- //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;
+ assert(!mode_is_float(mode));
+ if (mode_is_signed(mode)) {
+ res = gen_helper_binop(node, 0, new_bd_sparc_SDiv_reg,
+ new_bd_sparc_SDiv_imm);
+ } else {
+ res = gen_helper_binop(node, 0, new_bd_sparc_UDiv_reg,
+ new_bd_sparc_UDiv_imm);
+ }
+ return res;
}
+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
return new_bd_sparc_SwitchJmp(dbgi, block, sub, n_projs, get_Cond_default_proj(node) - translation);
}
-static bool is_cmp_unsigned(ir_node *b_value)
+static ir_mode *get_cmp_mode(ir_node *b_value)
{
ir_node *pred;
ir_node *op;
if (!is_Cmp(pred))
panic("can't determine cond signednes (no cmp)");
op = get_Cmp_left(pred);
- return !mode_is_signed(get_irn_mode(op));
+ return get_irn_mode(op);
}
/**
{
ir_node *selector = get_Cond_selector(node);
ir_mode *mode = get_irn_mode(selector);
+ ir_mode *cmp_mode;
ir_node *block;
ir_node *flag_node;
bool is_unsigned;
assert(is_Proj(selector));
assert(is_Cmp(get_Proj_pred(selector)));
+ cmp_mode = get_cmp_mode(selector);
+
block = be_transform_node(get_nodes_block(node));
dbgi = get_irn_dbg_info(node);
flag_node = be_transform_node(get_Proj_pred(selector));
pnc = get_Proj_proj(selector);
- is_unsigned = is_cmp_unsigned(selector);
- return new_bd_sparc_BXX(dbgi, block, flag_node, pnc, is_unsigned);
+ is_unsigned = !mode_is_signed(cmp_mode);
+ if (mode_is_float(cmp_mode)) {
+ assert(!is_unsigned);
+ return new_bd_sparc_fbfcc(dbgi, block, flag_node, pnc);
+ } else {
+ return new_bd_sparc_Bicc(dbgi, block, flag_node, pnc, is_unsigned);
+ }
}
/**
ir_node *op2 = get_Cmp_right(node);
ir_mode *cmp_mode = get_irn_mode(op1);
dbg_info *dbgi = get_irn_dbg_info(node);
- ir_node *new_op1;
- ir_node *new_op2;
-
- if (mode_is_float(cmp_mode)) {
- panic("FloatCmp not implemented");
- }
-
- /*
- if (get_mode_size_bits(cmp_mode) != 32) {
- panic("CmpMode != 32bit not supported yet");
- }
- */
-
+ ir_node *new_op1 = be_transform_node(op1);
+ ir_node *new_op2 = be_transform_node(op2);
assert(get_irn_mode(op2) == cmp_mode);
- /* compare with 0 can be done with Tst */
- /*
- if (is_Const(op2) && tarval_is_null(get_Const_tarval(op2))) {
- new_op1 = be_transform_node(op1);
- return new_bd_sparc_Tst(dbgi, block, new_op1, false,
- is_unsigned);
- }
-
- if (is_Const(op1) && tarval_is_null(get_Const_tarval(op1))) {
- new_op2 = be_transform_node(op2);
- return new_bd_sparc_Tst(dbgi, block, new_op2, true,
- is_unsigned);
+ if (mode_is_float(cmp_mode)) {
+ return new_bd_sparc_fcmp(dbgi, block, new_op1, new_op2, cmp_mode);
}
- */
/* integer compare */
- new_op1 = be_transform_node(op1);
new_op1 = gen_extension(dbgi, block, new_op1, cmp_mode);
- new_op2 = be_transform_node(op2);
new_op2 = gen_extension(dbgi, block, new_op2, cmp_mode);
return new_bd_sparc_Cmp_reg(dbgi, block, new_op1, new_op2);
}
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_SDiv(new_pred) || is_sparc_UDiv(new_pred));
+ assert(pn_sparc_SDiv_res == pn_sparc_UDiv_res);
+ assert(pn_sparc_SDiv_M == pn_sparc_UDiv_M);
+ 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_SDiv_res);
+ case pn_Div_M:
+ return new_r_Proj(new_pred, mode_gp, pn_sparc_SDiv_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);