"comment" => "construct Add: Add(a, b) = Add(b, a) = 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" => '. add %ia32_emit_binop /* Add(%A1, %A2) -> %D1 */',
+ "emit" => '. add %ia32_emit_binop /* Add(%A3, %A4) -> %D1 */',
"outs" => [ "res", "M" ],
},
+"AddC" => {
+ "comment" => "construct Add with Carry: AddC(a, b) = Add(b, a) = 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" => '. adc %ia32_emit_binop /* AddC(%A3, %A4) -> %D1 */',
+ "outs" => [ "res", "M" ],
+},
+
+"l_Add" => {
+ "op_flags" => "C",
+ "irn_flags" => "R",
+ "comment" => "construct lowered Add: Add(a, b) = Add(b, a) = a + b",
+ "arity" => 2,
+},
+
+"l_AddC" => {
+ "op_flags" => "C",
+ "comment" => "construct lowered Add with Carry: AddC(a, b) = Add(b, a) = a + b + carry",
+ "arity" => 2,
+},
+
+"MulS" => {
+ "comment" => "construct MulS: MulS(a, b) = MulS(b, a) = a * b",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "eax in_r3", "edx in_r4" ] },
+ "emit" => '. mul %ia32_emit_binop /* Mul(%A1, %A2) -> %D1 */',
+ "outs" => [ "EAX", "EDX", "M" ],
+},
+
+"l_MulS" => {
+ "op_flags" => "C",
+ "comment" => "construct lowered MulS: MulS(a, b) = MulS(b, a) = a * b",
+ "outs" => [ "EAX", "EDX", "M" ],
+ "arity" => 2
+},
+
"Mul" => {
"irn_flags" => "R",
"comment" => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
"outs" => [ "res", "M" ],
},
+"l_Mul" => {
+ "op_flags" => "C",
+ "comment" => "construct lowered Mul: Mul(a, b) = Mul(b, a) = a * b",
+ "arity" => 2
+},
+
# Mulh is an exception from the 4 INs with AM because the target is always EAX:EDX
"Mulh" => {
"comment" => "construct Mul: Mul(a, b) = Mul(b, a) = a * b",
"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(%A1, %A2) -> %D1 */',
+ "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",
+ "comment" => "construct lowered Sub: Sub(a, b) = a - b",
+ "arity" => 2,
+},
+
+"l_SubC" => {
+ "comment" => "construct lowered Sub with Carry: SubC(a, b) = a - b - carry",
+ "arity" => 2,
+},
+
"DivMod" => {
"op_flags" => "F|L",
"state" => "exc_pinned",
"outs" => [ "res", "M" ],
},
+"l_Shl" => {
+ "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" => {
+ "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",
"outs" => [ "res", "M" ],
},
+"l_Shr" => {
+ "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" => {
+ "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",
"outs" => [ "res", "M" ],
},
+"l_Shrs" => {
+ "comment" => "construct lowered Shrs: Shrs(a, b) = a << b",
+ "arity" => 2
+},
+
"RotR" => {
"irn_flags" => "R",
"comment" => "construct RotR: RotR(a, b) = a ROTR b",
"outs" => [ "res", "M" ],
},
+"l_Minus" => {
+ "comment" => "construct lowered Minus: Minus(a) = -a",
+ "arity" => 1,
+},
+
"Inc" => {
"irn_flags" => "R",
"comment" => "construct Increment: Inc(a) = a++",
"outs" => [ "res", "M" ],
},
-"CMov" => {
+"CmpCMov" => {
"irn_flags" => "R",
"comment" => "construct Conditional Move: CMov(sel, a, b) == sel ? a : b",
"reg_req" => { "in" => [ "gp", "gp", "gp", "gp" ], "out" => [ "in_r4" ] }
},
+"PsiCondCMov" => {
+ "irn_flags" => "R",
+ "comment" => "check if Psi condition tree evaluates to true and move result accordingly",
+ "reg_req" => { "in" => [ "gp", "gp", "gp" ], "out" => [ "in_r3" ] }
+},
+
"xCmpCMov" => {
"irn_flags" => "R",
"comment" => "construct Conditional Move: SSE Compare + int CMov ",
"reg_req" => { "in" => [ "vfp", "vfp", "gp", "gp" ], "out" => [ "in_r4" ] }
},
-"Set" => {
+"CmpSet" => {
"irn_flags" => "R",
"comment" => "construct Set: Set(sel) == sel ? 1 : 0",
- "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "eax ebx ecx edx" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "eax ebx ecx edx", "none" ] },
+ "outs" => [ "res", "M" ],
+},
+
+"PsiCondSet" => {
+ "irn_flags" => "R",
+ "comment" => "check if Psi condition tree evaluates to true and set result accordingly",
+ "reg_req" => { "in" => [ "gp" ], "out" => [ "eax ebx ecx edx" ] },
},
"xCmpSet" => {
"irn_flags" => "R",
"comment" => "construct Set: SSE Compare + int Set",
- "reg_req" => { "in" => [ "xmm", "xmm" ], "out" => [ "eax ebx ecx edx" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "eax ebx ecx edx", "none" ] },
+ "outs" => [ "res", "M" ],
},
"vfCmpSet" => {
"irn_flags" => "R",
"comment" => "construct Set: x87 Compare + int Set",
- "reg_req" => { "in" => [ "vfp", "vfp" ], "out" => [ "eax ebx ecx edx" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "eax ebx ecx edx", "none" ] },
+ "outs" => [ "res", "M" ],
},
"vfCMov" => {