update TEMPLATE backend
authorMatthias Braun <matthias.braun@kit.edu>
Thu, 19 Jul 2012 08:38:11 +0000 (10:38 +0200)
committerMatthias Braun <matthias.braun@kit.edu>
Mon, 23 Jul 2012 12:47:40 +0000 (14:47 +0200)
Still broken for anything except int f(void) { return 0; } though...

ir/be/TEMPLATE/TEMPLATE_spec.pl
ir/be/TEMPLATE/TEMPLATE_transform.c
ir/be/TEMPLATE/bearch_TEMPLATE.c
scripts/ir_spec.py

index 666cdc4..3b40e58 100644 (file)
@@ -211,6 +211,21 @@ Jmp => {
        mode      => "mode_X",
 },
 
+Start => {
+       state     => "pinned",
+       reg_req   => { in => [], out => [ "sp:I|S", "none" ] },
+       outs      => [ "stack", "M" ],
+       ins       => [],
+},
+
+Return => {
+       state    => "pinned",
+       op_flags => [ "cfopcode" ],
+       ins      => [ "stack", "mem" ],
+       reg_req  => { in => [ "sp", "none", ], out => [] },
+       mode     => "mode_X",
+},
+
 # Load / Store
 
 Load => {
index 90c1ec4..d80cefb 100644 (file)
@@ -48,6 +48,8 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 typedef ir_node* (*new_binop_func)(dbg_info *dbgi, ir_node *block,
                                    ir_node *left, ir_node *right);
 
+static ir_mode *gp_regs_mode;
+
 static ir_node *transform_binop(ir_node *node, new_binop_func new_func)
 {
        ir_node  *block     = get_nodes_block(node);
@@ -216,6 +218,28 @@ static ir_node *gen_Jmp(ir_node *node)
        return new_bd_TEMPLATE_Jmp(dbgi, new_block);
 }
 
+static ir_node *gen_Start(ir_node *node)
+{
+       dbg_info *dbgi      = get_irn_dbg_info(node);
+       ir_node  *block     = get_nodes_block(node);
+       ir_node  *new_block = be_transform_node(block);
+
+       return new_bd_TEMPLATE_Start(dbgi, new_block);
+}
+
+static ir_node *gen_Return(ir_node *node)
+{
+       dbg_info *dbgi      = get_irn_dbg_info(node);
+       ir_node  *block     = get_nodes_block(node);
+       ir_node  *new_block = be_transform_node(block);
+       ir_node  *mem       = get_Return_mem(node);
+       ir_node  *new_mem   = be_transform_node(mem);
+       ir_graph *irg       = get_irn_irg(node);
+       ir_node  *sp        = get_irg_frame(irg);
+
+       return new_bd_TEMPLATE_Return(dbgi, new_block, sp, new_mem);
+}
+
 /**
  * returns true if mode should be stored in a general purpose register
  */
@@ -251,26 +275,62 @@ static ir_node *gen_Phi(ir_node *node)
        return phi;
 }
 
