Commit cd1ba320 authored by Matthias Braun's avatar Matthias Braun
Browse files

update TEMPLATE backend

Still broken for anything except int f(void) { return 0; } though...
parent 16a8ee53
......@@ -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 => {
......
......@@ -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);
}
......
......@@ -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 */
},
};
......
# 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" ]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment