- refactoring of backend generator scripts: You can create multiple constructors
[libfirm] / ir / be / ppc32 / ppc32_spec.pl
index 8383330..c520fd0 100644 (file)
@@ -1,88 +1,9 @@
 # Creation: 2006/02/13
 # $Id$
-# This is a template specification for the Firm-Backend
 
 # the cpu architecture (ia32, ia64, mips, sparc, ppc32, ...)
 
 $arch = "ppc32";
-$new_emit_syntax = 1;
-
-# The node description is done as a perl hash initializer with the
-# following structure:
-#
-# %nodes = (
-#
-# <op-name> => {
-#   "op_flags"  => "N|L|C|X|I|F|Y|H|c|K",
-#   "irn_flags" => "R|N|I"
-#   "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"
-# },
-#
-# ... # (all nodes you need to describe)
-#
-# ); # close the %nodes initializer
-
-# op_flags: flags for the operation, OPTIONAL (default is "N")
-# the op_flags correspond to the firm irop_flags:
-#   N   irop_flag_none
-#   L   irop_flag_labeled
-#   C   irop_flag_commutative
-#   X   irop_flag_cfopcode
-#   I   irop_flag_ip_cfopcode
-#   F   irop_flag_fragile
-#   Y   irop_flag_forking
-#   H   irop_flag_highlevel
-#   c   irop_flag_constlike
-#   K   irop_flag_keep
-#
-# irn_flags: special node flags, OPTIONAL (default is 0)
-# following irn_flags are supported:
-#   R   rematerializeable
-#   N   not spillable
-#   I   ignore for register allocation
-#
-# state: state of the operation, OPTIONAL (default is "floats")
-#
-# arity: arity of the operation, MUST NOT BE OMITTED
-#
-# args:  the OPTIONAL arguments of the node constructor (debug, irg and block
-#        are always the first 3 arguments and are always autmatically
-#        created)
-#        If this key is missing the following arguments will be created:
-#        for i = 1 .. arity: ir_node *op_i
-#        ir_mode *mode
-#
-# outs:  if a node defines more than one output, the names of the projections
-#        nodes having outs having automatically the mode mode_T
-#
-# comment: OPTIONAL comment for the node constructor
-#
-# rd_constructor: for every operation there will be a
-#      new_rd_<arch>_<op-name> function with the arguments from above
-#      which creates the ir_node corresponding to the defined operation
-#      you can either put the complete source code of this function here
-#
-#      This key is OPTIONAL. If omitted, the following constructor will
-#      be created:
-#      if (!op_<arch>_<op-name>) assert(0);
-#      for i = 1 to arity
-#         set in[i] = op_i
-#      done
-#      res = new_ir_node(db, irg, block, op_<arch>_<op-name>, mode, arity, in)
-#      return res
-#
-# NOTE: rd_constructor and args are only optional if and only if arity is 0,1,2 or 3
 
 # register types:
 #   0 - no special type
@@ -183,17 +104,19 @@ $new_emit_syntax = 1;
 ); # %reg_classes
 
 %emit_templates = (
-    S0 => "${arch}_emit_source_register(env, node, 0);",
-    S1 => "${arch}_emit_source_register(env, node, 1);",
-    S2 => "${arch}_emit_source_register(env, node, 2);",
-    D0 => "${arch}_emit_dest_register(env, node, 0);",
-    D1 => "${arch}_emit_dest_register(env, node, 1);",
-    D2 => "${arch}_emit_dest_register(env, node, 2);",
-       O  => "${arch}_emit_offset(env, node);",
-       C  => "${arch}_emit_immediate(env, node);",
-       RLWIMI => "${arch}_emit_rlwimi_helper(env, node);",
+    S0 => "${arch}_emit_source_register(node, 0);",
+    S1 => "${arch}_emit_source_register(node, 1);",
+    S2 => "${arch}_emit_source_register(node, 2);",
+    D0 => "${arch}_emit_dest_register(node, 0);",
+    D1 => "${arch}_emit_dest_register(node, 1);",
+    D2 => "${arch}_emit_dest_register(node, 2);",
+       O  => "${arch}_emit_offset(node);",
+       C  => "${arch}_emit_immediate(node);",
+       RLWIMI => "${arch}_emit_rlwimi_helper(node);",
 );
 
