Commit 9697d318 authored by Matthias Braun's avatar Matthias Braun
Browse files

sparc: initial ASM support (no constraints, no clobbers)

parent 302e20bf
......@@ -284,7 +284,7 @@ static bool emits_multiple_instructions(const ir_node *node)
return is_sparc_SMulh(node) || is_sparc_UMulh(node)
|| is_sparc_SDiv(node) || is_sparc_UDiv(node)
|| be_is_MemPerm(node) || be_is_Perm(node)
|| is_sparc_SubSP(node);
|| is_sparc_SubSP(node) || is_sparc_ASM(node);
}
static bool uses_reg(const ir_node *node, unsigned reg_index, unsigned width)
......@@ -709,6 +709,23 @@ static void emit_be_IncSP(const ir_node *irn)
sparc_emitf(irn, "%s %S0, %d, %D0", insn, offset);
}
static void emit_sparc_ASM(const ir_node *node)
{
be_emit_cstring("#APP\n");
be_emit_write_line();
const sparc_asm_attr_t *attr = get_sparc_asm_attr_const(node);
const char *s = get_id_str(attr->text);
if (s[0] != '\t')
be_emit_char('\t');
be_emit_string(s);
be_emit_cstring("\n#NO_APP\n");
be_emit_write_line();
}
/**
* Emits code for stack space management.
*/
......@@ -1269,6 +1286,7 @@ static void sparc_register_emitters(void)
be_set_emitter(op_be_IncSP, emit_be_IncSP);
be_set_emitter(op_be_MemPerm, emit_be_MemPerm);
be_set_emitter(op_be_Perm, emit_be_Perm);
be_set_emitter(op_sparc_ASM, emit_sparc_ASM);
be_set_emitter(op_sparc_Ba, emit_sparc_Ba);
be_set_emitter(op_sparc_Bicc, emit_sparc_Bicc);
be_set_emitter(op_sparc_Call, emit_sparc_Call);
......
......@@ -208,6 +208,18 @@ const sparc_fp_conv_attr_t *get_sparc_fp_conv_attr_const(const ir_node *node)
return (const sparc_fp_conv_attr_t*) get_irn_generic_attr_const(node);
}
sparc_asm_attr_t *get_sparc_asm_attr(ir_node *node)
{
assert(is_sparc_ASM(node));
return (sparc_asm_attr_t*)get_irn_generic_attr(node);
}
const sparc_asm_attr_t *get_sparc_asm_attr_const(const ir_node *node)
{
assert(is_sparc_ASM(node));
return (const sparc_asm_attr_t*)get_irn_generic_attr_const(node);
}
/**
* Initializes the nodes attributes.
*/
......@@ -266,6 +278,12 @@ static void init_sparc_switch_jmp_attributes(ir_node *node,
}
}
static void init_sparc_asm_attributes(ir_node *node, ident *text)
{
sparc_asm_attr_t *attr = get_sparc_asm_attr(node);
attr->text = text;
}
/**
* copies sparc attributes of node
*/
......@@ -346,5 +364,15 @@ static int cmp_attr_sparc_fp_conv(const ir_node *a, const ir_node *b)
|| attr_a->dest_mode != attr_b->dest_mode;
}
static int cmp_attr_sparc_asm(const ir_node *a, const ir_node *b)
{
if (cmp_attr_sparc(a, b))
return 1;
const sparc_asm_attr_t *attr_a = get_sparc_asm_attr_const(a);
const sparc_asm_attr_t *attr_b = get_sparc_asm_attr_const(b);
return attr_a->text != attr_b->text;
}
/* Include the generated constructor functions */
#include "gen_sparc_new_nodes.c.inl"
......@@ -36,6 +36,9 @@ const sparc_fp_attr_t *get_sparc_fp_attr_const(const ir_node *node);
sparc_fp_conv_attr_t *get_sparc_fp_conv_attr(ir_node *node);
const sparc_fp_conv_attr_t *get_sparc_fp_conv_attr_const(const ir_node *node);
sparc_asm_attr_t *get_sparc_asm_attr(ir_node *node);
const sparc_asm_attr_t *get_sparc_asm_attr_const(const ir_node *node);
/* Include the generated headers */
#include "gen_sparc_new_nodes.h"
......
......@@ -81,6 +81,12 @@ struct sparc_switch_jmp_attr_t {
ir_entity *table_entity;
};
typedef struct sparc_asm_attr_t sparc_asm_attr_t;
struct sparc_asm_attr_t {
sparc_attr_t base;
ident *text;
};
enum n_sparc_Return {
n_sparc_Return_mem = 0,
n_sparc_Return_sp = 1,
......
......@@ -112,12 +112,15 @@ $default_copy_attr = "sparc_copy_attr";
"\tinit_sparc_switch_jmp_attributes(res, table, jump_table);\n",
sparc_fp_attr_t => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);\n".
"\tinit_sparc_fp_attributes(res, fp_mode);\n",
sparc_fp_conv_attr_t => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);".
sparc_fp_conv_attr_t => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);\n".
"\tinit_sparc_fp_conv_attributes(res, src_mode, dest_mode);\n",
sparc_asm_attr_t => "\tinit_sparc_attributes(res, irn_flags_, in_reqs, n_res);\n".
"\tinit_sparc_asm_attributes(res, text);",
);
%compare_attr = (
sparc_attr_t => "cmp_attr_sparc",
sparc_asm_attr_t => "cmp_attr_sparc_asm",
sparc_fp_attr_t => "cmp_attr_sparc_fp",
sparc_fp_conv_attr_t => "cmp_attr_sparc_fp_conv",
sparc_jmp_cond_attr_t => "cmp_attr_sparc_jmp_cond",
......@@ -238,6 +241,15 @@ my %float_unop_constructors = (
%nodes = (
ASM => {
state => "exc_pinned",
reg_req => { in => [ "none" ], out => [ "none" ] },
ins => [ "mem" ],
outs => [ "M" ],
attr => "ident *text",
attr_type => "sparc_asm_attr_t",
},
Add => {
irn_flags => [ "rematerializable" ],
mode => $mode_gp,
......
......@@ -468,6 +468,37 @@ only_offset:
address->offset = offset;
}
static ir_node *gen_ASM(ir_node *node)
{
size_t n_clobbers = get_ASM_n_clobbers(node);
size_t n_output_constraints = get_ASM_n_output_constraints(node);
size_t n_inputs = get_ASM_n_inputs(node);
if (n_clobbers != 0 || n_output_constraints != 0 || n_inputs != 0) {
panic("ASM with output constraints/input constraints or clobber not supported yet");
}
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *block = be_transform_node(get_nodes_block(node));
ident *text = get_ASM_text(node);
ir_node *mem = get_ASM_mem(node);
ir_node *new_mem = be_transform_node(mem);
return new_bd_sparc_ASM(dbgi, block, new_mem, text);
}
static ir_node *gen_Proj_ASM(ir_node *node)
{
long pn = get_Proj_proj(node);
ir_node *pred = get_Proj_pred(node);
ir_node *new_pred = be_transform_node(pred);
switch (pn) {
case 0:
return new_r_Proj(new_pred, mode_M, pn_sparc_ASM_M);
default:
panic("unexpected Proj from ASM found");
}
}
/**
* Creates an sparc Add.
*
......@@ -2285,6 +2316,8 @@ static ir_node *gen_Proj(ir_node *node)
ir_node *pred = get_Proj_pred(node);
switch (get_irn_opcode(pred)) {
case iro_ASM:
return gen_Proj_ASM(node);
case iro_Alloc:
return gen_Proj_Alloc(node);
case iro_Store:
......@@ -2338,6 +2371,7 @@ static void sparc_register_transformers(void)
{
be_start_transform_setup();
be_set_transform_function(op_ASM, gen_ASM);
be_set_transform_function(op_Add, gen_Add);
be_set_transform_function(op_Alloc, gen_Alloc);
be_set_transform_function(op_And, gen_And);
......
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