+ "irn_flags" => "R",
+ "comment" => "construct Lea: Lea(a,b) = lea [a+b*const+offs] | res = a + b * const + offs with const = 0,1,2,4,8",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "gp" ] },
+ "emit" => '. lea %D1, %ia32_emit_am /* LEA(%A1, %A2) */'
+},
+
+#-----------------------------------------------------------------------------#
+# _____ _____ ______ __ _ _ _ #
+# / ____/ ____| ____| / _| | | | | | #
+# | (___| (___ | |__ | |_| | ___ __ _| |_ _ __ ___ __| | ___ ___ #
+# \___ \\___ \| __| | _| |/ _ \ / _` | __| | '_ \ / _ \ / _` |/ _ \/ __| #
+# ____) |___) | |____ | | | | (_) | (_| | |_ | | | | (_) | (_| | __/\__ \ #
+# |_____/_____/|______| |_| |_|\___/ \__,_|\__| |_| |_|\___/ \__,_|\___||___/ #
+#-----------------------------------------------------------------------------#
+
+# commutative operations
+
+"fAdd" => {
+ "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", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
+ "emit" => '. adds%M %ia32_emit_binop /* 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", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
+ "emit" => '. muls%M %ia32_emit_binop /* 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", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
+ "emit" => '. maxs%M %ia32_emit_binop /* 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", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
+ "emit" => '. mins%M %ia32_emit_binop /* 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", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
+ "emit" => '. andp%M %ia32_emit_binop /* SSE And(%A3, %A4) -> %D1 */'
+},
+
+"fOr" => {
+ "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", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
+ "emit" => '. orp%M %ia32_emit_binop /* SSE Or(%A3, %A4) -> %D1 */'
+},
+
+"fEor" => {
+ "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", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
+ "emit" => '. xorp%M %ia32_emit_binop /* SSE Xor(%A3, %A4) -> %D1 */'
+},
+
+# not commutative operations
+
+"fSub" => {
+ "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", "xmm", "xmm", "none" ], "out" => [ "in_r3" ] },
+ "emit" => '. subs%M %ia32_emit_binop /* SSE Sub(%A1, %A2) -> %D1 */'
+},
+
+"fDiv" => {
+ "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", "xmm", "xmm", "none" ], "out" => [ "in_r3 !in_r4" ] },
+ "emit" => '. divs%M %ia32_emit_binop /* SSE Div(%A1, %A2) -> %D1 */'
+},
+
+# other operations
+
+"fCondJmp" => {
+ "op_flags" => "L|X|Y",
+ "comment" => "construct conditional jump: UCOMIS A, B && JMPxx LABEL",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "none", "none" ] },
+},
+
+"fConst" => {
+ "op_flags" => "c",
+ "irn_flags" => "R",
+ "comment" => "represents a SSE constant",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "out" => [ "xmm" ] },
+ "emit" => '. mov%M %D1, %C /* Load fConst into register */',
+},
+
+# Load / Store
+
+"fLoad" => {
+ "op_flags" => "L|F",
+ "irn_flags" => "R",
+ "state" => "exc_pinned",
+ "comment" => "construct SSE Load: Load(ptr, mem) = LD ptr",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "none" ], "out" => [ "xmm" ] },
+ "emit" => '. movs%M %D1, %ia32_emit_am /* Load((%A1)) -> %D1 */'
+},
+
+"fStore" => {
+ "op_flags" => "L|F",
+ "state" => "exc_pinned",
+ "comment" => "construct Store: Store(ptr, val, mem) = ST ptr,val",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "xmm", "none" ] },
+ "emit" => '. movs%M %ia32_emit_binop /* Store(%S3) -> (%A1) */'
+},
+
+# CopyB
+
+"CopyB" => {
+ "op_flags" => "F|H",
+ "state" => "pinned",
+ "comment" => "implements a memcopy: CopyB(dst, src, size, mem) == memcpy(dst, src, size)",
+ "reg_req" => { "in" => [ "edi", "esi", "ecx", "none" ], "out" => [ "none" ] },
+},
+
+"CopyB_i" => {
+ "op_flags" => "F|H",
+ "state" => "pinned",
+ "comment" => "implements a memcopy: CopyB(dst, src, mem) == memcpy(dst, src, attr(size))",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "edi", "esi", "none" ], "out" => [ "none" ] },
+},
+
+# Conversions
+
+"Conv_I2I" => {
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "in_r3", "none" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "comment" => "construct Conv Int -> Int"
+},
+
+"Conv_I2I8Bit" => {
+ "reg_req" => { "in" => [ "gp", "gp", "eax ebx ecx edx", "none" ], "out" => [ "in_r3", "none" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "comment" => "construct Conv Int -> Int"
+},
+
+"Conv_I2FP" => {
+ "reg_req" => { "in" => [ "gp", "gp", "gp", "none" ], "out" => [ "xmm", "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", "xmm", "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", "xmm", "none" ], "out" => [ "xmm", "none" ] },
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "comment" => "construct Conv Floating Point -> Floating Point",
+},
+
+#----------------------------------------------------------#
+# _ _ _ __ _ _ #
+# (_) | | | | / _| | | | #
+# __ ___ _ __| |_ _ _ __ _| | | |_| | ___ __ _| |_ #
+# \ \ / / | '__| __| | | |/ _` | | | _| |/ _ \ / _` | __| #
+# \ V /| | | | |_| |_| | (_| | | | | | | (_) | (_| | |_ #
+# \_/ |_|_| \__|\__,_|\__,_|_| |_| |_|\___/ \__,_|\__| #
+# | | #
+# _ __ ___ __| | ___ ___ #
+# | '_ \ / _ \ / _` |/ _ \/ __| #
+# | | | | (_) | (_| | __/\__ \ #
+# |_| |_|\___/ \__,_|\___||___/ #
+#----------------------------------------------------------#
+
+"vfadd" => {
+ "irn_flags" => "R",
+ "comment" => "virtual fp 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", "vfp", "vfp", "none" ], "out" => [ "vfp" ] },
+},
+
+"vfmul" => {
+ "irn_flags" => "R",
+ "comment" => "virtual fp 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", "vfp", "vfp", "none" ], "out" => [ "vfp" ] },
+},
+
+"vfsub" => {
+ "irn_flags" => "R",
+ "comment" => "virtual fp Sub: Sub(a, b) = a - b",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "vfp" ] },
+},
+
+"vfdiv" => {
+ "comment" => "virtual fp Div: Div(a, b) = a / b",
+ "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n",
+ "reg_req" => { "in" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "vfp" ] },
+},
+
+"vfabs" => {
+ "irn_flags" => "R",
+ "comment" => "virtual fp Abs: Abs(a) = |a|",
+ "reg_req" => { "in" => [ "vfp"], "out" => [ "vfp" ] },
+},
+
+"vfchs" => {
+ "irn_flags" => "R",
+ "comment" => "virtual fp Chs: Chs(a) = -a",
+ "reg_req" => { "in" => [ "vfp"], "out" => [ "vfp" ] },
+},
+
+"vfsin" => {
+ "irn_flags" => "R",
+ "comment" => "virtual fp Sin: Sin(a) = sin(a)",
+ "reg_req" => { "in" => [ "vfp"], "out" => [ "vfp" ] },