Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
737ff982
Commit
737ff982
authored
Apr 27, 2010
by
Hannes Rapp
Browse files
- added emit_section_sparc to begnuas
- fixed register spilling & register specs [r27450]
parent
1c551372
Changes
5
Hide whitespace changes
Inline
Side-by-side
ir/be/begnuas.c
View file @
737ff982
...
...
@@ -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
"
);
...
...
ir/be/begnuas.h
View file @
737ff982
...
...
@@ -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.
...
...
ir/be/sparc/sparc_emitter.c
View file @
737ff982
...
...
@@ -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_id
ent
(
entity
)
)
;
be_
gas_
emit_ent
ity
(
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
(
"
\t
sethi %%hi(%s), "
,
label
);
be_emit_cstring
(
"
\t
sethi %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
(
"
\t
or "
);
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
();
...
...
ir/be/sparc/sparc_spec.pl
View file @
737ff982
...
...
@@ -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
,
...
...
ir/be/sparc/sparc_transform.c
View file @
737ff982
...
...
@@ -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
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment