Commit 737ff982 authored by Hannes Rapp's avatar Hannes Rapp
Browse files

- added emit_section_sparc to begnuas

- fixed register spilling & register specs

[r27450]
parent 1c551372
......@@ -102,6 +102,55 @@ static void emit_section_macho(be_gas_section_t section)
}
}
static void emit_section_sparc(be_gas_section_t section, const ir_entity *entity)
{
be_gas_section_t base = section & GAS_SECTION_TYPE_MASK;
be_gas_section_t flags = section & ~GAS_SECTION_TYPE_MASK;
static const char *const basename[] = {
"text", "data", "rodata", "bss", "ctors", "dtors"
};
if (current_section == section && !(section & GAS_SECTION_FLAG_COMDAT))
return;
current_section = section;
be_emit_cstring("\t.section\t\".");
/* Part1: section-name */
if (flags & GAS_SECTION_FLAG_TLS)
be_emit_char('t');
assert(base < sizeof(basename)/sizeof(basename[0]));
be_emit_string(basename[base]);
if (flags & GAS_SECTION_FLAG_COMDAT) {
be_emit_char('.');
be_gas_emit_entity(entity);
}
be_emit_char('"');
/* for the simple sections we're done here */
if (flags == 0)
goto end;
be_emit_cstring(",#alloc");
switch (base) {
case GAS_SECTION_TEXT: be_emit_cstring(",#execinstr"); break;
case GAS_SECTION_DATA:
case GAS_SECTION_BSS: be_emit_cstring(",#write"); break;
default:
/* nothing */
break;
}
if (flags & GAS_SECTION_FLAG_TLS) {
be_emit_cstring(",#tls");
}
end:
be_emit_char('\n');
be_emit_write_line();
}
static void emit_section(be_gas_section_t section, const ir_entity *entity)
{
be_gas_section_t base = section & GAS_SECTION_TYPE_MASK;
......@@ -116,6 +165,9 @@ static void emit_section(be_gas_section_t section, const ir_entity *entity)
if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O) {
emit_section_macho(section);
return;
} else if(be_gas_object_file_format == OBJECT_FILE_FORMAT_ELF_SPARC) {
emit_section_sparc(section, entity);
return;
}
if (current_section == section && !(section & GAS_SECTION_FLAG_COMDAT))
......@@ -185,6 +237,8 @@ static void emit_section(be_gas_section_t section, const ir_entity *entity)
be_emit_write_line();
}
void be_gas_emit_switch_section(be_gas_section_t section)
{
/* you have to produce a switch_section call with entity manually
......@@ -470,6 +524,7 @@ void be_gas_emit_function_prolog(const ir_entity *entity, unsigned po2alignment)
switch (be_gas_object_file_format) {
case OBJECT_FILE_FORMAT_ELF:
case OBJECT_FILE_FORMAT_ELF_SPARC:
be_emit_cstring("\t.type\t");
be_gas_emit_entity(entity);
be_emit_cstring(", ");
......@@ -1316,6 +1371,7 @@ static void emit_common(const ir_entity *entity)
be_emit_write_line();
return;
case OBJECT_FILE_FORMAT_ELF:
case OBJECT_FILE_FORMAT_ELF_SPARC:
be_emit_cstring("\t.comm ");
be_gas_emit_entity(entity);
be_emit_irprintf(",%u,%u\n", size, alignment);
......@@ -1348,6 +1404,7 @@ static void emit_local_common(const ir_entity *entity)
be_emit_write_line();
return;
case OBJECT_FILE_FORMAT_ELF:
case OBJECT_FILE_FORMAT_ELF_SPARC:
be_emit_cstring("\t.local ");
be_gas_emit_entity(entity);
be_emit_cstring("\n");
......
......@@ -52,17 +52,20 @@ typedef enum object_file_format_t {
OBJECT_FILE_FORMAT_ELF, /**< Executable and Linkable Format (unixes) */
OBJECT_FILE_FORMAT_COFF, /**< Common Object File Format (Windows) */
OBJECT_FILE_FORMAT_MACH_O, /**< Mach Object File Format (OS/X) */
OBJECT_FILE_FORMAT_LAST = OBJECT_FILE_FORMAT_MACH_O
OBJECT_FILE_FORMAT_ELF_SPARC, /**< Sparc variant of ELF */
OBJECT_FILE_FORMAT_LAST = OBJECT_FILE_FORMAT_ELF_SPARC
} object_file_format_t;
/** The variable where the GAS dialect is stored. */
extern object_file_format_t be_gas_object_file_format;
extern bool be_gas_emit_types;
/**
* the .type directive needs to specify @function, #function or %function
* depending on the target architecture (yay)
*/
extern char be_gas_elf_type_char;
extern char be_gas_elf_type_char;
/**
* Generate all entities.
......
......@@ -235,7 +235,7 @@ static void sparc_emit_cfop_target(const ir_node *node)
*/
static void sparc_emit_entity(ir_entity *entity)
{
be_emit_ident(get_entity_ld_ident(entity));
be_gas_emit_entity(entity);
}
/***********************************************************************************
......@@ -383,20 +383,22 @@ static void emit_be_Perm(const ir_node *irn)
static void emit_sparc_SymConst(const ir_node *irn)
{
const sparc_symconst_attr_t *attr = get_sparc_symconst_attr_const(irn);
ident *id_symconst = get_entity_ident(attr->entity);
const char *label = get_id_str(id_symconst);
//sethi %hi(const32),%reg
//or %reg,%lo(const32),%reg
be_emit_irprintf("\tsethi %%hi(%s), ", label);
be_emit_cstring("\tsethi %hi(");
be_gas_emit_entity(attr->entity);
be_emit_cstring("), ");
sparc_emit_dest_register(irn, 0);
be_emit_cstring("\n ");
// TODO: could be combined with the following load/store instruction
be_emit_cstring("\tor ");
sparc_emit_dest_register(irn, 0);
be_emit_irprintf(", %%lo(%s), ", label);
be_emit_cstring(", %lo(");
be_gas_emit_entity(attr->entity);
be_emit_cstring("), ");
sparc_emit_dest_register(irn, 0);
be_emit_finish_line_gas(irn);
}
......@@ -729,6 +731,7 @@ void sparc_gen_routine(const sparc_code_gen_t *cg, ir_graph *irg)
int i, n;
be_gas_elf_type_char = '#';
be_gas_object_file_format = OBJECT_FILE_FORMAT_ELF_SPARC;
/* register all emitter functions */
sparc_register_emitters();
......
......@@ -117,12 +117,12 @@ $mode_fp = "mode_D";
{ name => "g7", realname => "g7", type => 4 }, # reserved by SPARC ABI
# window's out registers
{ name => "o0", realname => "o0", type => 0 }, # param 1 / return value from callee
{ name => "o1", realname => "o1", type => 0 }, # param 2
{ name => "o2", realname => "o2", type => 0 }, # param 3
{ name => "o3", realname => "o3", type => 0 }, # param 4
{ name => "o4", realname => "o4", type => 0 }, # param 5
{ name => "o5", realname => "o5", type => 0 }, # param 6
{ name => "o0", realname => "o0", type => 1 }, # param 1 / return value from callee
{ name => "o1", realname => "o1", type => 1 }, # param 2
{ name => "o2", realname => "o2", type => 1 }, # param 3
{ name => "o3", realname => "o3", type => 1 }, # param 4
{ name => "o4", realname => "o4", type => 1 }, # param 5
{ name => "o5", realname => "o5", type => 1 }, # param 6
{ name => "sp", realname => "sp", type => 4 }, # our stackpointer
{ name => "o7", realname => "o6", type => 4 }, # temp. value / address of CALL instr.
......@@ -137,12 +137,12 @@ $mode_fp = "mode_D";
{ name => "l7", realname => "l7", type => 0 },
# window's in registers
{ name => "i0", realname => "i0", type => 1 }, # incoming param1 / return value to caller
{ name => "i1", realname => "i1", type => 1 }, # param 2
{ name => "i2", realname => "i2", type => 1 }, # param 3
{ name => "i3", realname => "i3", type => 1 }, # param 4
{ name => "i4", realname => "i4", type => 1 }, # param 5
{ name => "i5", realname => "i5", type => 1 }, # param 6
{ name => "i0", realname => "i0", type => 0 }, # incoming param1 / return value to caller
{ name => "i1", realname => "i1", type => 0 }, # param 2
{ name => "i2", realname => "i2", type => 0 }, # param 3
{ name => "i3", realname => "i3", type => 0 }, # param 4
{ name => "i4", realname => "i4", type => 0 }, # param 5
{ name => "i5", realname => "i5", type => 0 }, # param 6
{ name => "fp", realname => "fp", type => 4 }, # our framepointer
{ name => "i7", realname => "i7", type => 4 }, # return address - 8
{ mode => $mode_gp }
......@@ -585,6 +585,16 @@ UMul => {
emit =>'. umul %S1, %R2I, %D1'
},
UDiv => {
irn_flags => "R",
mode => $mode_gp,
comment => "construct Div: Div(a, b) = a / b",
reg_req => { in => [ "gp", "gp" ], out => [ "gp" ] },
outs => [ "res" ],
constructors => \%binop_operand_constructors,
emit =>'. udiv %S1, %R2I, %D1'
},
Minus => {
irn_flags => "R",
mode => $mode_gp,
......
......@@ -278,7 +278,6 @@ static ir_node *gen_Store(ir_node *node)
* @return the created sparc Mul node
*/
static ir_node *gen_Mul(ir_node *node) {
ir_node *block = be_transform_node(get_nodes_block(node));
ir_mode *mode = get_irn_mode(node);
dbg_info *dbgi = get_irn_dbg_info(node);
......@@ -292,13 +291,34 @@ static ir_node *gen_Mul(ir_node *node) {
assert(mode_is_data(mode));
mul = gen_helper_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, new_bd_sparc_UMul_reg, new_bd_sparc_UMul_imm);
// TODO: throws an error - check why
proj_res_low = new_rd_Proj(dbgi, mul, mode_Iu, pn_sparc_UMul_low);
return proj_res_low;
//return gen_helper_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, new_bd_sparc_Mul_reg, new_bd_sparc_Mul_imm);
}
/**
* Creates an sparc Div.
*
* @return the created sparc Div node
*/
static ir_node *gen_Div(ir_node *node) {
ir_mode *mode = get_irn_mode(node);
dbg_info *dbgi = get_irn_dbg_info(node);
//ir_node *proj_res_low;
if (mode_is_float(mode))
panic("FP not supported yet");
return gen_helper_binop(node, MATCH_SIZE_NEUTRAL, new_bd_sparc_UDiv_reg, new_bd_sparc_UDiv_imm);
//proj_res = new_rd_Proj(dbgi, mul, mode_Iu, pn_sparc_UDiv_res);
//return proj_res;
//return gen_helper_binop(node, MATCH_COMMUTATIVE | MATCH_SIZE_NEUTRAL, new_bd_sparc_Mul_reg, new_bd_sparc_Mul_imm);
}
/**
* transform abs node:
* mov a, b
......@@ -972,6 +992,7 @@ void sparc_register_transformers(void)
set_transformer(op_Jmp, gen_Jmp);
set_transformer(op_Mul, gen_Mul);
set_transformer(op_Div, gen_Div);
set_transformer(op_Abs, gen_Abs);
set_transformer(op_Shl, gen_Shl);
set_transformer(op_Shr, gen_Shr);
......
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