X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_spec.pl;h=dbfa32bb8215372501bf3e62e74e537d68cdd422;hb=55ced8ac7f0e4d8235b3d9a2006a858cdd424bfa;hp=95c3abf1e29a19126c5e6ceafc6e89ebaaa3c9ca;hpb=475e9ffc1749434c667028d54d3d2e806d2dcd72;p=libfirm diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 95c3abf1e..dbfa32bb8 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -14,14 +14,16 @@ $arch = "ia32"; # => { # "op_flags" => "N|L|C|X|I|F|Y|H|c|K", # "irn_flags" => "R|N|I" -# "arity" => "0|1|2|3 ... |variable|dynamic|all", -# "state" => "floats|pinned", +# "arity" => "0|1|2|3 ... |variable|dynamic|any", +# "state" => "floats|pinned|mem_pinned|exc_pinned", # "args" => [ # { "type" => "type 1", "name" => "name 1" }, # { "type" => "type 2", "name" => "name 2" }, # ... # ], # "comment" => "any comment for constructor", +# "reg_req" => { "in" => [ "reg_class|register" ], "out" => [ "reg_class|register|in_rX" ] }, +# "cmp_attr" => "c source code for comparing node attributes", # "emit" => "emit code with templates", # "rd_constructor" => "c source code which constructs an ir_node" # }, @@ -49,7 +51,7 @@ $arch = "ia32"; # N not spillable # I ignore for register allocation # -# state: state of the operation, OPTIONAL (default is "pinned") +# state: state of the operation, OPTIONAL (default is "floats") # # arity: arity of the operation, MUST NOT BE OMITTED # @@ -83,23 +85,18 @@ $arch = "ia32"; # 1 - caller save (register must be saved by the caller of a function) # 2 - callee save (register must be saved by the called function) # 4 - ignore (do not assign this register) -# 8 - this is the stack pointer -# 16 - this is the base pointer -# NOTE: Make sure to list the registers returning the call-result before all other -# caller save registers and in the correct order, otherwise it will break -# the magic! -# Last entry of each class is the largest Firm-Mode a register can hold +# NOTE: Last entry of each class is the largest Firm-Mode a register can hold %reg_classes = ( "gp" => [ - { "name" => "eax", "type" => 1 }, - { "name" => "edx", "type" => 1 }, - { "name" => "ebx", "type" => 2 }, - { "name" => "ecx", "type" => 1 }, - { "name" => "esi", "type" => 2 }, - { "name" => "edi", "type" => 2 }, - { "name" => "ebp", "type" => 16 }, - { "name" => "esp", "type" => 8 }, - { "name" => "xxx", "type" => 4 }, # we need a dummy register for NoReg and Unknown nodes + { "name" => "eax", "type" => 1 }, + { "name" => "edx", "type" => 1 }, + { "name" => "ebx", "type" => 2 }, + { "name" => "ecx", "type" => 1 }, + { "name" => "esi", "type" => 2 }, + { "name" => "edi", "type" => 2 }, + { "name" => "ebp", "type" => 2 }, + { "name" => "esp", "type" => 6 }, + { "name" => "xxx", "type" => 6 }, # we need a dummy register for NoReg and Unknown nodes { "mode" => "mode_P" } ], "fp" => [ @@ -111,6 +108,7 @@ $arch = "ia32"; { "name" => "xmm5", "type" => 1 }, { "name" => "xmm6", "type" => 1 }, { "name" => "xmm7", "type" => 1 }, + { "name" => "xxxx", "type" => 6 }, # we need a dummy register for NoReg and Unknown nodes { "mode" => "mode_D" } ] ); # %reg_classes @@ -221,6 +219,16 @@ $arch = "ia32"; ' }, +"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\t\t\t/* compare Sel for CMov (%A2, %A3) */ +. cmovne %D1, %S3\t\t\t/* sel == true -> return %S3 */ +' +}, + # not commutative operations "Sub" => { @@ -312,7 +320,6 @@ $arch = "ia32"; # other operations "Conv" => { - "arity" => 1, "reg_req" => { "in" => [ "gp" ], "out" => [ "in_r1" ] }, "comment" => "construct Conv: Conv(a) = (conv)a" }, @@ -337,8 +344,8 @@ $arch = "ia32"; "emit" => '. mov %D1, %C\t\t\t/* Mov Const into register */', "cmp_attr" => ' - if (attr_a->tp == attr_b->tp) { - if (attr_a->tp == ia32_SymConst) { + if (attr_a->data.tp == attr_b->data.tp) { + if (attr_a->data.tp == ia32_SymConst) { if (attr_a->sc == NULL || attr_b->sc == NULL) return 1; else @@ -392,27 +399,6 @@ $arch = "ia32"; "emit" => '. lea %D1, %ia32_emit_am\t\t/* %D1 = %S1 + %S2 << %C + %O, (%A1, %A2) */' }, -"StackParam" => { - "arity" => 1, - "remat" => 1, - "comment" => "constructs a Stack Parameter to retrieve a parameter from Stack", - "reg_req" => { "in" => [ "none" ], "out" => [ "gp" ] }, - "cmp_attr" => -' - return (attr_a->pn_code != attr_b->pn_code); -' -}, - -"StackArg" => { - "arity" => 2, - "comment" => "constructs a Stack Argument to pass an argument on Stack", - "reg_req" => { "in" => [ "none", "gp" ], "out" => [ "none" ] }, - "cmp_attr" => -' - return (attr_a->pn_code != attr_b->pn_code); -' -}, - #--------------------------------------------------------# # __ _ _ _ # # / _| | | | | | # @@ -492,7 +478,6 @@ $arch = "ia32"; # other operations "fConv" => { - "arity" => 1, "reg_req" => { "in" => [ "fp" ], "out" => [ "gp" ] }, "comment" => "construct Conv: Conv(a) = (conv)a" }, @@ -511,8 +496,8 @@ $arch = "ia32"; "emit" => '. mov%M %D1, %C\t\t\t/* Load fConst into register */', "cmp_attr" => ' - if (attr_a->tp == attr_b->tp) { - if (attr_a->tp == ia32_SymConst) { + if (attr_a->data.tp == attr_b->data.tp) { + if (attr_a->data.tp == ia32_SymConst) { if (attr_a->sc == NULL || attr_b->sc == NULL) return 1; else @@ -552,25 +537,20 @@ $arch = "ia32"; "emit" => '. movs%M %ia32_emit_am, %S3\t\t\t/* Store(%S3) -> (%A1) */' }, -"fStackParam" => { - "arity" => 1, - "remat" => 1, - "comment" => "constructs a Stack Parameter to retrieve a SSE parameter from Stack", - "reg_req" => { "in" => [ "none" ], "out" => [ "fp" ] }, - "cmp_attr" => -' - return (attr_a->pn_code != attr_b->pn_code); -' +# 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" ] }, }, -"fStackArg" => { - "arity" => 2, - "comment" => "constructs a Stack Argument to pass an argument on Stack", - "reg_req" => { "in" => [ "none", "fp" ], "out" => [ "none" ] }, - "cmp_attr" => -' - return (attr_a->pn_code != attr_b->pn_code); -' +"CopyB_i" => { + "op_flags" => "F|H", + "state" => "pinned", + "comment" => "implements a memcopy: CopyB(dst, src, mem) == memcpy(dst, src, attr(size))", + "reg_req" => { "in" => [ "edi", "esi", "none" ], "out" => [ "none" ] }, }, # Call @@ -590,31 +570,4 @@ $arch = "ia32"; " }, -# Return - -"Return" => { - "op_flags" => "L|X", - "state" => "pinned", - "arity" => "variable", - "comment" => "construct Return: Return(...)", - "args" => [ - { "type" => "int", "name" => "n" }, - { "type" => "ir_node **", "name" => "in" } - ], - "rd_constructor" => -" if (!op_ia32_Return) assert(0); - return new_ir_node(db, irg, block, op_ia32_Return, mode_X, n, in); -" -}, - -# M/Alloc - -"Alloca" => { - "op_flags" => "L|F", - "state" => "pinned", - "arity" => "2", - "comment" => "construct Alloca: allocate memory on Stack", - "reg_req" => { "in" => [ "gp" ], "out" => [ "gp" ] } -}, - ); # end of %nodes