-"Sub" => {
- "irn_flags" => "R",
- "comment" => "construct Sub: Sub(a, b) = a - b",
- "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. sub %ia32_emit_binop /* Sub(%A3, %A4) -> %D1 */',
- "outs" => [ "res", "M" ],
-},
-
-"SubC" => {
- "comment" => "construct Sub with Carry: SubC(a, b) = a - b - carry",
- "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. sbb %ia32_emit_binop /* SubC(%A3, %A4) -> %D1 */',
- "outs" => [ "res", "M" ],
-},
-
-"l_Sub" => {
- "irn_flags" => "R",
- "cmp_attr" => " return 1;\n",
- "comment" => "construct lowered Sub: Sub(a, b) = a - b",
- "arity" => 2,
-},
-
-"l_SubC" => {
- "cmp_attr" => " return 1;\n",
- "comment" => "construct lowered Sub with Carry: SubC(a, b) = a - b - carry",
- "arity" => 2,
-},
-
-"DivMod" => {
- "op_flags" => "F|L",
- "state" => "exc_pinned",
- "reg_req" => { "in" => [ "eax", "gp", "edx", "none" ], "out" => [ "eax", "edx" ] },
- "attr" => "ia32_op_flavour_t dm_flav",
- "init_attr" => " attr->data.op_flav = dm_flav;",
- "cmp_attr" => " return attr_a->data.op_flav != attr_b->data.op_flav;\n",
- "emit" =>
-' if (mode_is_signed(get_ia32_res_mode(n))) {
-4. idiv %S2 /* signed DivMod(%S1, %S2) -> %D1, (%A1, %A2, %A3) */
- }
- else {
-4. div %S2 /* unsigned DivMod(%S1, %S2) -> %D1, (%A1, %A2, %A3) */
- }
-',
- "outs" => [ "div_res", "mod_res", "M" ],
-},
-
-"Shl" => {
- "irn_flags" => "R",
- "comment" => "construct Shl: Shl(a, b) = a << b",
- "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
- "emit" => '. shl %ia32_emit_binop /* Shl(%A1, %A2) -> %D1 */',
- "outs" => [ "res", "M" ],
-},
-
-"l_Shl" => {
- "cmp_attr" => " return 1;\n",
- "comment" => "construct lowered Shl: Shl(a, b) = a << b",
- "arity" => 2
-},
-
-"ShlD" => {
- "irn_flags" => "R",
- "comment" => "construct ShlD: ShlD(a, b, c) = a, b << count (shift left count bits from b into a)",
- "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r5" ] },
- "emit" =>
-'
-if (get_ia32_immop_type(n) == ia32_ImmNone) {
- if (get_ia32_op_type(n) == ia32_AddrModeD) {
-4. shld %ia32_emit_am, %S4, %%cl /* ShlD(%A3, %A4, %A5) -> %D1 */
- }
- else {
-4. shld %S3, %S4, %%cl /* ShlD(%A3, %A4, %A5) -> %D1 */
- }
-}
-else {
- if (get_ia32_op_type(n) == ia32_AddrModeD) {
-4. shld %ia32_emit_am, %S4, %C /* ShlD(%A3, %A4, %A5) -> %D1 */
- }
- else {
-4. shld %S3, %S4, %C /* ShlD(%A3, %A4, %A5) -> %D1 */
- }
-}
-',
- "outs" => [ "res", "M" ],
-},
-
-"l_ShlD" => {
- "cmp_attr" => " return 1;\n",
- "comment" => "construct lowered ShlD: ShlD(a, b, c) = a, b << count (shift left count bits from b into a)",
- "arity" => 3
-},
-
-"Shr" => {
- "irn_flags" => "R",
- "comment" => "construct Shr: Shr(a, b) = a >> b",
- "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
- "emit" => '. shr %ia32_emit_binop /* Shr(%A1, %A2) -> %D1 */',
- "outs" => [ "res", "M" ],
-},
-
-"l_Shr" => {
- "cmp_attr" => " return 1;\n",
- "comment" => "construct lowered Shr: Shr(a, b) = a << b",
- "arity" => 2
-},
-
-"ShrD" => {
- "irn_flags" => "R",
- "comment" => "construct ShrD: ShrD(a, b, c) = a, b >> count (shift rigth count bits from a into b)",
- "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r5" ] },
- "emit" =>
-'
-if (get_ia32_immop_type(n) == ia32_ImmNone) {
- if (get_ia32_op_type(n) == ia32_AddrModeD) {
-4. shrd %ia32_emit_am, %S4, %%cl /* ShrD(%A3, %A4, %A5) -> %D1 */
- }
- else {
-4. shrd %S3, %S4, %%cl /* ShrD(%A3, %A4, %A5) -> %D1 */
- }
-}
-else {
- if (get_ia32_op_type(n) == ia32_AddrModeD) {
-4. shrd %ia32_emit_am, %S4, %C /* ShrD(%A3, %A4, %A5) -> %D1 */
- }
- else {
-4. shrd %S3, %S4, %C /* ShrD(%A3, %A4, %A5) -> %D1 */
- }
-}
-',
- "outs" => [ "res", "M" ],
-},
-
-"l_ShrD" => {
- "cmp_attr" => " return 1;\n",
- "comment" => "construct lowered ShrD: ShrD(a, b, c) = a, b >> count (shift rigth count bits from a into b)",
- "arity" => 3
-},
-
-"Shrs" => {
- "irn_flags" => "R",
- "comment" => "construct Shrs: Shrs(a, b) = a >> b",
- "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
- "emit" => '. sar %ia32_emit_binop /* Shrs(%A1, %A2) -> %D1 */',
- "outs" => [ "res", "M" ],
-},
-
-"l_Shrs" => {
- "cmp_attr" => " return 1;\n",
- "comment" => "construct lowered Shrs: Shrs(a, b) = a << b",
- "arity" => 2
-},
-
-"RotR" => {
- "irn_flags" => "R",
- "comment" => "construct RotR: RotR(a, b) = a ROTR b",
- "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
- "emit" => '. ror %ia32_emit_binop /* RotR(%A1, %A2) -> %D1 */',
- "outs" => [ "res", "M" ],
-},
-
-"RotL" => {
- "irn_flags" => "R",
- "comment" => "construct RotL: RotL(a, b) = a ROTL b",
- "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
- "emit" => '. rol %ia32_emit_binop /* RotL(%A1, %A2) -> %D1 */',
- "outs" => [ "res", "M" ],
+Sub => {
+ irn_flags => "R",
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ],
+ out => [ "in_r4", "flags", "none" ] },
+ ins => [ "base", "index", "mem", "minuend", "subtrahend" ],
+ outs => [ "res", "flags", "M" ],
+ am => "source,binary",
+ emit => '. sub%M %binop',
+ units => [ "GP" ],
+ latency => 1,
+ mode => $mode_gp,
+ modified_flags => $status_flags
+},
+
+SubMem => {
+ irn_flags => "R",
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
+ ins => [ "base", "index", "mem", "subtrahend" ],
+ emit => '. sub%M %SI3, %AM',
+ units => [ "GP" ],
+ latency => 1,
+ mode => 'mode_M',
+ modified_flags => $status_flags
+},
+
+SubMem8Bit => {
+ irn_flags => "R",
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
+ ins => [ "base", "index", "mem", "subtrahend" ],
+ emit => '. sub%M %SB3, %AM',
+ units => [ "GP" ],
+ latency => 1,
+ mode => 'mode_M',
+ modified_flags => $status_flags
+},
+
+Sbb => {
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "gp", "gp", "flags" ],
+ out => [ "in_r4 !in_r5", "flags", "none" ] },
+ ins => [ "base", "index", "mem", "minuend", "subtrahend", "eflags" ],
+ outs => [ "res", "flags", "M" ],
+ am => "source,binary",
+ emit => '. sbb%M %binop',
+ units => [ "GP" ],
+ latency => 1,
+ mode => $mode_gp,
+ modified_flags => $status_flags
+},
+
+l_Sub => {
+ reg_req => { in => [ "none", "none" ], out => [ "none" ] },
+ ins => [ "minuend", "subtrahend" ],
+},
+
+l_Sbb => {
+ reg_req => { in => [ "none", "none", "none" ], out => [ "none" ] },
+ ins => [ "minuend", "subtrahend", "eflags" ],
+},
+
+IDiv => {
+ op_flags => "F|L",
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
+ out => [ "eax", "flags", "none", "edx", "none" ] },
+ ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
+ outs => [ "div_res", "flags", "M", "mod_res", "X_exc" ],
+ am => "source,unary",
+ emit => ". idiv%M %unop3",
+ latency => 25,
+ units => [ "GP" ],
+ modified_flags => $status_flags
+},
+
+Div => {
+ op_flags => "F|L",
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "gp", "eax", "edx" ],
+ out => [ "eax", "flags", "none", "edx", "none" ] },
+ ins => [ "base", "index", "mem", "divisor", "dividend_low", "dividend_high" ],
+ outs => [ "div_res", "flags", "M", "mod_res", "X_exc" ],
+ am => "source,unary",
+ emit => ". div%M %unop3",
+ latency => 25,
+ units => [ "GP" ],
+ modified_flags => $status_flags
+},
+
+Shl => {
+ irn_flags => "R",
+ reg_req => { in => [ "gp", "ecx" ],
+ out => [ "in_r1 !in_r2", "flags" ] },
+ ins => [ "val", "count" ],
+ outs => [ "res", "flags" ],
+ emit => '. shl %SB1, %S0',
+ units => [ "GP" ],
+ latency => 1,
+ mode => $mode_gp,
+ modified_flags => $status_flags
+},
+
+ShlMem => {
+ irn_flags => "R",
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
+ ins => [ "base", "index", "mem", "count" ],
+ emit => '. shl%M %SB3, %AM',
+ units => [ "GP" ],
+ latency => 1,
+ mode => "mode_M",
+ modified_flags => $status_flags
+},
+
+l_ShlDep => {
+ cmp_attr => "return 1;",
+ ins => [ "val", "count", "dep" ],
+ arity => 3
+},
+
+ShlD => {
+ irn_flags => "R",
+ reg_req => { in => [ "gp", "gp", "ecx" ],
+ out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
+ ins => [ "val_high", "val_low", "count" ],
+ outs => [ "res", "flags" ],
+ emit => ". shld%M %SB2, %S1, %D0",
+ latency => 6,
+ units => [ "GP" ],
+ mode => $mode_gp,
+ modified_flags => $status_flags
+},
+
+l_ShlD => {
+ cmp_attr => "return 1;",
+ ins => [ "val_high", "val_low", "count" ],
+ arity => 3,
+},
+
+Shr => {
+ irn_flags => "R",
+ reg_req => { in => [ "gp", "ecx" ],
+ out => [ "in_r1 !in_r2", "flags" ] },
+ ins => [ "val", "count" ],
+ outs => [ "res", "flags" ],
+ emit => '. shr %SB1, %S0',
+ units => [ "GP" ],
+ mode => $mode_gp,
+ latency => 1,
+ modified_flags => $status_flags
+},
+
+ShrMem => {
+ irn_flags => "R",
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
+ ins => [ "base", "index", "mem", "count" ],
+ emit => '. shr%M %SB3, %AM',
+ units => [ "GP" ],
+ mode => "mode_M",
+ latency => 1,
+ modified_flags => $status_flags
+},
+
+l_ShrDep => {
+ cmp_attr => "return 1;",
+ ins => [ "val", "count", "dep" ],
+ arity => 3
+},
+
+ShrD => {
+ irn_flags => "R",
+ reg_req => { in => [ "gp", "gp", "ecx" ],
+ out => [ "in_r1 !in_r2 !in_r3", "flags" ] },
+ ins => [ "val_high", "val_low", "count" ],
+ outs => [ "res", "flags" ],
+ emit => ". shrd%M %SB2, %S1, %D0",
+ latency => 6,
+ units => [ "GP" ],
+ mode => $mode_gp,
+ modified_flags => $status_flags
+},
+
+l_ShrD => {
+ cmp_attr => "return 1;",
+ arity => 3,
+ ins => [ "val_high", "val_low", "count" ],
+},
+
+Sar => {
+ irn_flags => "R",
+ reg_req => { in => [ "gp", "ecx" ],
+ out => [ "in_r1 !in_r2", "flags" ] },
+ ins => [ "val", "count" ],
+ outs => [ "res", "flags" ],
+ emit => '. sar %SB1, %S0',
+ units => [ "GP" ],
+ latency => 1,
+ mode => $mode_gp,
+ modified_flags => $status_flags
+},
+
+SarMem => {
+ irn_flags => "R",
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
+ ins => [ "base", "index", "mem", "count" ],
+ emit => '. sar%M %SB3, %AM',
+ units => [ "GP" ],
+ latency => 1,
+ mode => "mode_M",
+ modified_flags => $status_flags
+},
+
+l_SarDep => {
+ cmp_attr => "return 1;",
+ ins => [ "val", "count", "dep" ],
+ arity => 3
+},
+
+Ror => {
+ irn_flags => "R",
+ reg_req => { in => [ "gp", "ecx" ],
+ out => [ "in_r1 !in_r2", "flags" ] },
+ ins => [ "val", "count" ],
+ outs => [ "res", "flags" ],
+ emit => '. ror %SB1, %S0',
+ units => [ "GP" ],
+ latency => 1,
+ mode => $mode_gp,
+ modified_flags => $status_flags
+},
+
+RorMem => {
+ irn_flags => "R",
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
+ ins => [ "base", "index", "mem", "count" ],
+ emit => '. ror%M %SB3, %AM',
+ units => [ "GP" ],
+ latency => 1,
+ mode => "mode_M",
+ modified_flags => $status_flags
+},
+
+Rol => {
+ irn_flags => "R",
+ reg_req => { in => [ "gp", "ecx" ],
+ out => [ "in_r1 !in_r2", "flags" ] },
+ ins => [ "val", "count" ],
+ outs => [ "res", "flags" ],
+ emit => '. rol %SB1, %S0',
+ units => [ "GP" ],
+ latency => 1,
+ mode => $mode_gp,
+ modified_flags => $status_flags
+},
+
+RolMem => {
+ irn_flags => "R",
+ state => "exc_pinned",
+ reg_req => { in => [ "gp", "gp", "none", "ecx" ], out => [ "none" ] },
+ ins => [ "base", "index", "mem", "count" ],
+ emit => '. rol%M %SB3, %AM',
+ units => [ "GP" ],
+ latency => 1,
+ mode => "mode_M",
+ modified_flags => $status_flags