X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=a929cbdda4dc4d46cdef38448ee64d5a95751e8d;hb=004f9b10d631414720ea9c4a86d3f89b742a027e;hp=102e41c3ac85e7466a40db6da8eeb529ef0f4b7b;hpb=86609dfaeb583640afd96b0311bd88396a3fd816;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 102e41c3a..a929cbdda 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -104,6 +104,28 @@ $comment_string = "/*"; { "name" => "ecx", "type" => 1 }, { "name" => "esi", "type" => 2 }, { "name" => "edi", "type" => 2 }, +# { "name" => "r11", "type" => 1 }, +# { "name" => "r12", "type" => 1 }, +# { "name" => "r13", "type" => 1 }, +# { "name" => "r14", "type" => 1 }, +# { "name" => "r15", "type" => 1 }, +# { "name" => "r16", "type" => 1 }, +# { "name" => "r17", "type" => 1 }, +# { "name" => "r18", "type" => 1 }, +# { "name" => "r19", "type" => 1 }, +# { "name" => "r20", "type" => 1 }, +# { "name" => "r21", "type" => 1 }, +# { "name" => "r22", "type" => 1 }, +# { "name" => "r23", "type" => 1 }, +# { "name" => "r24", "type" => 1 }, +# { "name" => "r25", "type" => 1 }, +# { "name" => "r26", "type" => 1 }, +# { "name" => "r27", "type" => 1 }, +# { "name" => "r28", "type" => 1 }, +# { "name" => "r29", "type" => 1 }, +# { "name" => "r30", "type" => 1 }, +# { "name" => "r31", "type" => 1 }, +# { "name" => "r32", "type" => 1 }, { "name" => "ebp", "type" => 2 }, { "name" => "esp", "type" => 4 }, { "name" => "gp_NOREG", "type" => 6 }, # we need a dummy register for NoReg nodes @@ -145,8 +167,6 @@ $comment_string = "/*"; { "name" => "st5", "type" => 1 }, { "name" => "st6", "type" => 1 }, { "name" => "st7", "type" => 1 }, - { "name" => "st_NOREG", "type" => 6 }, # we need a dummy register for NoReg nodes - { "name" => "st_UKNWN", "type" => 6 }, # we need a dummy register for Unknown nodes { "mode" => "mode_E" } ] ); # %reg_classes @@ -193,10 +213,49 @@ $comment_string = "/*"; "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", + "cmp_attr" => " return 1;\n", + "comment" => "construct lowered Add: Add(a, b) = Add(b, a) = a + b", + "arity" => 2, +}, + +"l_AddC" => { + "op_flags" => "C", + "cmp_attr" => " return 1;\n", + "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" ] }, + "emit" => '. mul %ia32_emit_unop /* Mul(%A1, %A2) -> %D1 */', + "outs" => [ "EAX", "EDX", "M" ], +}, + +"l_MulS" => { + "op_flags" => "C", + "cmp_attr" => " return 1;\n", + "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", @@ -206,12 +265,19 @@ $comment_string = "/*"; "outs" => [ "res", "M" ], }, +"l_Mul" => { + "op_flags" => "C", + "cmp_attr" => " return 1;\n", + "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", "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" => '. imul %ia32_emit_binop /* Mulh(%A1, %A2) -> %D1 */', + "reg_req" => { "in" => [ "gp", "gp", "gp", "gp", "none" ], "out" => [ "eax in_r3", "edx" ] }, + "emit" => '. imul %ia32_emit_unop /* Mulh(%A1, %A2) -> %D1 */', "outs" => [ "EAX", "EDX", "M" ], }, @@ -242,6 +308,13 @@ $comment_string = "/*"; "outs" => [ "res", "M" ], }, +"l_Eor" => { + "op_flags" => "C", + "cmp_attr" => " return 1;\n", + "comment" => "construct lowered Eor: Eor(a, b) = Eor(b, a) = a EOR b", + "arity" => 2 +}, + "Max" => { "irn_flags" => "R", "comment" => "construct Max: Max(a, b) = Max(b, a) = a > b ? a : b", @@ -272,16 +345,6 @@ $comment_string = "/*"; ' }, -"CMov" => { - "irn_flags" => "R", - "comment" => "construct Mux: Mux(sel, a, b) == sel ? a : b", - "reg_req" => { "in" => [ "gp", "gp", "gp" ], "out" => [ "in_r2" ] }, - "emit" => -'. cmp %S1, 0 /* compare Sel for CMov (%A2, %A3) */ -. cmovne %D1, %S3 /* sel == true -> return %S3 */ -' -}, - # not commutative operations "Sub" => { @@ -289,10 +352,31 @@ $comment_string = "/*"; "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", + "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", @@ -320,6 +404,45 @@ $comment_string = "/*"; "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", @@ -329,6 +452,45 @@ $comment_string = "/*"; "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", @@ -338,6 +500,12 @@ $comment_string = "/*"; "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", @@ -367,6 +535,12 @@ $comment_string = "/*"; "outs" => [ "res", "M" ], }, +"l_Minus" => { + "cmp_attr" => " return 1;\n", + "comment" => "construct lowered Minus: Minus(a) = -a", + "arity" => 1, +}, + "Inc" => { "irn_flags" => "R", "comment" => "construct Increment: Inc(a) = a++", @@ -470,6 +644,23 @@ $comment_string = "/*"; "outs" => [ "res", "M" ], }, +"l_Load" => { + "op_flags" => "L|F", + "cmp_attr" => " return 1;\n", + "comment" => "construct lowered Load: Load(ptr, mem) = LD ptr -> reg", + "outs" => [ "res", "M" ], + "arity" => 2, +}, + +"l_Store" => { + "op_flags" => "L|F", + "cmp_attr" => " return 1;\n", + "state" => "exc_pinned", + "comment" => "construct lowered Store: Store(ptr, val, mem) = ST ptr,val", + "arity" => 3, + "outs" => [ "M" ], +}, + "Store" => { "op_flags" => "L|F", "state" => "exc_pinned", @@ -613,6 +804,15 @@ else { # not commutative operations +"xAndNot" => { + "irn_flags" => "R", + "comment" => "construct SSE AndNot: AndNot(a, b) = a AND NOT 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" => '. andnp%M %ia32_emit_binop /* SSE AndNot(%A3, %A4) -> %D1 */', + "outs" => [ "res", "M" ], +}, + "xSub" => { "irn_flags" => "R", "comment" => "construct SSE Sub: Sub(a, b) = a - b", @@ -633,6 +833,13 @@ else { # other operations +"xCmp" => { + "irn_flags" => "R", + "comment" => "construct SSE Compare: Cmp(a, b) == a = a cmp b", + "reg_req" => { "in" => [ "gp", "gp", "xmm", "xmm", "none" ], "out" => [ "in_r3 !in_r4" ] }, + "outs" => [ "res", "M" ], +}, + "xCondJmp" => { "op_flags" => "L|X|Y", "comment" => "construct conditional jump: UCOMIS A, B && JMPxx LABEL", @@ -647,7 +854,7 @@ else { "comment" => "represents a SSE constant", "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n", "reg_req" => { "in" => [ "none" ], "out" => [ "xmm" ] }, - "emit" => '. mov%M %D1, %C /* Load fConst into register */', + "emit" => '. movs%M %D1, %C /* Load fConst into register */', }, # Load / Store @@ -673,6 +880,20 @@ else { "outs" => [ "M" ], }, +"l_X87toSSE" => { + "op_flags" => "L|F", + "comment" => "construct: transfer a value from x87 FPU into a SSE register", + "cmp_attr" => " return 1;\n", + "arity" => 3, +}, + +"l_SSEtoX87" => { + "op_flags" => "L|F", + "comment" => "construct: transfer a value from SSE register to x87 FPU", + "cmp_attr" => " return 1;\n", + "arity" => 3, +}, + # CopyB "CopyB" => { @@ -727,6 +948,63 @@ else { "outs" => [ "res", "M" ], }, +"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" => [ "xmm", "xmm", "gp", "gp" ], "out" => [ "in_r4" ] } +}, + +"vfCmpCMov" => { + "irn_flags" => "R", + "comment" => "construct Conditional Move: x87 Compare + int CMov", + "reg_req" => { "in" => [ "vfp", "vfp", "gp", "gp" ], "out" => [ "in_r4" ] } +}, + +"CmpSet" => { + "irn_flags" => "R", + "comment" => "construct Set: Set(sel) == sel ? 1 : 0", + "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" => [ "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" => [ "gp", "gp", "vfp", "vfp", "none" ], "out" => [ "eax ebx ecx edx", "none" ] }, + "outs" => [ "res", "M" ], +}, + +"vfCMov" => { + "irn_flags" => "R", + "comment" => "construct x87 Conditional Move: vfCMov(sel, a, b) = sel ? a : b", + "reg_req" => { "in" => [ "vfp", "vfp", "vfp", "vfp" ], "out" => [ "vfp" ] } +}, + #----------------------------------------------------------# # _ _ _ __ _ _ # # (_) | | | | / _| | | | # @@ -751,12 +1029,19 @@ else { "vfmul" => { "irn_flags" => "R", - "comment" => "virtual fp Mul: Mul(a, b) = Mul(b, a) = a + b", + "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" ] }, "outs" => [ "res", "M" ], }, +"l_vfmul" => { + "op_flags" => "C", + "cmp_attr" => " return 1;\n", + "comment" => "lowered virtual fp Mul: Mul(a, b) = Mul(b, a) = a * b", + "arity" => 2, +}, + "vfsub" => { "irn_flags" => "R", "comment" => "virtual fp Sub: Sub(a, b) = a - b", @@ -765,6 +1050,12 @@ else { "outs" => [ "res", "M" ], }, +"l_vfsub" => { + "cmp_attr" => " return 1;\n", + "comment" => "lowered virtual fp Sub: Sub(a, b) = a - b", + "arity" => 2, +}, + "vfdiv" => { "comment" => "virtual fp Div: Div(a, b) = a / b", "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n", @@ -772,6 +1063,12 @@ else { "outs" => [ "res", "M" ], }, +"l_vfdiv" => { + "cmp_attr" => " return 1;\n", + "comment" => "lowered virtual fp Div: Div(a, b) = a / b", + "arity" => 2, +}, + "vfabs" => { "irn_flags" => "R", "comment" => "virtual fp Abs: Abs(a) = |a|", @@ -833,6 +1130,13 @@ else { "outs" => [ "res", "M" ], }, +"l_vfild" => { + "cmp_attr" => " return 1;\n", + "comment" => "lowered virtual fp integer Load: Load(ptr, mem) = iLD ptr -> reg", + "outs" => [ "res", "M" ], + "arity" => 2, +}, + "vfist" => { "comment" => "virtual fp integer Store: Store(ptr, val, mem) = iST ptr,val", "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n", @@ -840,6 +1144,14 @@ else { "outs" => [ "M" ], }, +"l_vfist" => { + "cmp_attr" => " return 1;\n", + "comment" => "lowered virtual fp integer Store: Store(ptr, val, mem) = iST ptr,val", + "outs" => [ "M" ], + "arity" => 3, +}, + + # constants "vfldz" => { @@ -887,6 +1199,7 @@ else { "vfConst" => { "op_flags" => "c", "irn_flags" => "R", + "init_attr" => " set_ia32_ls_mode(res, mode);", "comment" => "represents a virtual floating point constant", "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n", "reg_req" => { "in" => [ "none" ], "out" => [ "vfp" ] }, @@ -1082,6 +1395,7 @@ else { "fild" => { "op_flags" => "R", "irn_flags" => "R", + "rd_constructor" => "NONE", "comment" => "x87 fp integer Load: Load(ptr, mem) = iLD ptr -> reg", "reg_req" => { }, "emit" => '. fild %ia32_emit_am /* integer Load((%A1)) -> %D1 */', @@ -1162,13 +1476,13 @@ else { }, "fldConst" => { - "op_flags" => "R", - "op_flags" => "c", + "op_flags" => "R|c", "irn_flags" => "R", + "rd_constructor" => "NONE", "comment" => "represents a x87 constant", "cmp_attr" => " return ia32_compare_immop_attr(attr_a, attr_b);\n", "reg_req" => { "out" => [ "st" ] }, - "emit" => '. fld%M %C /* Load fConst into register -> %D1 */', + "emit" => '. fld %ia32_emit_adr /* Load fConst into register -> %D1 */', }, # fxch, fpush, fpop