"irn_flags" => "R",
"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_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. add %ia32_emit_binop\t\t\t/* Add(%A1, %A2) -> %D1 */'
},
"irn_flags" => "A",
"comment" => "construct Mul: Mul(a, b) = Mul(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_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. imul %ia32_emit_binop\t\t\t/* Mul(%A1, %A2) -> %D1 */'
},
"Mulh" => {
"comment" => "construct Mul: Mul(a, b) = Mul(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_r1", "edx in_r2" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "eax in_r3", "edx in_r4" ] },
"emit" => '. imul %ia32_emit_unop\t\t\t/* Mulh(%A1, %A2) -> %D1 */ '
},
"irn_flags" => "R",
"comment" => "construct And: And(a, b) = And(b, a) = a AND b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. and %ia32_emit_binop\t\t\t/* And(%A1, %A2) -> %D1 */'
},
"irn_flags" => "R",
"comment" => "construct Or: Or(a, b) = Or(b, a) = a OR b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. or %ia32_emit_binop\t\t\t/* Or(%A1, %A2) -> %D1 */'
},
"irn_flags" => "R",
"comment" => "construct Eor: Eor(a, b) = Eor(b, a) = a EOR b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. xor %ia32_emit_binop\t\t\t/* Xor(%A1, %A2) -> %D1 */'
},
"CMov" => {
"irn_flags" => "R",
"comment" => "construct Mux: Mux(sel, a, b) == sel ? a : b",
- "reg_req" => { "in" => [ "gp", "gp", "gp" ], "out" => [ "in_r2" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp" ], "out" => [ "in_r2 !in_r3" ] },
"emit" =>
'. cmp %S1, 0\t\t\t/* compare Sel for CMov (%A2, %A3) */
. cmovne %D1, %S3\t\t\t/* sel == true -> return %S3 */
"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_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. sub %ia32_emit_binop\t\t\t/* Sub(%A1, %A2) -> %D1 */'
},
"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_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. shl %ia32_emit_binop\t\t\t/* Shl(%A1, %A2) -> %D1 */'
},
"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_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. shr %ia32_emit_binop\t\t\t/* Shr(%A1, %A2) -> %D1 */'
},
"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_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. sar %ia32_emit_binop\t\t\t/* Shrs(%A1, %A2) -> %D1 */'
},
"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_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. ror %ia32_emit_binop\t\t\t/* RotR(%A1, %A2) -> %D1 */'
},
"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_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "ecx", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. rol %ia32_emit_binop\t\t\t/* RotL(%A1, %A2) -> %D1 */'
},
"irn_flags" => "R",
"comment" => "construct Minus: Minus(a) = -a",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. neg %ia32_emit_unop\t\t\t/* Neg(%A1) -> %D1, (%A1) */'
},
"irn_flags" => "R",
"comment" => "construct Increment: Inc(a) = a++",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. inc %ia32_emit_unop\t\t\t/* Inc(%S1) -> %D1, (%A1) */'
},
"irn_flags" => "R",
"comment" => "construct Decrement: Dec(a) = a--",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. dec %ia32_emit_unop\t\t\t/* Dec(%S1) -> %D1, (%A1) */'
},
"irn_flags" => "R",
"comment" => "construct Not: Not(a) = !a",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3" ] },
"emit" => '. not %ia32_emit_unop\t\t\t/* Not(%S1) -> %D1, (%A1) */'
},
# other operations
-"Conv" => {
- "reg_req" => { "in" => [ "gp" ], "out" => [ "in_r1" ] },
- "comment" => "construct Conv: Conv(a) = (conv)a"
-},
-
"CondJmp" => {
"op_flags" => "L|X|Y",
"comment" => "construct conditional jump: CMP A, B && JMPxx LABEL",
"op_flags" => "L|X|Y",
"comment" => "construct switch",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "none" ] },
+ "reg_req" => { "in" => [ "gp" ], "out" => [ "none" ] },
},
"Const" => {
"comment" => "represents an integer constant",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "out" => [ "gp" ] },
- "emit" => '. mov %D1, %C\t\t\t/* Mov Const into register */',
+ "emit" =>
+' if (get_ia32_Immop_tarval(n) == get_tarval_null(get_irn_mode(n))) {
+4. sub %D1, %D1\t\t\t/* optimized mov 0 to register */
+ }
+ else {
+4. mov %D1, %C\t\t\t/* Mov Const into register */
+ }
+',
},
"Cdq" => {
"comment" => "construct Load: Load(ptr, mem) = LD ptr -> reg",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
"reg_req" => { "in" => [ "gp", "gp", "none" ], "out" => [ "gp" ] },
- "emit" => '. mov %D1, %ia32_emit_am\t\t\t/* Load((%A1)) -> %D1 */'
+ "emit" =>
+' if (get_mode_size_bits(get_ia32_ls_mode(n)) < 32) {
+4. mov%Mx %D1, %ia32_emit_am\t\t\t/* Load((%A1)) -> %D1 */
+ }
+ else {
+4. mov %D1, %ia32_emit_am\t\t\t/* Load((%A1)) -> %D1 */
+ }
+'
},
"Store" => {
"irn_flags" => "R",
"comment" => "construct SSE 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", "fp", "fp", "none" ], "out" => [ "in_r1" ] },
- "emit" => '. adds%M %ia32_emit_binop\t\t\t/* SSE Add(%A1, %A2) -> %D1 */'
+ "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3 !in_r4" ] },
+ "emit" => '. adds%M %ia32_emit_binop\t\t\t/* SSE Add(%A3, %A4) -> %D1 */'
},
"fMul" => {
"irn_flags" => "R",
"comment" => "construct SSE Mul: Mul(a, b) = Mul(b, a) = a * b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. muls%M %ia32_emit_binop\t\t\t/* SSE Mul(%A1, %A2) -> %D1 */'
+ "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3 !in_r4" ] },
+ "emit" => '. muls%M %ia32_emit_binop\t\t\t/* SSE Mul(%A3, %A4) -> %D1 */'
},
"fMax" => {
"irn_flags" => "R",
"comment" => "construct SSE Max: Max(a, b) = Max(b, a) = a > b ? a : b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. maxs%M %ia32_emit_binop\t\t\t/* SSE Max(%A1, %A2) -> %D1 */'
+ "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3 !in_r4" ] },
+ "emit" => '. maxs%M %ia32_emit_binop\t\t\t/* SSE Max(%A3, %A4) -> %D1 */'
},
"fMin" => {
"irn_flags" => "R",
"comment" => "construct SSE Min: Min(a, b) = Min(b, a) = a < b ? a : b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
- "emit" => '. mins%M %ia32_emit_binop\t\t\t/* SSE Min(%A1, %A2) -> %D1 */'
+ "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3 !in_r4" ] },
+ "emit" => '. mins%M %ia32_emit_binop\t\t\t/* SSE Min(%A3, %A4) -> %D1 */'
},
"fAnd" => {
"irn_flags" => "R",
"comment" => "construct SSE And: And(a, b) = a AND b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. andp%M %ia32_emit_binop\t\t\t/* SSE And(%A3, %A4) -> %D1 */'
},
"irn_flags" => "R",
"comment" => "construct SSE Or: Or(a, b) = a OR b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. orp%M %ia32_emit_binop\t\t\t/* SSE Or(%A3, %A4) -> %D1 */'
},
"irn_flags" => "R",
"comment" => "construct SSE Eor: Eor(a, b) = a XOR b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. xorp%M %ia32_emit_binop\t\t\t/* SSE Xor(%A3, %A4) -> %D1 */'
},
"irn_flags" => "R",
"comment" => "construct SSE Sub: Sub(a, b) = a - b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. subs%M %ia32_emit_binop\t\t\t/* SSE Sub(%A1, %A2) -> %D1 */'
},
"irn_flags" => "R",
"comment" => "construct SSE Div: Div(a, b) = a / b",
"cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
- "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r1" ] },
+ "reg_req" => { "in" => [ "gp", "gp", "fp", "fp", "none" ], "out" => [ "in_r3 !in_r4" ] },
"emit" => '. divs%M %ia32_emit_binop\t\t\t/* SSE Div(%A1, %A2) -> %D1 */'
},
# other operations
-"fConv" => {
- "reg_req" => { "in" => [ "fp" ], "out" => [ "gp" ] },
- "comment" => "construct Conv: Conv(a) = (conv)a"
-},
-
"fCondJmp" => {
"op_flags" => "L|X|Y",
"comment" => "construct conditional jump: UCOMIS A, B && JMPxx LABEL",
"reg_req" => { "in" => [ "edi", "esi", "none" ], "out" => [ "none" ] },
},
+# Conversions
+
+"Conv_I2FP" => {
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "fp", "none" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "comment" => "construct Conv Int -> Floating Point"
+},
+
+"Conv_FP2I" => {
+ "reg_req" => { "in" => [ "gp", "gp", "fp", "none" ], "out" => [ "gp", "none" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "comment" => "construct Conv Floating Point -> Int"
+},
+
+"Conv_FP2FP" => {
+ "reg_req" => { "in" => [ "gp", "gp", "fp", "none" ], "out" => [ "fp", "none" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "comment" => "construct Conv Floating Point -> Floating Point",
+},
+
); # end of %nodes