From: Michael Beck Date: Fri, 18 Jan 2008 10:45:16 +0000 (+0000) Subject: more support for exceptions added X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=180f84a1ee29292ad83809121983bf5ab4a2dc42;p=libfirm more support for exceptions added [r17432] --- diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index c669fcbc7..372c59362 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -679,9 +679,9 @@ IDiv => { op_flags => "F|L", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax", "edx", "gp" ], - out => [ "eax", "flags", "none", "edx" ] }, + out => [ "eax", "flags", "none", "edx", "none" ] }, ins => [ "base", "index", "mem", "left_low", "left_high", "right" ], - outs => [ "div_res", "flags", "M", "mod_res" ], + outs => [ "div_res", "flags", "M", "mod_res", "X_exc" ], am => "source,ternary", emit => ". idiv%M %unop5", latency => 25, @@ -693,9 +693,9 @@ Div => { op_flags => "F|L", state => "exc_pinned", reg_req => { in => [ "gp", "gp", "none", "eax", "edx", "gp" ], - out => [ "eax", "flags", "none", "edx" ] }, + out => [ "eax", "flags", "none", "edx", "none" ] }, ins => [ "base", "index", "mem", "left_low", "left_high", "right" ], - outs => [ "div_res", "flags", "M", "mod_res" ], + outs => [ "div_res", "flags", "M", "mod_res", "X_exc" ], am => "source,ternary", emit => ". div%M %unop5", latency => 25, @@ -1304,9 +1304,9 @@ Cltd => { Load => { op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none" ], out => [ "gp", "none" ] }, + reg_req => { in => [ "gp", "gp", "none" ], out => [ "gp", "none", "none" ] }, ins => [ "base", "index", "mem" ], - outs => [ "res", "M" ], + outs => [ "res", "M", "X_exc" ], latency => 0, emit => ". mov%SE%ME%.l %AM, %D0", units => [ "GP" ], @@ -1330,8 +1330,9 @@ l_Store => { Store => { op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] }, + reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], + outs => [ "M", "X_exc" ], emit => '. mov%M %SI3, %AM', latency => 2, units => [ "GP" ], @@ -1341,8 +1342,9 @@ Store => { Store8Bit => { op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => ["none" ] }, + reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => ["none", "none" ] }, ins => [ "base", "index", "mem", "val" ], + outs => [ "M", "X_exc" ], emit => '. mov%M %SB3, %AM', latency => 2, units => [ "GP" ], @@ -1600,12 +1602,12 @@ Ucomi => { xLoad => { op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none" ], out => [ "xmm", "none" ] }, + reg_req => { in => [ "gp", "gp", "none" ], out => [ "xmm", "none", "none" ] }, ins => [ "base", "index", "mem" ], + outs => [ "res", "M", "X_exc" ], emit => '. mov%XXM %AM, %D0', attr => "ir_mode *load_mode", init_attr => "attr->ls_mode = load_mode;", - outs => [ "res", "M" ], latency => 0, units => [ "SSE" ], }, @@ -1613,8 +1615,9 @@ xLoad => { xStore => { op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "xmm" ] }, + reg_req => { in => [ "gp", "gp", "none", "xmm" ], out => [ "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], + outs => [ "M", "X_exc" ], emit => '. mov%XXM %S3, %AM', latency => 0, units => [ "SSE" ], @@ -1853,9 +1856,9 @@ vfld => { irn_flags => "R", op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none" ] }, + reg_req => { in => [ "gp", "gp", "none" ], out => [ "vfp", "none", "none" ] }, ins => [ "base", "index", "mem" ], - outs => [ "res", "M" ], + outs => [ "res", "M", "X_exc" ], attr => "ir_mode *load_mode", init_attr => "attr->attr.ls_mode = load_mode;", latency => 2, @@ -1867,8 +1870,9 @@ vfst => { irn_flags => "R", op_flags => "L|F", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "vfp" ] }, + reg_req => { in => [ "gp", "gp", "none", "vfp" ], out => [ "none", "none" ] }, ins => [ "base", "index", "mem", "val" ], + outs => [ "M", "X_exc" ], attr => "ir_mode *store_mode", init_attr => "attr->attr.ls_mode = store_mode;", latency => 2, diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index cceca5141..f1ca54c62 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -1340,33 +1340,28 @@ static ir_node *create_Div(ir_node *node) ir_node *new_node; ir_mode *mode; ir_node *sign_extension; - int has_exc; ia32_address_mode_t am; ia32_address_t *addr = &am.addr; /* the upper bits have random contents for smaller modes */ - has_exc = 0; switch (get_irn_opcode(node)) { case iro_Div: op1 = get_Div_left(node); op2 = get_Div_right(node); mem = get_Div_mem(node); mode = get_Div_resmode(node); - has_exc = be_get_Proj_for_pn(node, pn_Div_X_except) != NULL; break; case iro_Mod: op1 = get_Mod_left(node); op2 = get_Mod_right(node); mem = get_Mod_mem(node); mode = get_Mod_resmode(node); - has_exc = be_get_Proj_for_pn(node, pn_Mod_X_except) != NULL; break; case iro_DivMod: op1 = get_DivMod_left(node); op2 = get_DivMod_right(node); mem = get_DivMod_mem(node); mode = get_DivMod_resmode(node); - has_exc = be_get_Proj_for_pn(node, pn_DivMod_X_except) != NULL; break; default: panic("invalid divmod node %+F", node); @@ -1404,7 +1399,6 @@ static ir_node *create_Div(ir_node *node) sign_extension, am.new_op2); } - set_ia32_exc_label(new_node, has_exc); set_irn_pinned(new_node, get_irn_pinned(node)); set_am_attributes(new_node, &am); @@ -1850,8 +1844,6 @@ static ir_node *gen_Load(ir_node *node) { add_irn_dep(new_node, get_irg_frame(irg)); } - set_ia32_exc_label(new_node, - be_get_Proj_for_pn(node, pn_Load_X_except) != NULL); SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node)); return new_node; @@ -2271,8 +2263,6 @@ static ir_node *gen_Store(ir_node *node) set_ia32_op_type(new_node, ia32_AddrModeD); set_ia32_ls_mode(new_node, mode); - set_ia32_exc_label(new_node, - be_get_Proj_for_pn(node, pn_Store_X_except) != NULL); set_address(new_node, &addr); SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node)); @@ -4321,15 +4311,22 @@ static ir_node *gen_Proj_Load(ir_node *node) { /* renumber the proj */ new_pred = be_transform_node(pred); if (is_ia32_Load(new_pred)) { - if (proj == pn_Load_res) { - return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, - pn_ia32_Load_res); - } else if (proj == pn_Load_M) { - return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, - pn_ia32_Load_M); + switch (proj) { + case pn_Load_res: + return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res); + case pn_Load_M: + return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M); + case pn_Load_X_regular: + return new_rd_Jmp(dbgi, irg, block); + case pn_Load_X_except: + /* This Load might raise an exception. Mark it. */ + set_ia32_exc_label(new_pred, 1); + return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc); + default: + break; } - } else if(is_ia32_Conv_I2I(new_pred) - || is_ia32_Conv_I2I8Bit(new_pred)) { + } else if (is_ia32_Conv_I2I(new_pred) || + is_ia32_Conv_I2I8Bit(new_pred)) { set_irn_mode(new_pred, mode_T); if (proj == pn_Load_res) { return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res); @@ -4337,20 +4334,34 @@ static ir_node *gen_Proj_Load(ir_node *node) { return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem); } } else if (is_ia32_xLoad(new_pred)) { - if (proj == pn_Load_res) { - return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, - pn_ia32_xLoad_res); - } else if (proj == pn_Load_M) { - return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, - pn_ia32_xLoad_M); + switch (proj) { + case pn_Load_res: + return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res); + case pn_Load_M: + return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M); + case pn_Load_X_regular: + return new_rd_Jmp(dbgi, irg, block); + case pn_Load_X_except: + /* This Load might raise an exception. Mark it. */ + set_ia32_exc_label(new_pred, 1); + return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc); + default: + break; } } else if (is_ia32_vfld(new_pred)) { - if (proj == pn_Load_res) { - return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, - pn_ia32_vfld_res); - } else if (proj == pn_Load_M) { - return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, - pn_ia32_vfld_M); + switch (proj) { + case pn_Load_res: + return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res); + case pn_Load_M: + return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M); + case pn_Load_X_regular: + return new_rd_Jmp(dbgi, irg, block); + case pn_Load_X_except: + /* This Load might raise an exception. Mark it. */ + set_ia32_exc_label(new_pred, 1); + return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc); + default: + break; } } else { /* can happen for ProJMs when source address mode happened for the @@ -4359,7 +4370,7 @@ static ir_node *gen_Proj_Load(ir_node *node) { /* however it should not be the result proj, as that would mean the load had multiple users and should not have been used for SourceAM */ - if(proj != pn_Load_M) { + if (proj != pn_Load_M) { panic("internal error: transformed node not a Load"); } return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1); @@ -4390,6 +4401,11 @@ static ir_node *gen_Proj_DivMod(ir_node *node) { return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M); case pn_Div_res: return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res); + case pn_Div_X_regular: + return new_rd_Jmp(dbgi, irg, block); + case pn_Div_X_except: + set_ia32_exc_label(new_pred, 1); + return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc); default: break; } @@ -4400,6 +4416,9 @@ static ir_node *gen_Proj_DivMod(ir_node *node) { return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M); case pn_Mod_res: return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res); + case pn_Mod_X_except: + set_ia32_exc_label(new_pred, 1); + return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc); default: break; } @@ -4412,6 +4431,11 @@ static ir_node *gen_Proj_DivMod(ir_node *node) { return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res); case pn_DivMod_res_mod: return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res); + case pn_DivMod_X_regular: + return new_rd_Jmp(dbgi, irg, block); + case pn_DivMod_X_except: + set_ia32_exc_label(new_pred, 1); + return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc); default: break; }