X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=a996025fbe24f8db5fae0dc3483b2a4e4620584d;hb=a61c3426415a95aea3e7ba1444d97782c471e681;hp=b2016b6a7358e4dcd1983e60fa0a5805e2bd8838;hpb=d98d4ab0a6cf8e162331f4f908b17ecd874e941d;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index b2016b6a7..a996025fb 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,46 @@ $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", + "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", @@ -206,6 +262,12 @@ $comment_string = "/*"; "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", @@ -242,6 +304,12 @@ $comment_string = "/*"; "outs" => [ "res", "M" ], }, +"l_Eor" => { + "op_flags" => "C", + "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 +340,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 +347,29 @@ $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", + "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", @@ -320,6 +397,43 @@ $comment_string = "/*"; "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", @@ -329,6 +443,43 @@ $comment_string = "/*"; "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", @@ -338,6 +489,11 @@ $comment_string = "/*"; "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", @@ -367,6 +523,11 @@ $comment_string = "/*"; "outs" => [ "res", "M" ], }, +"l_Minus" => { + "comment" => "construct lowered Minus: Minus(a) = -a", + "arity" => 1, +}, + "Inc" => { "irn_flags" => "R", "comment" => "construct Increment: Inc(a) = a++", @@ -501,7 +662,18 @@ $comment_string = "/*"; "Push" => { "comment" => "push a gp register on the stack", "reg_req" => { "in" => [ "esp", "gp", "none" ], "out" => [ "esp" ] }, - "emit" => '. push %S2 /* Push(%A2) */', + "emit" => ' +if (get_ia32_id_cnst(n)) { + if (get_ia32_immop_type(n) == ia32_ImmConst) { +. push %C /* Push(%A2) */ + } else { +. push OFFSET FLAT:%C /* Push(%A2) */ + } +} +else { +. push %S2 /* Push(%A2) */ +} +', "outs" => [ "stack", "M" ], }, @@ -602,6 +774,15 @@ $comment_string = "/*"; # 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", @@ -622,6 +803,13 @@ $comment_string = "/*"; # 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", @@ -636,7 +824,7 @@ $comment_string = "/*"; "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 @@ -716,6 +904,63 @@ $comment_string = "/*"; "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" ] } +}, + #----------------------------------------------------------# # _ _ _ __ _ _ # # (_) | | | | / _| | | | # @@ -876,6 +1121,7 @@ $comment_string = "/*"; "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" ] }, @@ -1071,6 +1317,7 @@ $comment_string = "/*"; "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 */', @@ -1151,13 +1398,13 @@ $comment_string = "/*"; }, "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