+$default_cmp_attr = "NULL";
+
 #--------------------------------------------------#
 #                        _                         #
 #                       (_)                        #
@@ -229,7 +152,6 @@ $new_emit_syntax = 1;
 },
 
 "Addi" => {
-  "op_flags"  => "c",
   "irn_flags" => "R",
   "comment"   => "construct Add: Addi(a, const) = Addi(const, a) = a + const",
   "reg_req"   => { "in" => [ "!r0" ], "out" => [ "gp" ] },
@@ -586,7 +508,6 @@ $new_emit_syntax = 1;
 },
 
 "Ori" => {
-  "op_flags"  => "c",
   "irn_flags" => "R",
   "comment"   => "ors constant with register",
   "reg_req"   => { "in" => [ "gp"], "out" => [ "gp" ] },
@@ -598,7 +519,6 @@ $new_emit_syntax = 1;
 },
 
 "Andi_dot" => {
-  "op_flags"  => "c",
   "irn_flags" => "R",
   "comment"   => "ands constant with register with cr0 update",
   "reg_req"   => { "in" => [ "gp"], "out" => [ "gp", "cr0" ] },
@@ -723,7 +643,7 @@ $new_emit_syntax = 1;
   "op_flags"  => "L|F",
   "state"     => "exc_pinned",
   "comment"   => "construct Store: Store (byte) (ptr, val, mem) = ST ptr,val",
-  "reg_req"   => { "in" => [ "!r0", "gp", "none" ] },
+  "reg_req"   => { "in" => [ "!r0", "gp", "none" ], "out" => [ "none" ] },
   "emit"      => '. stb %S1, %O(%S0)',
   "cmp_attr"  =>
 '
@@ -736,7 +656,7 @@ $new_emit_syntax = 1;
   "op_flags"  => "L|F",
   "state"     => "exc_pinned",
   "comment"   => "construct Store: Store (halfword) (ptr, val, mem) = ST ptr,val",
-  "reg_req"   => { "in" => [ "!r0", "gp", "none" ] },
+  "reg_req"   => { "in" => [ "!r0", "gp", "none" ], "out" => [ "none" ] },
   "emit"      => '. sth %S1, %O(%S0)',
   "cmp_attr"  =>
 '
@@ -749,7 +669,7 @@ $new_emit_syntax = 1;
   "op_flags"  => "L|F",
   "state"     => "exc_pinned",
   "comment"   => "construct Store: Store (word) (ptr, val, mem) = ST ptr,val",
-  "reg_req"   => { "in" => [ "!r0", "gp", "none" ] },
+  "reg_req"   => { "in" => [ "!r0", "gp", "none" ], "out" => [ "none" ] },
   "emit"      => '. stw %S1, %O(%S0)',
   "cmp_attr"  =>
 '
@@ -946,7 +866,7 @@ $new_emit_syntax = 1;
   "op_flags"  => "L|F",
   "state"     => "exc_pinned",
   "comment"   => "construct Store (double): Store(ptr, val, mem)  = ST ptr,val",
-  "reg_req"   => { "in" => [ "!r0", "fp", "none" ] },
+  "reg_req"   => { "in" => [ "!r0", "fp", "none" ], "out" => [ "none" ] },
   "emit"      => '. stfd %S1, %O(%S0)',
   "cmp_attr"  =>
 '
@@ -959,7 +879,7 @@ $new_emit_syntax = 1;
   "op_flags"  => "L|F",
   "state"     => "exc_pinned",
   "comment"   => "construct Store (single): Store(ptr, val, mem)  = ST ptr,val",
-  "reg_req"   => { "in" => [ "!r0", "fp", "none" ] },
+  "reg_req"   => { "in" => [ "!r0", "fp", "none" ], "out" => [ "none" ] },
   "emit"      => '. stfs %S1, %O(%S0)',
   "cmp_attr"  =>
 '