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
aa5c48c2
Commit
aa5c48c2
authored
Feb 01, 2010
by
Hannes Rapp
Browse files
[r27015]
parent
4f644c28
Changes
7
Hide whitespace changes
Inline
Side-by-side
ir/be/sparc/bearch_sparc.c
View file @
aa5c48c2
...
...
@@ -65,6 +65,7 @@
#include "gen_sparc_regalloc_if.h"
#include "sparc_transform.h"
#include "sparc_emitter.h"
#include "sparc_map_regs.h"
DEBUG_ONLY
(
static
firm_dbg_module_t
*
dbg
=
NULL
;)
...
...
@@ -74,10 +75,22 @@ static arch_irn_class_t sparc_classify(const ir_node *irn)
return
0
;
}
static
ir_entity
*
sparc_get_frame_entity
(
const
ir_node
*
node
)
static
ir_entity
*
sparc_get_frame_entity
(
const
ir_node
*
irn
)
{
(
void
)
node
;
/* TODO: return the ir_entity assigned to the frame */
const
sparc_attr_t
*
attr
=
get_sparc_attr_const
(
irn
);
if
(
is_sparc_FrameAddr
(
irn
))
{
const
sparc_symconst_attr_t
*
attr
=
get_irn_generic_attr_const
(
irn
);
return
attr
->
entity
;
}
if
(
attr
->
is_load_store
)
{
const
sparc_load_store_attr_t
*
load_store_attr
=
get_sparc_load_store_attr_const
(
irn
);
if
(
load_store_attr
->
is_frame_entity
)
{
return
load_store_attr
->
entity
;
}
}
return
NULL
;
}
...
...
@@ -85,6 +98,7 @@ static void sparc_set_frame_entity(ir_node *node, ir_entity *ent)
{
(
void
)
node
;
(
void
)
ent
;
panic
(
"sparc_set_frame_entity() called. This should not happen."
);
/* TODO: set the ir_entity assigned to the frame */
}
...
...
@@ -94,9 +108,14 @@ static void sparc_set_frame_entity(ir_node *node, ir_entity *ent)
*/
static
void
sparc_set_frame_offset
(
ir_node
*
irn
,
int
offset
)
{
(
void
)
irn
;
(
void
)
offset
;
/* TODO: correct offset if irn accesses the stack */
if
(
is_sparc_FrameAddr
(
irn
))
{
sparc_symconst_attr_t
*
attr
=
get_irn_generic_attr
(
irn
);
attr
->
fp_offset
+=
offset
;
}
else
{
sparc_load_store_attr_t
*
attr
=
get_sparc_load_store_attr
(
irn
);
assert
(
attr
->
base
.
is_load_store
);
attr
->
offset
+=
offset
;
}
}
static
int
sparc_get_sp_bias
(
const
ir_node
*
irn
)
...
...
@@ -174,10 +193,86 @@ static void sparc_before_ra(void *self)
be_sched_fix_flags
(
cg
->
birg
,
&
sparc_reg_classes
[
CLASS_sparc_flags
],
&
sparc_flags_remat
);
}
/**
* transform reload node => load
*/
static
void
transform_Reload
(
ir_node
*
node
)
{
ir_graph
*
irg
=
get_irn_irg
(
node
);
ir_node
*
block
=
get_nodes_block
(
node
);
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
ptr
=
get_irg_frame
(
irg
);
ir_node
*
mem
=
get_irn_n
(
node
,
be_pos_Reload_mem
);
ir_mode
*
mode
=
get_irn_mode
(
node
);
ir_entity
*
entity
=
be_get_frame_entity
(
node
);
const
arch_register_t
*
reg
;
ir_node
*
proj
;
ir_node
*
load
;
ir_node
*
sched_point
=
sched_prev
(
node
);
load
=
new_bd_sparc_Load
(
dbgi
,
block
,
ptr
,
mem
,
mode
,
entity
,
false
,
0
,
true
);
sched_add_after
(
sched_point
,
load
);
sched_remove
(
node
);
proj
=
new_rd_Proj
(
dbgi
,
block
,
load
,
mode
,
pn_sparc_Load_res
);
reg
=
arch_get_irn_register
(
node
);
arch_set_irn_register
(
proj
,
reg
);
exchange
(
node
,
proj
);
}
/**
* transform spill node => store
*/
static
void
transform_Spill
(
ir_node
*
node
)
{
ir_graph
*
irg
=
get_irn_irg
(
node
);
ir_node
*
block
=
get_nodes_block
(
node
);
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
ptr
=
get_irg_frame
(
irg
);
ir_node
*
mem
=
new_NoMem
();
ir_node
*
val
=
get_irn_n
(
node
,
be_pos_Spill_val
);
ir_mode
*
mode
=
get_irn_mode
(
val
);
ir_entity
*
entity
=
be_get_frame_entity
(
node
);
ir_node
*
sched_point
;
ir_node
*
store
;
sched_point
=
sched_prev
(
node
);
store
=
new_bd_sparc_Store
(
dbgi
,
block
,
ptr
,
val
,
mem
,
mode
,
entity
,
false
,
0
,
true
);
sched_remove
(
node
);
sched_add_after
(
sched_point
,
store
);
exchange
(
node
,
store
);
}
/**
* walker to transform be_Spill and be_Reload nodes
*/
static
void
sparc_after_ra_walker
(
ir_node
*
block
,
void
*
data
)
{
ir_node
*
node
,
*
prev
;
(
void
)
data
;
for
(
node
=
sched_last
(
block
);
!
sched_is_begin
(
node
);
node
=
prev
)
{
prev
=
sched_prev
(
node
);
if
(
be_is_Reload
(
node
))
{
transform_Reload
(
node
);
}
else
if
(
be_is_Spill
(
node
))
{
transform_Spill
(
node
);
}
}
}
static
void
sparc_after_ra
(
void
*
self
)
{
(
void
)
self
;
/* Some stuff you need to do immediatly after register allocation */
sparc_code_gen_t
*
cg
=
self
;
be_coalesce_spillslots
(
cg
->
birg
);
irg_block_walk_graph
(
cg
->
irg
,
NULL
,
sparc_after_ra_walker
,
NULL
);
}
...
...
@@ -428,13 +523,17 @@ void sparc_get_call_abi(const void *self, ir_type *method_type,
be_abi_call_set_flags
(
abi
,
call_flags
,
&
sparc_abi_callbacks
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
/* TODO: implement register parameter: */
/* reg = get reg for param i; */
/* be_abi_call_param_reg(abi, i, reg); */
/* default: all parameters on stack */
tp
=
get_method_param_type
(
method_type
,
i
);
mode
=
get_type_mode
(
tp
);
be_abi_call_param_stack
(
abi
,
i
,
mode
,
4
,
0
,
0
);
/* pass args 0-5 via registers, remaining via stack */
if
(
i
<
6
)
{
be_abi_call_param_reg
(
abi
,
i
,
sparc_get_RegParam_reg
(
i
));
}
else
{
tp
=
get_method_param_type
(
method_type
,
i
);
mode
=
get_type_mode
(
tp
);
be_abi_call_param_stack
(
abi
,
i
,
mode
,
4
,
0
,
0
);
}
}
/* TODO: set correct return register */
...
...
ir/be/sparc/sparc_map_regs.c
0 → 100644
View file @
aa5c48c2
/*
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* Licensees holding valid libFirm Professional Edition licenses may use
* this file in accordance with the libFirm Commercial License.
* Agreement provided with the Software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/**
* @file
* @brief Register mapping for firm nodes. Stolen from bearch_firm :)
* @author Hannes Rapp
* @version $Id: sparc_map_regs.c 22754 2008-10-11 20:49:37Z matze $
*/
#include "config.h"
#include <stdlib.h>
#include "sparc_map_regs.h"
#include "sparc_new_nodes.h"
#include "gen_sparc_regalloc_if.h"
static
const
arch_register_t
*
gp_param_regs
[]
=
{
&
sparc_gp_regs
[
REG_O0
],
&
sparc_gp_regs
[
REG_O1
],
&
sparc_gp_regs
[
REG_O2
],
&
sparc_gp_regs
[
REG_O3
],
&
sparc_gp_regs
[
REG_O4
],
&
sparc_gp_regs
[
REG_O5
],
};
const
arch_register_t
*
sparc_get_RegParam_reg
(
int
n
)
{
assert
(
n
<
6
&&
n
>=
0
&&
"trying to get register for param >= 6"
);
return
gp_param_regs
[
n
];
}
ir/be/sparc/sparc_map_regs.h
0 → 100644
View file @
aa5c48c2
/*
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* Licensees holding valid libFirm Professional Edition licenses may use
* this file in accordance with the libFirm Commercial License.
* Agreement provided with the Software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/**
* @file
* @brief declarations for SPARC register allocation
* @author Hannes Rapp
* @version $Id: sparc_map_regs.h 26317 2009-08-05 10:53:46Z matze $
*/
#ifndef FIRM_BE_SPARC_SPARC_MAP_REGS_H
#define FIRM_BE_SPARC_SPARC_MAP_REGS_H
#include "irnode.h"
#include "set.h"
#include "../bearch.h"
#include "sparc_nodes_attr.h"
const
arch_register_t
*
sparc_get_RegParam_reg
(
int
n
);
#endif
ir/be/sparc/sparc_new_nodes.c
View file @
aa5c48c2
...
...
@@ -93,25 +93,42 @@ static void sparc_set_attr_imm(ir_node *res, int immediate_value)
attr
->
immediate_value
=
immediate_value
;
}
static
void
set_sparc_jmp_cond_proj_num
(
ir_node
*
node
,
int
proj_num
)
void
set_sparc_jmp_cond_proj_num
(
ir_node
*
node
,
int
proj_num
)
{
sparc_jmp_cond_attr_t
*
attr
=
get_sparc_jmp_cond_attr
(
node
);
attr
->
proj_num
=
proj_num
;
}
static
void
set_sparc_jmp_switch_n_projs
(
ir_node
*
node
,
int
n_projs
)
void
set_sparc_jmp_switch_n_projs
(
ir_node
*
node
,
int
n_projs
)
{
sparc_jmp_switch_attr_t
*
attr
=
get_sparc_jmp_switch_attr
(
node
);
attr
->
n_projs
=
n_projs
;
}
static
void
set_sparc_jmp_switch_default_proj_num
(
ir_node
*
node
,
long
def_proj_num
)
void
set_sparc_jmp_switch_default_proj_num
(
ir_node
*
node
,
long
def_proj_num
)
{
sparc_jmp_switch_attr_t
*
attr
=
get_sparc_jmp_switch_attr
(
node
);
attr
->
default_proj_num
=
def_proj_num
;
}
int
get_sparc_jmp_cond_proj_num
(
const
ir_node
*
node
)
{
const
sparc_jmp_cond_attr_t
*
attr
=
get_sparc_jmp_cond_attr_const
(
node
);
return
attr
->
proj_num
;
}
int
get_sparc_jmp_switch_n_projs
(
const
ir_node
*
node
)
{
const
sparc_jmp_switch_attr_t
*
attr
=
get_sparc_jmp_switch_attr_const
(
node
);
return
attr
->
n_projs
;
}
long
get_sparc_jmp_switch_default_proj_num
(
const
ir_node
*
node
)
{
const
sparc_jmp_switch_attr_t
*
attr
=
get_sparc_jmp_switch_attr_const
(
node
);
return
attr
->
default_proj_num
;
}
/* ATTRIBUTE GETTERS */
sparc_attr_t
*
get_sparc_attr
(
ir_node
*
node
)
{
...
...
@@ -297,37 +314,73 @@ static int cmp_attr_sparc(ir_node *a, ir_node *b)
{
const
sparc_attr_t
*
attr_a
=
get_sparc_attr_const
(
a
);
const
sparc_attr_t
*
attr_b
=
get_sparc_attr_const
(
b
);
(
void
)
attr_a
;
(
void
)
attr_b
;
return
0
;
return
attr_a
->
immediate_value
!=
attr_b
->
immediate_value
||
attr_a
->
is_load_store
!=
attr_b
->
is_load_store
;
}
/* CUSTOM ATTRIBUTE CMP FUNCTIONS */
static
int
cmp_attr_sparc_load_store
(
ir_node
*
a
,
ir_node
*
b
)
{
return
0
;
const
sparc_load_store_attr_t
*
attr_a
=
get_sparc_load_store_attr_const
(
a
);
const
sparc_load_store_attr_t
*
attr_b
=
get_sparc_load_store_attr_const
(
b
);
if
(
cmp_attr_sparc
(
a
,
b
))
return
1
;
return
attr_a
->
entity
!=
attr_b
->
entity
||
attr_a
->
entity_sign
!=
attr_b
->
entity_sign
||
attr_a
->
is_frame_entity
!=
attr_b
->
is_frame_entity
||
attr_a
->
load_store_mode
!=
attr_b
->
load_store_mode
||
attr_a
->
offset
!=
attr_b
->
offset
;
}
static
int
cmp_attr_sparc_symconst
(
ir_node
*
a
,
ir_node
*
b
)
{
return
0
;
const
sparc_symconst_attr_t
*
attr_a
=
get_sparc_symconst_attr_const
(
a
);
const
sparc_symconst_attr_t
*
attr_b
=
get_sparc_symconst_attr_const
(
b
);
if
(
cmp_attr_sparc
(
a
,
b
))
return
1
;
return
attr_a
->
entity
!=
attr_b
->
entity
||
attr_a
->
fp_offset
!=
attr_b
->
fp_offset
;
}
static
int
cmp_attr_sparc_jmp_cond
(
ir_node
*
a
,
ir_node
*
b
)
{
return
0
;
const
sparc_jmp_cond_attr_t
*
attr_a
=
get_sparc_jmp_cond_attr_const
(
a
);
const
sparc_jmp_cond_attr_t
*
attr_b
=
get_sparc_jmp_cond_attr_const
(
b
);
if
(
cmp_attr_sparc
(
a
,
b
))
return
1
;
return
attr_a
->
proj_num
!=
attr_b
->
proj_num
;
}
static
int
cmp_attr_sparc_jmp_switch
(
ir_node
*
a
,
ir_node
*
b
)
{
return
0
;
const
sparc_jmp_switch_attr_t
*
attr_a
=
get_sparc_jmp_switch_attr_const
(
a
);
const
sparc_jmp_switch_attr_t
*
attr_b
=
get_sparc_jmp_switch_attr_const
(
b
);
if
(
cmp_attr_sparc
(
a
,
b
))
return
1
;
return
attr_a
->
default_proj_num
!=
attr_b
->
default_proj_num
||
attr_a
->
n_projs
!=
attr_b
->
n_projs
;
}
static
int
cmp_attr_sparc_cmp
(
ir_node
*
a
,
ir_node
*
b
)
{
return
0
;
const
sparc_cmp_attr_t
*
attr_a
=
get_sparc_cmp_attr_const
(
a
);
const
sparc_cmp_attr_t
*
attr_b
=
get_sparc_cmp_attr_const
(
b
);
if
(
cmp_attr_sparc
(
a
,
b
))
return
1
;
return
attr_a
->
ins_permuted
!=
attr_b
->
ins_permuted
||
attr_a
->
is_unsigned
!=
attr_b
->
is_unsigned
;
}
/* Include the generated constructor functions */
...
...
ir/be/sparc/sparc_new_nodes.h
View file @
aa5c48c2
...
...
@@ -74,6 +74,38 @@ const arch_register_req_t *get_sparc_in_req(const ir_node *node, int pos);
*/
void
set_sparc_req_in
(
ir_node
*
node
,
const
arch_register_req_t
*
req
,
int
pos
);
/**
* Returns the proj num
*/
int
get_sparc_jmp_cond_proj_num
(
const
ir_node
*
node
);
/**
* Sets the proj num
*/
void
set_sparc_jmp_cond_proj_num
(
ir_node
*
node
,
int
proj_num
);
/**
* Returns the number of projs of a SwitchJmp.
*/
int
get_sparc_jmp_switch_n_projs
(
const
ir_node
*
node
);
/**
* Sets the number of projs of a SwitchJmp.
*/
void
set_sparc_jmp_switch_n_projs
(
ir_node
*
node
,
int
n_projs
);
/**
* Returns the default_proj_num.
*/
long
get_sparc_jmp_switch_default_proj_num
(
const
ir_node
*
node
);
/**
* Sets the default_proj_num.
*/
void
set_sparc_jmp_switch_default_proj_num
(
ir_node
*
node
,
long
default_proj_num
);
/* Include the generated headers */
#include "gen_sparc_new_nodes.h"
...
...
ir/be/sparc/sparc_spec.pl
View file @
aa5c48c2
...
...
@@ -107,44 +107,44 @@ $mode_fp = "mode_D";
# available SPARC registers: 8 globals, 24 window regs (8 ins, 8 outs, 8 locals)
%reg_classes
=
(
gp
=>
[
{
name
=>
"
g0
",
realname
=>
"
r
0
",
type
=>
4
},
# hardwired 0, behaves like /dev/null
{
name
=>
"
g1
",
realname
=>
"
r
1
",
type
=>
1
},
# temp. value
{
name
=>
"
g2
",
realname
=>
"
r
2
",
type
=>
1
},
{
name
=>
"
g3
",
realname
=>
"
r
3
",
type
=>
1
},
{
name
=>
"
g4
",
realname
=>
"
r
4
",
type
=>
1
},
{
name
=>
"
g5
",
realname
=>
"
r
5
",
type
=>
1
},
# reserved by SPARC ABI
{
name
=>
"
g6
",
realname
=>
"
r
6
",
type
=>
1
},
# reserved by SPARC ABI
{
name
=>
"
g7
",
realname
=>
"
r
7
",
type
=>
2
},
# reserved by SPARC ABI
{
name
=>
"
g0
",
realname
=>
"
g
0
",
type
=>
4
},
# hardwired 0, behaves like /dev/null
{
name
=>
"
g1
",
realname
=>
"
g
1
",
type
=>
1
},
# temp. value
{
name
=>
"
g2
",
realname
=>
"
g
2
",
type
=>
1
},
{
name
=>
"
g3
",
realname
=>
"
g
3
",
type
=>
1
},
{
name
=>
"
g4
",
realname
=>
"
g
4
",
type
=>
1
},
{
name
=>
"
g5
",
realname
=>
"
g
5
",
type
=>
4
},
# reserved by SPARC ABI
{
name
=>
"
g6
",
realname
=>
"
g
6
",
type
=>
4
},
# reserved by SPARC ABI
{
name
=>
"
g7
",
realname
=>
"
g
7
",
type
=>
2
},
# reserved by SPARC ABI
# window's out registers
{
name
=>
"
o0
",
realname
=>
"
r8
",
type
=>
1
},
# param 1 / return value from callee
{
name
=>
"
o1
",
realname
=>
"
r9
",
type
=>
1
},
# param 2
{
name
=>
"
o2
",
realname
=>
"
r10
",
type
=>
1
},
# param 3
{
name
=>
"
o3
",
realname
=>
"
r11
",
type
=>
1
},
# param 4
{
name
=>
"
o4
",
realname
=>
"
r12
",
type
=>
1
},
# param 5
{
name
=>
"
o5
",
realname
=>
"
r13
",
type
=>
1
},
# param 6
{
name
=>
"
sp
",
realname
=>
"
r14
",
type
=>
4
},
# our stackpointer
{
name
=>
"
o7
",
realname
=>
"
r15
",
type
=>
1
},
# temp. value / address of CALL instr.
{
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
=>
1
},
# temp. value / address of CALL instr.
# window's local registers
{
name
=>
"
l0
",
realname
=>
"
r16
",
type
=>
2
},
{
name
=>
"
l1
",
realname
=>
"
r17
",
type
=>
2
},
{
name
=>
"
l2
",
realname
=>
"
r18
",
type
=>
2
},
{
name
=>
"
l3
",
realname
=>
"
r19
",
type
=>
2
},
{
name
=>
"
l4
",
realname
=>
"
r20
",
type
=>
2
},
{
name
=>
"
l5
",
realname
=>
"
r21
",
type
=>
2
},
{
name
=>
"
l6
",
realname
=>
"
r22
",
type
=>
2
},
{
name
=>
"
l7
",
realname
=>
"
r23
",
type
=>
2
},
{
name
=>
"
l0
",
realname
=>
"
l0
",
type
=>
2
},
{
name
=>
"
l1
",
realname
=>
"
l1
",
type
=>
2
},
{
name
=>
"
l2
",
realname
=>
"
l2
",
type
=>
2
},
{
name
=>
"
l3
",
realname
=>
"
l3
",
type
=>
2
},
{
name
=>
"
l4
",
realname
=>
"
l4
",
type
=>
2
},
{
name
=>
"
l5
",
realname
=>
"
l5
",
type
=>
2
},
{
name
=>
"
l6
",
realname
=>
"
l6
",
type
=>
2
},
{
name
=>
"
l7
",
realname
=>
"
l7
",
type
=>
2
},
# window's in registers
{
name
=>
"
i0
",
realname
=>
"
r24
",
type
=>
2
},
# incoming param1 / return value to caller
{
name
=>
"
i1
",
realname
=>
"
r25
",
type
=>
2
},
# param 2
{
name
=>
"
i2
",
realname
=>
"
r26
",
type
=>
2
},
# param 3
{
name
=>
"
i3
",
realname
=>
"
r27
",
type
=>
2
},
# param 4
{
name
=>
"
i4
",
realname
=>
"
r28
",
type
=>
2
},
# param 5
{
name
=>
"
i5
",
realname
=>
"
r29
",
type
=>
2
},
# param 6
{
name
=>
"
fp
",
realname
=>
"
r30
",
type
=>
4
},
# our framepointer
{
name
=>
"
i7
",
realname
=>
"
r31
",
type
=>
2
},
# return address - 8
{
name
=>
"
i0
",
realname
=>
"
i0
",
type
=>
2
},
# incoming param1 / return value to caller
{
name
=>
"
i1
",
realname
=>
"
i1
",
type
=>
2
},
# param 2
{
name
=>
"
i2
",
realname
=>
"
i2
",
type
=>
2
},
# param 3
{
name
=>
"
i3
",
realname
=>
"
i3
",
type
=>
2
},
# param 4
{
name
=>
"
i4
",
realname
=>
"
i4
",
type
=>
2
},
# param 5
{
name
=>
"
i5
",
realname
=>
"
i5
",
type
=>
2
},
# param 6
{
name
=>
"
fp
",
realname
=>
"
i6
",
type
=>
4
},
# our framepointer
{
name
=>
"
i7
",
realname
=>
"
i7
",
type
=>
2
},
# return address - 8
{
mode
=>
$mode_gp
}
],
flags
=>
[
...
...
@@ -323,7 +323,6 @@ my %binop_operand_constructors = (
# commutative operations
Add
=>
{
op_flags
=>
"
C
",
irn_flags
=>
"
R
",
comment
=>
"
construct Add: Add(a, b) = Add(b, a) = a + b
",
mode
=>
$mode_gp
,
...
...
@@ -354,6 +353,30 @@ Load => {
emit
=>
'
. ld%LM [%S1%O], %D1
'
},
LoadHi
=>
{
op_flags
=>
"
L|F
",
comment
=>
"
construct LoadHi: Load(ptr, mem) = sethi hi(ptr) -> reg
",
state
=>
"
exc_pinned
",
ins
=>
[
"
ptr
",
"
mem
"
],
outs
=>
[
"
res
",
"
M
"
],
reg_req
=>
{
in
=>
[
"
gp
",
"
none
"
],
out
=>
[
"
gp
",
"
none
"
]
},
attr_type
=>
"
sparc_load_store_attr_t
",
attr
=>
"
ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity
",
emit
=>
'
. sethi %%hi(%S1), %D1
'
},
LoadLo
=>
{
op_flags
=>
"
L|F
",
comment
=>
"
construct LoadLo: Or(in, ptr, mem) = or in lo(ptr) -> reg
",
state
=>
"
exc_pinned
",
ins
=>
[
"
hireg
",
"
ptr
",
"
mem
"
],
outs
=>
[
"
res
",
"
M
"
],
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
none
"
],
out
=>
[
"
gp
",
"
none
"
]
},
attr_type
=>
"
sparc_load_store_attr_t
",
attr
=>
"
ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity
",
emit
=>
'
. or %S1, %%lo(%S2), %D1
'
},
Store
=>
{
op_flags
=>
"
L|F
",
comment
=>
"
construct Store: Store(ptr, val, mem) = ST ptr,val
",
...
...
@@ -364,7 +387,7 @@ Store => {
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
",
"
none
"
],
out
=>
[
"
none
"
]
},
attr_type
=>
"
sparc_load_store_attr_t
",
attr
=>
"
ir_mode *ls_mode, ir_entity *entity, int entity_sign, long offset, bool is_frame_entity
",
emit
=>
'
. st%SM %S
1
, [%
D
1%O]
'
emit
=>
'
. st%SM %S
2
, [%
S
1%O]
'
},
Mov
=>
{
...
...
@@ -421,6 +444,14 @@ Branch => {
init_attr
=>
"
\t
set_sparc_jmp_cond_proj_num(res, proj_num);
",
},
Jmp
=>
{
state
=>
"
pinned
",
op_flags
=>
"
X
",
irn_flags
=>
"
J
",
reg_req
=>
{
out
=>
[
"
none
"
]
},
mode
=>
"
mode_X
",
},
Cmp
=>
{
irn_flags
=>
"
R|F
",
emit
=>
'
. cmp %S1, %R2I
',
...
...
@@ -450,6 +481,52 @@ SwitchJmp => {
reg_req
=>
{
in
=>
[
"
gp
"
],
out
=>
[
"
none
"
]
},
attr_type
=>
"
sparc_jmp_switch_attr_t
",
},
ShiftLL
=>
{
irn_flags
=>
"
R
",
comment
=>
"
construct shift logical left
",
mode
=>
$mode_gp
,
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
"
],
out
=>
[
"
gp
"
]
},
emit
=>
'
. sll %S1, %R2I, %D1
',
constructors
=>
\
%binop_operand_constructors
,
},
ShiftLR
=>
{
irn_flags
=>
"
R
",
comment
=>
"
construct shift logical right
",
mode
=>
$mode_gp
,
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
"
],
out
=>
[
"
gp
"
]
},
emit
=>
'
. slr %S1, %R2I, %D1
',
constructors
=>
\
%binop_operand_constructors
,
},
ShiftRA
=>
{
irn_flags
=>
"
R
",
comment
=>
"
construct shift right arithmetical
",
mode
=>
$mode_gp
,
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
"
],
out
=>
[
"
gp
"
]
},
emit
=>
'
. sra %S1, %R2I, %D1
',
constructors
=>
\
%binop_operand_constructors
,
},
And
=>
{
irn_flags
=>
"
R
",
comment
=>
"
construct logical and
",
mode
=>
$mode_gp
,
reg_req
=>
{
in
=>
[
"
gp
",
"
gp
"
],
out
=>
[
"
gp
"
]
},
emit
=>
'
. and %S1, %R2I, %D1
',
constructors
=>
\
%binop_operand_constructors
,
},