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
fd5331da
Commit
fd5331da
authored
Jul 14, 2010
by
Matthias Braun
Browse files
arm: implement calling conventions for float and double parameter
[r27737]
parent
ce972cd9
Changes
12
Hide whitespace changes
Inline
Side-by-side
ir/be/arm/arm_cconv.c
View file @
fd5331da
...
...
@@ -40,10 +40,13 @@ calling_convention_t *decide_calling_convention(ir_type *function_type)
=
sizeof
(
param_regs
)
/
sizeof
(
param_regs
[
0
]);
int
n_result_regs
=
sizeof
(
result_regs
)
/
sizeof
(
result_regs
[
0
]);
int
n_float_result_regs
=
sizeof
(
float_result_regs
)
/
sizeof
(
float_result_regs
[
0
]);
int
n_params
;
int
n_results
;
int
i
;
int
regnum
;
int
float_regnum
;
calling_convention_t
*
cconv
;
/* determine how parameters are passed */
...
...
@@ -56,15 +59,15 @@ calling_convention_t *decide_calling_convention(ir_type *function_type)
ir_mode
*
mode
=
get_type_mode
(
param_type
);
int
bits
=
get_mode_size_bits
(
mode
);
reg_or_stackslot_t
*
param
=
&
params
[
i
];
param
->
type
=
param_type
;
if
(
regnum
<
n_param_regs
)
{
const
arch_register_t
*
reg
=
param_regs
[
regnum
++
];
param
->
reg0
=
reg
;
}
else
{
param
->
type
=
param_type
;
param
->
offset
=
stack_offset
;
/* increase offset 4 bytes so everything is aligned */
stack_offset
+=
4
;
stack_offset
+=
bits
>
32
?
bits
/
8
:
4
;
continue
;
}
...
...
@@ -81,28 +84,39 @@ calling_convention_t *decide_calling_convention(ir_type *function_type)
ir_type
*
type
=
get_type_for_mode
(
mode
);
param
->
type
=
type
;
param
->
offset
=
stack_offset
;
assert
(
get_mode_size_bits
(
mode
)
==
32
);
stack_offset
+=
4
;
}
}
}
n_results
=
get_method_n_ress
(
function_type
);
regnum
=
0
;
results
=
XMALLOCNZ
(
reg_or_stackslot_t
,
n_results
);
n_results
=
get_method_n_ress
(
function_type
);
regnum
=
0
;
float_regnum
=
0
;
results
=
XMALLOCNZ
(
reg_or_stackslot_t
,
n_results
);
for
(
i
=
0
;
i
<
n_results
;
++
i
)
{
ir_type
*
result_type
=
get_method_res_type
(
function_type
,
i
);
ir_mode
*
result_mode
=
get_type_mode
(
result_type
);
reg_or_stackslot_t
*
result
=
&
results
[
i
];
if
(
get_mode_size_bits
(
result_mode
)
>
32
)
{
panic
(
"Results with more than 32bits not supported by arm backend yet"
);
}
if
(
regnum
>=
n_result_regs
)
{
panic
(
"Too many results for arm backend"
);
if
(
mode_is_float
(
result_mode
))
{
if
(
float_regnum
>=
n_float_result_regs
)
{
panic
(
"Too many float results for arm backend"
);
}
else
{
const
arch_register_t
*
reg
=
float_result_regs
[
float_regnum
++
];
result
->
reg0
=
reg
;
}
}
else
{
const
arch_register_t
*
reg
=
result_regs
[
regnum
++
];
result
->
reg0
=
reg
;
if
(
get_mode_size_bits
(
result_mode
)
>
32
)
{
panic
(
"Results with more than 32bits not supported by arm backend yet"
);
}
if
(
regnum
>=
n_result_regs
)
{
panic
(
"Too many results for arm backend"
);
}
else
{
const
arch_register_t
*
reg
=
result_regs
[
regnum
++
];
result
->
reg0
=
reg
;
}
}
}
...
...
ir/be/arm/arm_cconv.h
View file @
fd5331da
...
...
@@ -47,7 +47,16 @@ static const arch_register_t *const caller_saves[] = {
&
arm_gp_regs
[
REG_R1
],
&
arm_gp_regs
[
REG_R2
],
&
arm_gp_regs
[
REG_R3
],
&
arm_gp_regs
[
REG_LR
]
&
arm_gp_regs
[
REG_LR
],
&
arm_fpa_regs
[
REG_F0
],
&
arm_fpa_regs
[
REG_F1
],
&
arm_fpa_regs
[
REG_F2
],
&
arm_fpa_regs
[
REG_F3
],
&
arm_fpa_regs
[
REG_F4
],
&
arm_fpa_regs
[
REG_F5
],
&
arm_fpa_regs
[
REG_F6
],
&
arm_fpa_regs
[
REG_F7
],
};
static
const
arch_register_t
*
const
param_regs
[]
=
{
...
...
@@ -64,6 +73,11 @@ static const arch_register_t* const result_regs[] = {
&
arm_gp_regs
[
REG_R3
]
};
static
const
arch_register_t
*
const
float_result_regs
[]
=
{
&
arm_fpa_regs
[
REG_F0
],
&
arm_fpa_regs
[
REG_F1
]
};
/** information about a single parameter or result */
typedef
struct
reg_or_stackslot_t
{
...
...
ir/be/arm/arm_emitter.c
View file @
fd5331da
...
...
@@ -134,27 +134,18 @@ static const arch_register_t *get_out_reg(const ir_node *node, int pos)
return
reg
;
}
/**
* Emit the name of the source register at given input position.
*/
void
arm_emit_source_register
(
const
ir_node
*
node
,
int
pos
)
{
const
arch_register_t
*
reg
=
get_in_reg
(
node
,
pos
);
be_emit_string
(
arch_register_get_name
(
reg
));
}
/**
* Emit the name of the destination register at given output position.
*/
void
arm_emit_dest_register
(
const
ir_node
*
node
,
int
pos
)
{
const
arch_register_t
*
reg
=
get_out_reg
(
node
,
pos
);
be_emit_string
(
arch_register_get_name
(
reg
));
}
/**
* Emit a node's offset.
*/
void
arm_emit_offset
(
const
ir_node
*
node
)
{
const
arm_load_store_attr_t
*
attr
=
get_arm_load_store_attr_const
(
node
);
...
...
@@ -178,20 +169,16 @@ static void arm_emit_fpa_postfix(const ir_mode *mode)
be_emit_char
(
c
);
}
/**
* Emit the instruction suffix depending on the mode.
*/
void
arm_emit_mode
(
const
ir_node
*
node
)
void
arm_emit_float_load_store_mode
(
const
ir_node
*
node
)
{
ir_mode
*
mode
;
const
arm_load_store_attr_t
*
attr
=
get_arm_load_store_attr_const
(
node
);
arm_emit_fpa_postfix
(
attr
->
load_store_mode
);
}
if
(
is_arm_irn
(
node
))
{
const
arm_attr_t
*
attr
=
get_arm_attr_const
(
node
);
mode
=
attr
->
op_mode
?
attr
->
op_mode
:
get_irn_mode
(
node
);
}
else
{
mode
=
get_irn_mode
(
node
);
}
arm_emit_fpa_postfix
(
mode
);
void
arm_emit_float_arithmetic_mode
(
const
ir_node
*
node
)
{
const
arm_farith_attr_t
*
attr
=
get_arm_farith_attr_const
(
node
);
arm_emit_fpa_postfix
(
attr
->
mode
);
}
void
arm_emit_symconst
(
const
ir_node
*
node
)
...
...
@@ -374,13 +361,13 @@ static void emit_arm_FrameAddr(const ir_node *irn)
/**
* Emit a floating point fpa constant.
*/
static
void
emit_arm_f
pa
Const
(
const
ir_node
*
irn
)
static
void
emit_arm_fConst
(
const
ir_node
*
irn
)
{
sym_or_tv_t
key
,
*
entry
;
unsigned
label
;
ir_mode
*
mode
;
key
.
u
.
tv
=
get_f
pa
Const_value
(
irn
);
key
.
u
.
tv
=
get_fConst_value
(
irn
);
key
.
is_entity
=
false
;
key
.
label
=
0
;
entry
=
(
sym_or_tv_t
*
)
set_insert
(
sym_or_tv
,
&
key
,
sizeof
(
key
),
HASH_PTR
(
key
.
u
.
generic
));
...
...
@@ -795,7 +782,6 @@ static void emit_be_Copy(const ir_node *irn)
if
(
mode_is_float
(
mode
))
{
if
(
USE_FPA
(
cg
->
isa
))
{
be_emit_cstring
(
"
\t
mvf"
);
arm_emit_mode
(
irn
);
be_emit_char
(
' '
);
arm_emit_dest_register
(
irn
,
0
);
be_emit_cstring
(
", "
);
...
...
@@ -912,32 +898,6 @@ static void emit_arm_Jmp(const ir_node *node)
be_emit_finish_line_gas
(
node
);
}
static
void
emit_arm_fpaDbl2GP
(
const
ir_node
*
irn
)
{
be_emit_cstring
(
"
\t
stfd "
);
arm_emit_source_register
(
irn
,
0
);
be_emit_cstring
(
", [sp, #-8]!"
);
be_emit_pad_comment
();
be_emit_cstring
(
"/* Push fp to stack */"
);
be_emit_finish_line_gas
(
NULL
);
be_emit_cstring
(
"
\t
ldmfd sp!, {"
);
arm_emit_dest_register
(
irn
,
1
);
be_emit_cstring
(
", "
);
arm_emit_dest_register
(
irn
,
0
);
be_emit_char
(
'}'
);
be_emit_pad_comment
();
be_emit_cstring
(
"/* Pop destination */"
);
be_emit_finish_line_gas
(
irn
);
}
static
void
emit_arm_LdTls
(
const
ir_node
*
irn
)
{
(
void
)
irn
;
panic
(
"TLS not supported for this target"
);
/* Er... our gcc does not support it... Install a newer toolchain. */
}
static
void
emit_nothing
(
const
ir_node
*
irn
)
{
(
void
)
irn
;
...
...
@@ -969,28 +929,26 @@ static void arm_register_emitters(void)
arm_register_spec_emitters
();
/* custom emitter */
set_emitter
(
op_arm_B
,
emit_arm_B
);
set_emitter
(
op_arm_CopyB
,
emit_arm_CopyB
);
set_emitter
(
op_arm_fpaConst
,
emit_arm_fpaConst
);
set_emitter
(
op_arm_fpaDbl2GP
,
emit_arm_fpaDbl2GP
);
set_emitter
(
op_arm_FrameAddr
,
emit_arm_FrameAddr
);
set_emitter
(
op_arm_Jmp
,
emit_arm_Jmp
);
set_emitter
(
op_arm_LdTls
,
emit_arm_LdTls
);
set_emitter
(
op_arm_SwitchJmp
,
emit_arm_SwitchJmp
);
set_emitter
(
op_arm_SymConst
,
emit_arm_SymConst
);
set_emitter
(
op_be_Call
,
emit_be_Call
);
set_emitter
(
op_be_Copy
,
emit_be_Copy
);
set_emitter
(
op_be_CopyKeep
,
emit_be_Copy
);
set_emitter
(
op_be_IncSP
,
emit_be_IncSP
);
set_emitter
(
op_be_MemPerm
,
emit_be_MemPerm
);
set_emitter
(
op_be_Perm
,
emit_be_Perm
);
set_emitter
(
op_be_Return
,
emit_be_Return
);
set_emitter
(
op_arm_B
,
emit_arm_B
);
set_emitter
(
op_arm_CopyB
,
emit_arm_CopyB
);
set_emitter
(
op_arm_fConst
,
emit_arm_fConst
);
set_emitter
(
op_arm_FrameAddr
,
emit_arm_FrameAddr
);
set_emitter
(
op_arm_Jmp
,
emit_arm_Jmp
);
set_emitter
(
op_arm_SwitchJmp
,
emit_arm_SwitchJmp
);
set_emitter
(
op_arm_SymConst
,
emit_arm_SymConst
);
set_emitter
(
op_be_Call
,
emit_be_Call
);
set_emitter
(
op_be_Copy
,
emit_be_Copy
);
set_emitter
(
op_be_CopyKeep
,
emit_be_Copy
);
set_emitter
(
op_be_IncSP
,
emit_be_IncSP
);
set_emitter
(
op_be_MemPerm
,
emit_be_MemPerm
);
set_emitter
(
op_be_Perm
,
emit_be_Perm
);
set_emitter
(
op_be_Return
,
emit_be_Return
);
/* no need to emit anything for the following nodes */
set_emitter
(
op_Phi
,
emit_nothing
);
set_emitter
(
op_be_Keep
,
emit_nothing
);
set_emitter
(
op_be_Start
,
emit_nothing
);
set_emitter
(
op_be_Barrier
,
emit_nothing
);
set_emitter
(
op_Phi
,
emit_nothing
);
set_emitter
(
op_be_Keep
,
emit_nothing
);
set_emitter
(
op_be_Start
,
emit_nothing
);
set_emitter
(
op_be_Barrier
,
emit_nothing
);
}
/**
...
...
@@ -1109,9 +1067,6 @@ static int cmp_sym_or_tv(const void *elt, const void *key, size_t size)
return
p1
->
u
.
generic
!=
p2
->
u
.
generic
;
}
/**
* Main driver. Emits the code for one routine.
*/
void
arm_gen_routine
(
const
arm_code_gen_t
*
arm_cg
,
ir_graph
*
irg
)
{
ir_node
**
blk_sched
;
...
...
ir/be/arm/arm_emitter.h
View file @
fd5331da
...
...
@@ -35,7 +35,8 @@
#include "bearch_arm_t.h"
void
arm_emit_mode
(
const
ir_node
*
node
);
void
arm_emit_float_load_store_mode
(
const
ir_node
*
node
);
void
arm_emit_float_arithmetic_mode
(
const
ir_node
*
node
);
void
arm_emit_symconst
(
const
ir_node
*
node
);
void
arm_emit_source_register
(
const
ir_node
*
node
,
int
pos
);
void
arm_emit_dest_register
(
const
ir_node
*
node
,
int
pos
);
...
...
ir/be/arm/arm_new_nodes.c
View file @
fd5331da
...
...
@@ -72,7 +72,8 @@ static bool arm_has_symconst_attr(const ir_node *node)
static
bool
has_load_store_attr
(
const
ir_node
*
node
)
{
return
is_arm_Ldr
(
node
)
||
is_arm_Str
(
node
)
||
is_arm_LinkLdrPC
(
node
);
return
is_arm_Ldr
(
node
)
||
is_arm_Str
(
node
)
||
is_arm_LinkLdrPC
(
node
)
||
is_arm_Ldf
(
node
)
||
is_arm_Stf
(
node
);
}
static
bool
has_shifter_operand
(
const
ir_node
*
node
)
...
...
@@ -88,6 +89,11 @@ static bool has_cmp_attr(const ir_node *node)
return
is_arm_Cmp
(
node
)
||
is_arm_Tst
(
node
);
}
static
bool
has_farith_attr
(
const
ir_node
*
node
)
{
return
is_arm_Dvf
(
node
)
||
is_arm_Adf
(
node
);
}
/**
* Dumper interface for dumping arm nodes in vcg.
* @param F the output file
...
...
@@ -197,6 +203,10 @@ static void arm_dump_node(FILE *F, ir_node *n, dump_reason_t reason)
fputc
(
'\n'
,
F
);
fprintf
(
F
,
"frame offset = %d
\n
"
,
attr
->
fp_offset
);
}
if
(
has_farith_attr
(
n
))
{
const
arm_farith_attr_t
*
attr
=
get_arm_farith_attr_const
(
n
);
ir_fprintf
(
F
,
"arithmetic mode = %+F
\n
"
,
attr
->
mode
);
}
break
;
}
}
...
...
@@ -230,21 +240,28 @@ const arm_SymConst_attr_t *get_arm_SymConst_attr_const(const ir_node *node)
return
get_irn_generic_attr_const
(
node
);
}
static
const
arm_fpaConst_attr_t
*
get_arm_fpaConst_attr_const
(
const
ir_node
*
node
)
static
const
arm_fConst_attr_t
*
get_arm_fConst_attr_const
(
const
ir_node
*
node
)
{
const
arm_attr_t
*
attr
=
get_arm_attr_const
(
node
);
const
arm_fpaConst_attr_t
*
fpa_attr
=
CONST_CAST_ARM_ATTR
(
arm_fpaConst_attr_t
,
attr
);
assert
(
is_arm_fConst
(
node
));
return
get_irn_generic_attr_const
(
node
);
}
return
fpa_attr
;
static
arm_fConst_attr_t
*
get_arm_fConst_attr
(
ir_node
*
node
)
{
assert
(
is_arm_fConst
(
node
));
return
get_irn_generic_attr
(
node
);
}
static
arm_fpaConst
_attr_t
*
get_arm_f
paConst
_attr
(
ir_node
*
node
)
arm_farith
_attr_t
*
get_arm_f
arith
_attr
(
ir_node
*
node
)
{
arm_attr_t
*
attr
=
get_arm_attr
(
node
);
arm_fpaConst_attr_t
*
fpa_attr
=
CAST_ARM_ATTR
(
arm_fpaConst_attr_t
,
attr
);
assert
(
has_farith_attr
(
node
));
return
get_irn_generic_attr
(
node
);
}
return
fpa_attr
;
const
arm_farith_attr_t
*
get_arm_farith_attr_const
(
const
ir_node
*
node
)
{
assert
(
has_farith_attr
(
node
));
return
get_irn_generic_attr_const
(
node
);
}
arm_CondJmp_attr_t
*
get_arm_CondJmp_attr
(
ir_node
*
node
)
...
...
@@ -289,15 +306,15 @@ void set_arm_req_in(ir_node *node, const arch_register_req_t *req, int pos)
attr
->
in_req
[
pos
]
=
req
;
}
tarval
*
get_f
pa
Const_value
(
const
ir_node
*
node
)
tarval
*
get_fConst_value
(
const
ir_node
*
node
)
{
const
arm_f
pa
Const_attr_t
*
attr
=
get_arm_f
pa
Const_attr_const
(
node
);
const
arm_fConst_attr_t
*
attr
=
get_arm_fConst_attr_const
(
node
);
return
attr
->
tv
;
}
void
set_f
pa
Const_value
(
ir_node
*
node
,
tarval
*
tv
)
void
set_fConst_value
(
ir_node
*
node
,
tarval
*
tv
)
{
arm_f
pa
Const_attr_t
*
attr
=
get_arm_f
pa
Const_attr
(
node
);
arm_fConst_attr_t
*
attr
=
get_arm_fConst_attr
(
node
);
attr
->
tv
=
tv
;
}
...
...
@@ -351,7 +368,6 @@ static void init_arm_attributes(ir_node *node, int flags,
arch_irn_set_flags
(
node
,
flags
);
attr
->
in_req
=
in_reqs
;
attr
->
instr_fl
=
0
;
info
=
be_get_info
(
node
);
info
->
out_infos
=
NEW_ARR_D
(
reg_out_info_t
,
obst
,
n_res
);
...
...
@@ -397,6 +413,12 @@ static void init_arm_SymConst_attributes(ir_node *res, ir_entity *entity,
attr
->
fp_offset
=
symconst_offset
;
}
static
void
init_arm_farith_attributes
(
ir_node
*
res
,
ir_mode
*
mode
)
{
arm_farith_attr_t
*
attr
=
get_irn_generic_attr
(
res
);
attr
->
mode
=
mode
;
}
static
void
init_arm_CopyB_attributes
(
ir_node
*
res
,
unsigned
size
)
{
arm_CopyB_attr_t
*
attr
=
get_irn_generic_attr
(
res
);
...
...
@@ -405,9 +427,9 @@ static void init_arm_CopyB_attributes(ir_node *res, unsigned size)
static
int
cmp_attr_arm
(
ir_node
*
a
,
ir_node
*
b
)
{
arm_attr_t
*
attr_a
=
get_irn_generic_attr
(
a
)
;
arm_attr_t
*
attr_b
=
get_irn_generic_attr
(
b
)
;
return
attr_a
->
instr_fl
!=
attr_b
->
instr_fl
;
(
void
)
a
;
(
void
)
b
;
return
0
;
}
static
int
cmp_attr_arm_SymConst
(
ir_node
*
a
,
ir_node
*
b
)
...
...
@@ -453,16 +475,16 @@ static int cmp_attr_arm_SwitchJmp(ir_node *a, ir_node *b)
return
1
;
}
static
int
cmp_attr_arm_f
pa
Const
(
ir_node
*
a
,
ir_node
*
b
)
static
int
cmp_attr_arm_fConst
(
ir_node
*
a
,
ir_node
*
b
)
{
const
arm_f
pa
Const_attr_t
*
attr_a
;
const
arm_f
pa
Const_attr_t
*
attr_b
;
const
arm_fConst_attr_t
*
attr_a
;
const
arm_fConst_attr_t
*
attr_b
;
if
(
cmp_attr_arm
(
a
,
b
))
return
1
;
attr_a
=
get_arm_f
pa
Const_attr_const
(
a
);
attr_b
=
get_arm_f
pa
Const_attr_const
(
b
);
attr_a
=
get_arm_fConst_attr_const
(
a
);
attr_b
=
get_arm_fConst_attr_const
(
b
);
return
attr_a
->
tv
!=
attr_b
->
tv
;
}
...
...
@@ -551,6 +573,19 @@ static int cmp_attr_arm_cmp(ir_node *a, ir_node *b)
return
0
;
}
static
int
cmp_attr_arm_farith
(
ir_node
*
a
,
ir_node
*
b
)
{
const
arm_farith_attr_t
*
attr_a
;
const
arm_farith_attr_t
*
attr_b
;
if
(
cmp_attr_arm
(
a
,
b
))
return
1
;
attr_a
=
get_arm_farith_attr_const
(
a
);
attr_b
=
get_arm_farith_attr_const
(
b
);
return
attr_a
->
mode
!=
attr_b
->
mode
;
}
/** copies the ARM attributes of a node. */
static
void
arm_copy_attr
(
ir_graph
*
irg
,
const
ir_node
*
old_node
,
ir_node
*
new_node
)
...
...
ir/be/arm/arm_new_nodes.h
View file @
fd5331da
...
...
@@ -62,6 +62,9 @@ const arm_shifter_operand_t *get_arm_shifter_operand_attr_const(const ir_node *n
arm_cmp_attr_t
*
get_arm_cmp_attr
(
ir_node
*
node
);
const
arm_cmp_attr_t
*
get_arm_cmp_attr_const
(
const
ir_node
*
node
);
arm_farith_attr_t
*
get_arm_farith_attr
(
ir_node
*
node
);
const
arm_farith_attr_t
*
get_arm_farith_attr_const
(
const
ir_node
*
node
);
void
set_arm_in_req_all
(
ir_node
*
node
,
const
arch_register_req_t
**
reqs
);
/**
...
...
@@ -75,14 +78,14 @@ const arch_register_req_t *get_arm_in_req(const ir_node *node, int pos);
void
set_arm_req_in
(
ir_node
*
node
,
const
arch_register_req_t
*
req
,
int
pos
);
/**
* Return the tarval of a f
pa
Const
* Return the tarval of a fConst
*/
tarval
*
get_f
pa
Const_value
(
const
ir_node
*
node
);
tarval
*
get_fConst_value
(
const
ir_node
*
node
);
/**
* Sets the tarval of a f
pa
Const
* Sets the tarval of a fConst
*/
void
set_f
pa
Const_value
(
ir_node
*
node
,
tarval
*
tv
);
void
set_fConst_value
(
ir_node
*
node
,
tarval
*
tv
);
/**
* Returns the compare kind
...
...
ir/be/arm/arm_nodes_attr.h
View file @
fd5331da
...
...
@@ -48,13 +48,6 @@ typedef enum arm_shift_modifier_t {
ARM_SHF_RRX
,
/**< rotate right through carry bits */
}
arm_shift_modifier_t
;
/** fpa immediate bit */
#define ARM_FPA_IMM (1 << 3)
/**< fpa floating point immediate */
#define ARM_GET_FPA_IMM(attr) ((attr)->instr_fl & ARM_FPA_IMM)
#define ARM_SET_FPA_IMM(attr) ((attr)->instr_fl |= ARM_FPA_IMM)
#define ARM_CLR_FPA_IMM(attr) ((attr)->instr_fl &= ~ARM_FPA_IMM)
/** Encoding for fpa immediates */
enum
fpa_immediates
{
fpa_null
=
0
,
...
...
@@ -70,13 +63,9 @@ enum fpa_immediates {
/** Generic ARM node attributes. */
typedef
struct
arm_attr_t
{
except_attr
exc
;
/**< the exception attribute. MUST be the first one. */
except_attr
exc
;
/**< the exception attribute. MUST be the first one. */
const
arch_register_req_t
**
in_req
;
/**< register requirements for arguments */
ir_mode
*
op_mode
;
/**< operation mode if different from node's mode (used for fpa nodes) */
unsigned
instr_fl
;
/**< deprecated (was sometimes used for shift modifiers) */
bool
is_load_store
:
1
;
bool
is_load_store
:
1
;
}
arm_attr_t
;
/**
...
...
@@ -130,16 +119,22 @@ typedef struct arm_SwitchJmp_attr_t {
}
arm_SwitchJmp_attr_t
;
/** CopyB attributes */
typedef
struct
{
typedef
struct
arm_CopyB_attr_t
{
arm_attr_t
base
;
unsigned
size
;
}
arm_CopyB_attr_t
;
/** Attributes for a f
pa
Const */
typedef
struct
arm_f
pa
Const_attr_t
{
/** Attributes for a fConst */
typedef
struct
arm_fConst_attr_t
{
arm_attr_t
base
;
tarval
*
tv
;
/**< the tarval representing the FP const */
}
arm_fpaConst_attr_t
;
}
arm_fConst_attr_t
;
/** attributes for floatingpoint arithmetic operations */
typedef
struct
arm_farith_attr_t
{
arm_attr_t
base
;
ir_mode
*
mode
;
/* operation mode */
}
arm_farith_attr_t
;
/**
* Return the fpa immediate from the encoding.
...
...
ir/be/arm/arm_spec.pl
View file @
fd5331da
# Creation: 2006/02/13
# Arm Architecure Specification
# Author: Matthias Braun, Michael Beck, Oliver Richter, Tobias Gneist
# $Id$
# the cpu architecture (ia32, ia64, mips, sparc, ppc, ...)
$arch
=
"
arm
";
#
# Modes
#
$mode_gp
=
"
mode_Iu
";
$mode_flags
=
"
mode_Bu
";
$mode_fp
a
=
"
mode_E
";
$mode_gp
=
"
mode_Iu
";
$mode_flags
=
"
mode_Bu
";
$mode_fp
=
"
mode_E
";
# register types:
$normal
=
0
;
# no special type
...
...
@@ -41,7 +41,7 @@ $state = 32; # register represents a state
{
name
=>
"
pc
",
type
=>
$ignore
},
# this is our program counter
{
mode
=>
$mode_gp
}
],
fpa
=>
[
fpa
=>
[
{
name
=>
"
f0
",
type
=>
$caller_save
},
{
name
=>
"
f1
",
type
=>
$caller_save
},
{
name
=>
"
f2
",
type
=>
$caller_save
},
...
...
@@ -50,7 +50,7 @@ $state = 32; # register represents a state
{
name
=>
"
f5
",
type
=>
$caller_save
},
{
name
=>
"
f6
",
type
=>
$caller_save
},
{
name
=>
"
f7
",
type
=>
$caller_save
},
{
mode
=>
$mode_fp
a
}
{
mode
=>
$mode_fp
}
],
flags
=>
[
{
name
=>
"
fl
",
type
=>
0
},
...
...
@@ -59,7 +59,8 @@ $state = 32; # register represents a state
);
%emit_templates
=
(
M
=>
"
${arch}
_emit_mode(node);
",
FM
=>
"
${arch}
_emit_float_load_store_mode(node);
",
AM
=>
"
${arch}
_emit_float_arithmetic_mode(node);
",
LM
=>
"
${arch}
_emit_load_mode(node);
",
SM
=>
"
${arch}
_emit_store_mode(node);
",
SO
=>
"
${arch}
_emit_shifter_operand(node);
",
...
...
@@ -85,7 +86,7 @@ $default_copy_attr = "arm_copy_attr";
"
\t
init_arm_SymConst_attributes(res, entity, symconst_offset);
",
arm_CondJmp_attr_t
=>
"
\t
init_arm_attributes(res, flags, in_reqs, exec_units, n_res);
",
arm_SwitchJmp_attr_t
=>
"
\t
init_arm_attributes(res, flags, in_reqs, exec_units, n_res);
",
arm_f
pa
Const_attr_t
=>
"
\t
init_arm_attributes(res, flags, in_reqs, exec_units, n_res);
",
arm_fConst_attr_t
=>
"
\t
init_arm_attributes(res, flags, in_reqs, exec_units, n_res);
",
arm_load_store_attr_t
=>
"
\t
init_arm_attributes(res, flags, in_reqs, exec_units, n_res);
\n
"
.
"
\t
init_arm_load_store_attributes(res, ls_mode, entity, entity_sign, offset, is_frame_entity);
",
...
...
@@ -93,6 +94,9 @@ $default_copy_attr = "arm_copy_attr";
"
\t
init_arm_attributes(res, flags, in_reqs, exec_units, n_res);
\n
",
arm_cmp_attr_t
=>
"
\t
init_arm_attributes(res, flags, in_reqs, exec_units, n_res);
\n
",
arm_farith_attr_t
=>
"
\t
init_arm_attributes(res, flags, in_reqs, exec_units, n_res);
\n
"
.
"
\t
init_arm_farith_attributes(res, op_mode);
",
arm_CopyB_attr_t
=>
"
\t
init_arm_attributes(res, flags, in_reqs, exec_units, n_res);
\n
"
.
"
\t
init_arm_CopyB_attributes(res, size);
",
...
...
@@ -103,11 +107,12 @@ $default_copy_attr = "arm_copy_attr";
arm_SymConst_attr_t
=>
"
cmp_attr_arm_SymConst
",
arm_CondJmp_attr_t
=>
"
cmp_attr_arm_CondJmp
",
arm_SwitchJmp_attr_t
=>
"
cmp_attr_arm_SwitchJmp
",
arm_f
pa
Const_attr_t
=>
"
cmp_attr_arm_f
pa
Const
",
arm_fConst_attr_t
=>
"
cmp_attr_arm_fConst
",
arm_load_store_attr_t
=>
"
cmp_attr_arm_load_store
",
arm_shifter_operand_t
=>
"
cmp_attr_arm_shifter_operand
",
arm_CopyB_attr_t
=>
"
cmp_attr_arm_CopyB
",
arm_cmp_attr_t
=>
"
cmp_attr_arm_cmp
",
arm_farith_attr_t
=>
"
cmp_attr_arm_farith
",
);
my
%unop_shifter_operand_constructors
=
(
...
...
@@ -299,16 +304,6 @@ Mvn => {
constructors
=>
\
%unop_shifter_operand_constructors
,
},