+static ir_node *gen_Proj_Start(ir_node *node)
+{
+       dbg_info *dbgi      = get_irn_dbg_info(node);
+       ir_node  *block     = get_nodes_block(node);
+       ir_node  *new_block = be_transform_node(block);
+       ir_node  *start     = get_Proj_pred(node);
+       ir_node  *new_start = be_transform_node(start);
+       long      pn        = get_Proj_proj(node);
+
+       switch ((pn_Start) pn) {
+       case pn_Start_X_initial_exec:
+               return new_bd_TEMPLATE_Jmp(dbgi, new_block);
+       case pn_Start_M:
+               return new_rd_Proj(dbgi, new_start, mode_M, pn_TEMPLATE_Start_M);
+       case pn_Start_T_args:
+               return new_r_Bad(get_irn_irg(block), mode_T);
+       case pn_Start_P_frame_base:
+               return new_rd_Proj(dbgi, new_start, gp_regs_mode, pn_TEMPLATE_Start_stack);
+       }
+       panic("unexpected Start proj %ld\n", pn);
+}
+
+static ir_node *gen_Proj(ir_node *node)
+{
+       ir_node *pred = get_Proj_pred(node);
+
+       switch (get_irn_opcode(pred)) {
+       case iro_Start: return gen_Proj_Start(node);
+       default:
+               panic("code selection can't handle Proj after %+F\n", pred);
+       }
+}
+
 static void TEMPLATE_register_transformers(void)
 {
        be_start_transform_setup();
 
-       be_set_transform_function(op_Add,   gen_Add);
-       be_set_transform_function(op_And,   gen_And);
-       be_set_transform_function(op_Const, gen_Const);
-       be_set_transform_function(op_Div,   gen_Div);
-       be_set_transform_function(op_Eor,   gen_Eor);
-       be_set_transform_function(op_Jmp,   gen_Jmp);
-       be_set_transform_function(op_Load,  gen_Load);
-       be_set_transform_function(op_Minus, gen_Minus);
-       be_set_transform_function(op_Mul,   gen_Mul);
-       be_set_transform_function(op_Not,   gen_Not);
-       be_set_transform_function(op_Or,    gen_Or);
-       be_set_transform_function(op_Phi,   gen_Phi);
-       be_set_transform_function(op_Shl,   gen_Shl);
-       be_set_transform_function(op_Shr,   gen_Shr);
-       be_set_transform_function(op_Store, gen_Store);
-       be_set_transform_function(op_Sub,   gen_Sub);
+       be_set_transform_function(op_Add,    gen_Add);
+       be_set_transform_function(op_And,    gen_And);
+       be_set_transform_function(op_Const,  gen_Const);
+       be_set_transform_function(op_Div,    gen_Div);
+       be_set_transform_function(op_Eor,    gen_Eor);
+       be_set_transform_function(op_Jmp,    gen_Jmp);
+       be_set_transform_function(op_Load,   gen_Load);
+       be_set_transform_function(op_Minus,  gen_Minus);
+       be_set_transform_function(op_Mul,    gen_Mul);
+       be_set_transform_function(op_Not,    gen_Not);
+       be_set_transform_function(op_Or,     gen_Or);
+       be_set_transform_function(op_Proj,   gen_Proj);
+       be_set_transform_function(op_Phi,    gen_Phi);
+       be_set_transform_function(op_Return, gen_Return);
+       be_set_transform_function(op_Shl,    gen_Shl);
+       be_set_transform_function(op_Shr,    gen_Shr);
+       be_set_transform_function(op_Start,  gen_Start);
+       be_set_transform_function(op_Store,  gen_Store);
+       be_set_transform_function(op_Sub,    gen_Sub);
 }
 
 /**
@@ -278,6 +338,8 @@ static void TEMPLATE_register_transformers(void)
  */
 void TEMPLATE_transform_graph(ir_graph *irg)
 {
+       gp_regs_mode = TEMPLATE_reg_classes[CLASS_TEMPLATE_gp].mode;
+
        TEMPLATE_register_transformers();
        be_transform_graph(irg, NULL);
 }
index 29ab627..5dab854 100644 (file)
@@ -144,7 +144,7 @@ static TEMPLATE_isa_t TEMPLATE_isa_template = {
                NULL,                        /* main environment */
                7,                           /* costs for a spill instruction */
                5,                           /* costs for a reload instruction */
-               false,                       /* no custom abi handling */
+               true,                        /* no custom abi handling */
        },
 };
 
index 3f374d9..4a7aea0 100755 (executable)
@@ -1,3 +1,6 @@
+# Firm node specifications
+# The comments are in (standard python) restructured text format and are used
+# to generate documentation.
 from spec_util import abstract, setnodedefaults
 
 class Op(object):
@@ -85,7 +88,33 @@ class And(Binop):
        flags    = [ "commutative" ]
 
 class ASM(Op):
-       """executes assembler fragments of the target machine"""
+       """executes assembler fragments of the target machine.
+
+       The node contains a template for an assembler snippet. The compiler will
+       replace occurences of %0 to %9 with input/output registers,
+       %% with a single % char. Some backends allow additional specifiers (for
+       example %w3, %l3, %h3 on x86 to get a 16bit, 8hit low, 8bit high part
+       of a register).
+       After the replacements the text is emitted into the final assembly.
+
+       The clobber list contains names of registers which have an undefined value
+       after the assembler instruction is executed; it may also contain 'memory'
+       or 'cc' if global state/memory changes or the condition code registers
+       (some backends implicitely set cc, memory clobbers on all ASM statements).
+
+       Example (an i386 instruction)::
+
+               ASM(text="btsl %1, %0",
+                       input_constraints = ["=m", "r"],
+                       clobbers = ["cc"])
+
+       As there are no output, the %0 references the first input which is just an
+       address which the asm operation writes to. %1 references to an input which
+       is passed as a register. The condition code register has an unknown value
+       after the instruction.
+
+       (This format is inspired by the gcc extended asm syntax)
+       """
        mode             = "mode_T"
        arity            = "variable"
        flags            = [ "keep", "uses_memory" ]