Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
21762fc6
Commit
21762fc6
authored
Aug 09, 2010
by
Matthias Braun
Browse files
sparc: redo and improve sparc immediate handling (low-part after sethi is now omitted if it is 0)
[r27918]
parent
0651be96
Changes
6
Hide whitespace changes
Inline
Side-by-side
ir/be/sparc/sparc_emitter.c
View file @
21762fc6
...
...
@@ -111,9 +111,15 @@ static const arch_register_t *get_out_reg(const ir_node *node, int pos)
void
sparc_emit_immediate
(
const
ir_node
*
node
)
{
int
const
val
=
get_sparc_attr_const
(
node
)
->
immediate_value
;
assert
(
-
4096
<=
val
&&
val
<
4096
);
be_emit_irprintf
(
"%d"
,
val
);
int32_t
value
=
get_sparc_attr_const
(
node
)
->
immediate_value
;
assert
(
-
4096
<=
value
&&
value
<
4096
);
be_emit_irprintf
(
"%d"
,
value
);
}
void
sparc_emit_high_immediate
(
const
ir_node
*
node
)
{
uint32_t
value
=
(
uint32_t
)
get_sparc_attr_const
(
node
)
->
immediate_value
;
be_emit_irprintf
(
"%%hi(0x%X)"
,
value
);
}
void
sparc_emit_source_register
(
const
ir_node
*
node
,
int
pos
)
...
...
@@ -329,31 +335,6 @@ static void emit_sparc_Save(const ir_node *irn)
be_emit_finish_line_gas
(
irn
);
}
/**
* emits code to load hi 22 bit of a constant
*/
static
void
emit_sparc_HiImm
(
const
ir_node
*
irn
)
{
const
sparc_attr_t
*
attr
=
get_sparc_attr_const
(
irn
);
be_emit_cstring
(
"
\t
sethi "
);
be_emit_irprintf
(
"%%hi(%d), "
,
attr
->
immediate_value
);
sparc_emit_dest_register
(
irn
,
0
);
be_emit_finish_line_gas
(
irn
);
}
/**
* emits code to load lo 10bits of a constant
*/
static
void
emit_sparc_LoImm
(
const
ir_node
*
irn
)
{
const
sparc_attr_t
*
attr
=
get_sparc_attr_const
(
irn
);
be_emit_cstring
(
"
\t
or "
);
sparc_emit_source_register
(
irn
,
0
);
be_emit_irprintf
(
", %%lo(%d), "
,
attr
->
immediate_value
);
sparc_emit_dest_register
(
irn
,
0
);
be_emit_finish_line_gas
(
irn
);
}
/**
* emits code for mulh
*/
...
...
@@ -849,8 +830,6 @@ static void sparc_register_emitters(void)
set_emitter
(
op_sparc_Call
,
emit_sparc_Call
);
set_emitter
(
op_sparc_fbfcc
,
emit_sparc_fbfcc
);
set_emitter
(
op_sparc_FrameAddr
,
emit_sparc_FrameAddr
);
set_emitter
(
op_sparc_HiImm
,
emit_sparc_HiImm
);
set_emitter
(
op_sparc_LoImm
,
emit_sparc_LoImm
);
set_emitter
(
op_sparc_Mulh
,
emit_sparc_Mulh
);
set_emitter
(
op_sparc_Save
,
emit_sparc_Save
);
set_emitter
(
op_sparc_SDiv
,
emit_sparc_SDiv
);
...
...
ir/be/sparc/sparc_emitter.h
View file @
21762fc6
...
...
@@ -35,6 +35,7 @@
#include "bearch_sparc_t.h"
void
sparc_emit_immediate
(
const
ir_node
*
node
);
void
sparc_emit_high_immediate
(
const
ir_node
*
node
);
void
sparc_emit_mode
(
const
ir_node
*
node
);
void
sparc_emit_source_register
(
const
ir_node
*
node
,
int
pos
);
void
sparc_emit_reg_or_imm
(
const
ir_node
*
node
,
int
pos
);
...
...
ir/be/sparc/sparc_new_nodes.c
View file @
21762fc6
...
...
@@ -147,7 +147,7 @@ static void sparc_dump_node(FILE *F, ir_node *n, dump_reason_t reason)
}
}
static
void
sparc_set_attr_imm
(
ir_node
*
res
,
int
immediate_value
)
static
void
sparc_set_attr_imm
(
ir_node
*
res
,
int
32_t
immediate_value
)
{
sparc_attr_t
*
attr
=
get_irn_generic_attr
(
res
);
attr
->
immediate_value
=
immediate_value
;
...
...
ir/be/sparc/sparc_nodes_attr.h
View file @
21762fc6
...
...
@@ -26,6 +26,7 @@
#define FIRM_BE_SPARC_SPARC_NODES_ATTR_H
#include "../bearch.h"
#include <stdint.h>
typedef
struct
sparc_attr_t
sparc_attr_t
;
...
...
@@ -36,7 +37,7 @@ struct sparc_attr_t
{
except_attr
exc
;
/**< the exception attribute. MUST be the first one. */
const
arch_register_req_t
**
in_req
;
/**< register requirements for arguments */
int
immediate_value
;
/* immediate values */
int
32_t
immediate_value
;
/* immediate values */
bool
is_load_store
;
ir_entity
*
immediate_value_entity
;
/* hack for now */
...
...
ir/be/sparc/sparc_spec.pl
View file @
21762fc6
...
...
@@ -130,6 +130,7 @@ $state = 32; # register represents a state
D5
=>
"
${arch}
_emit_dest_register(node, 4);
",
D6
=>
"
${arch}
_emit_dest_register(node, 5);
",
IM
=>
"
${arch}
_emit_immediate(node);
",
HIM
=>
"
${arch}
_emit_high_immediate(node);
",
LM
=>
"
${arch}
_emit_load_mode(node);
",
SM
=>
"
${arch}
_emit_store_mode(node);
",
FLSM
=>
"
${arch}
_emit_float_load_store_mode(node);
",
...
...
@@ -179,7 +180,7 @@ $default_copy_attr = "sparc_copy_attr";
my
%cmp_operand_constructors
=
(
imm
=>
{
attr
=>
"
int immediate_value
",
attr
=>
"
int
32_t
immediate_value
",
custominit
=>
"
sparc_set_attr_imm(res, immediate_value);
",
reg_req
=>
{
in
=>
[
"
gp
"
],
out
=>
[
"
flags
"
]
},
ins
=>
[
"
left
"
],
...
...
@@ -192,7 +193,7 @@ my %cmp_operand_constructors = (
my
%unop_operand_constructors
=
(
imm
=>
{
attr
=>
"
int immediate_value
",
attr
=>
"
int
32_t
immediate_value
",
custominit
=>
"
sparc_set_attr_imm(res, immediate_value);
",
reg_req
=>
{
in
=>
[]
,
out
=>
[
"
gp
"
]
},
},
...
...
@@ -203,7 +204,7 @@ my %unop_operand_constructors = (
my
%binop_operand_constructors
=
(
imm
=>
{
attr
=>
"
int immediate_value
",
attr
=>
"
int
32_t
immediate_value
",
custominit
=>
"
sparc_set_attr_imm(res, immediate_value);
",
reg_req
=>
{
in
=>
[
"
gp
"
],
out
=>
[
"
gp
"
]
},
ins
=>
[
"
left
"
],
...
...
@@ -286,25 +287,14 @@ Ld => {
emit
=>
'
. ld%LM [%S1%O], %D1
'
},
HiImm
=>
{
irn_flags
=>
[
"
rematerializable
"
],
state
=>
"
exc_pinned
",
outs
=>
[
"
res
"
],
mode
=>
$mode_gp
,
reg_req
=>
{
in
=>
[]
,
out
=>
[
"
gp
"
]
},
attr
=>
"
int immediate_value
",
custominit
=>
"
sparc_set_attr_imm(res, immediate_value);
",
},
LoImm
=>
{
irn_flags
=>
[
"
rematerializable
"
],
state
=>
"
exc_pinned
",
ins
=>
[
"
hireg
"
],
outs
=>
[
"
res
"
],
mode
=>
$mode_gp
,
reg_req
=>
{
in
=>
[
"
gp
"
],
out
=>
[
"
gp
"
]
},
attr
=>
"
int immediate_value
",
SetHi
=>
{
irn_flags
=>
[
"
rematerializable
"
],
outs
=>
[
"
res
"
],
mode
=>
$mode_gp
,
reg_req
=>
{
in
=>
[]
,
out
=>
[
"
gp
"
]
},
attr
=>
"
int32_t immediate_value
",
custominit
=>
"
sparc_set_attr_imm(res, immediate_value);
",
emit
=>
'
. sethi %HIM, %D1
'
},
St
=>
{
...
...
@@ -326,14 +316,6 @@ St => {
emit
=>
'
. st%SM %S2, [%S1%O]
'
},
Mov
=>
{
irn_flags
=>
[
"
rematerializable
"
],
arity
=>
"
variable
",
emit
=>
'
. mov %R1I, %D1
',
mode
=>
$mode_gp
,
constructors
=>
\
%unop_operand_constructors
,
},
Save
=>
{
reg_req
=>
{
in
=>
[
"
sp
",
"
none
"],
...
...
ir/be/sparc/sparc_transform.c
View file @
21762fc6
...
...
@@ -33,6 +33,7 @@
#include "iredges.h"
#include "ircons.h"
#include "irprintf.h"
#include "iroptimize.h"
#include "dbginfo.h"
#include "iropt_t.h"
#include "debug.h"
...
...
@@ -151,50 +152,6 @@ static ir_node *gen_extension(dbg_info *dbgi, ir_node *block, ir_node *op,
}
}
/**
* Creates a possible DAG for a constant.
*/
static
ir_node
*
create_const_graph_value
(
dbg_info
*
dbgi
,
ir_node
*
block
,
long
value
)
{
ir_node
*
result
;
/* we need to load hi & lo separately */
if
(
value
<
-
4096
||
value
>
4095
)
{
ir_node
*
hi
=
new_bd_sparc_HiImm
(
dbgi
,
block
,
(
int
)
value
);
result
=
new_bd_sparc_LoImm
(
dbgi
,
block
,
hi
,
value
);
be_dep_on_frame
(
hi
);
}
else
{
result
=
new_bd_sparc_Mov_imm
(
dbgi
,
block
,
(
int
)
value
);
be_dep_on_frame
(
result
);
}
return
result
;
}
/**
* Create a DAG constructing a given Const.
*
* @param irn a Firm const
*/
static
ir_node
*
create_const_graph
(
ir_node
*
irn
,
ir_node
*
block
)
{
tarval
*
tv
=
get_Const_tarval
(
irn
);
ir_mode
*
mode
=
get_tarval_mode
(
tv
);
dbg_info
*
dbgi
=
get_irn_dbg_info
(
irn
);
long
value
;
if
(
mode_is_reference
(
mode
))
{
/* SPARC V8 is 32bit, so we can safely convert a reference tarval into Iu */
assert
(
get_mode_size_bits
(
mode
)
==
get_mode_size_bits
(
mode_gp
));
tv
=
tarval_convert_to
(
tv
,
mode_gp
);
}
value
=
get_tarval_long
(
tv
);
return
create_const_graph_value
(
dbgi
,
block
,
value
);
}
typedef
enum
{
MATCH_NONE
=
0
,
MATCH_COMMUTATIVE
=
1
<<
0
,
/**< commutative operation. */
...
...
@@ -202,7 +159,7 @@ typedef enum {
typedef
ir_node
*
(
*
new_binop_reg_func
)
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op1
,
ir_node
*
op2
);
typedef
ir_node
*
(
*
new_binop_fp_func
)
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
);
typedef
ir_node
*
(
*
new_binop_imm_func
)
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op1
,
int
simm13
);
typedef
ir_node
*
(
*
new_binop_imm_func
)
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op1
,
int
32_t
immediate
);
typedef
ir_node
*
(
*
new_unop_fp_func
)
(
dbg_info
*
dbgi
,
ir_node
*
block
,
ir_node
*
op1
,
ir_mode
*
mode
);
/**
...
...
@@ -211,14 +168,12 @@ typedef ir_node* (*new_unop_fp_func) (dbg_info *dbgi, ir_node *block, ir_node *o
*/
static
bool
is_imm_encodeable
(
const
ir_node
*
node
)
{
long
val
;
long
value
;
if
(
!
is_Const
(
node
))
return
false
;
val
=
get_tarval_long
(
get_Const_tarval
(
node
));
return
-
4096
<=
val
&&
val
<=
4095
;
value
=
get_tarval_long
(
get_Const_tarval
(
node
));
return
-
4096
<=
value
&&
value
<=
4095
;
}
/**
...
...
@@ -710,19 +665,15 @@ static ir_entity *create_float_const_entity(tarval *tv)
return
entity
;
}
/**
* Transforms a Const node.
*
* @param node the ir Const node
* @return The transformed sparc node.
*/
static
ir_node
*
gen_Const
(
ir_node
*
node
)
{
ir_node
*
block
=
be_transform_node
(
get_nodes_block
(
node
));
ir_mode
*
mode
=
get_irn_mode
(
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
);
tarval
*
tv
;
long
value
;
if
(
mode_is_float
(
mode
))
{
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
tarval
*
tv
=
get_Const_tarval
(
node
);
ir_entity
*
entity
=
create_float_const_entity
(
tv
);
ir_node
*
addr
=
make_addr
(
dbgi
,
entity
);
...
...
@@ -735,12 +686,21 @@ static ir_node *gen_Const(ir_node *node)
return
proj
;
}
/* use the 0 register instead of a 0-constant */
if
(
is_Const_null
(
node
))
{
tv
=
get_Const_tarval
(
node
);
value
=
get_tarval_long
(
tv
);
if
(
value
==
0
)
{
return
get_g0
();
}
else
if
(
-
4096
<=
value
&&
value
<=
4095
)
{
return
new_bd_sparc_Or_imm
(
dbgi
,
block
,
get_g0
(),
value
);
}
else
{
ir_node
*
hi
=
new_bd_sparc_SetHi
(
dbgi
,
block
,
value
);
be_dep_on_frame
(
hi
);
if
((
value
&
0x3ff
)
!=
0
)
{
return
new_bd_sparc_Or_imm
(
dbgi
,
block
,
hi
,
value
&
0x3ff
);
}
else
{
return
hi
;
}
}
return
create_const_graph
(
node
,
block
);
}
static
ir_mode
*
get_cmp_mode
(
ir_node
*
b_value
)
...
...
@@ -773,7 +733,7 @@ static ir_node *gen_Cond(ir_node *node)
// switch/case jumps
if
(
mode
!=
mode_b
)
{
panic
(
"SwitchJmp not
suppor
ted yet"
);
panic
(
"SwitchJ
u
mp not
implemen
ted yet"
);
}
// regular if/else jumps
...
...
@@ -965,10 +925,6 @@ static ir_node *gen_Conv(ir_node *node)
static
ir_node
*
gen_Unknown
(
ir_node
*
node
)
{
ir_node
*
block
=
get_nodes_block
(
node
);
ir_node
*
new_block
=
be_transform_node
(
block
);
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
/* just produce a 0 */
ir_mode
*
mode
=
get_irn_mode
(
node
);
if
(
mode_is_float
(
mode
))
{
...
...
@@ -976,7 +932,7 @@ static ir_node *gen_Unknown(ir_node *node)
be_dep_on_frame
(
node
);
return
node
;
}
else
if
(
mode_needs_gp_reg
(
mode
))
{
return
create_const_graph_value
(
dbgi
,
new_block
,
0
);
return
get_g0
(
);
}
panic
(
"Unexpected Unknown mode"
);
...
...
@@ -1899,6 +1855,9 @@ void sparc_transform_graph(sparc_code_gen_t *cg)
node_to_stack
=
NULL
;
be_add_missing_keeps
(
irg
);
/* do code placement, to optimize the position of constants */
place_code
(
cg
->
irg
);
}
void
sparc_init_transform
(
void
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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