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
69d4cb08
Commit
69d4cb08
authored
Jun 02, 2007
by
Matthias Braun
Browse files
more work on ia32 assembler nodes
[r14270]
parent
930ef5ed
Changes
4
Hide whitespace changes
Inline
Side-by-side
ir/be/ia32/ia32_emitter.c
View file @
69d4cb08
...
...
@@ -1311,18 +1311,135 @@ void emit_Jmp(ia32_emit_env_t *env, const ir_node *node) {
be_emit_finish_line_gas
(
env
,
node
);
}
static
const
char
*
emit_asm_operand
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
,
const
char
*
s
)
{
const
arch_register_t
*
reg
;
const
char
*
reg_name
;
char
c
;
char
modifier
=
0
;
int
num
=
-
1
;
ia32_attr_t
*
attr
;
int
n_outs
;
int
p
;
assert
(
*
s
==
'%'
);
c
=
*
(
++
s
);
/* parse modifiers */
switch
(
c
)
{
case
0
:
ir_fprintf
(
stderr
,
"Warning: asm text (%+F) ends with %
\n
"
,
node
);
be_emit_char
(
env
,
'%'
);
return
s
+
1
;
case
'%'
:
be_emit_char
(
env
,
'%'
);
return
s
+
1
;
case
'w'
:
case
'b'
:
modifier
=
c
;
++
s
;
break
;
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
break
;
default:
ir_fprintf
(
stderr
,
"Warning: asm text (%+F) contains unknown modifier "
"'%c' for asm op
\n
"
,
node
,
c
);
++
s
;
break
;
}
/* parse number */
sscanf
(
s
,
"%d%n"
,
&
num
,
&
p
);
if
(
num
<
0
)
{
ir_fprintf
(
stderr
,
"Warning: Couldn't parse assembler operand (%+F)
\n
"
,
node
);
return
s
;
}
else
{
s
+=
p
;
}
/* get register */
attr
=
get_ia32_attr
(
node
);
n_outs
=
attr
->
data
.
n_res
;
if
(
num
<
n_outs
)
{
reg
=
get_out_reg
(
env
,
node
,
num
);
}
else
{
int
in
=
num
-
n_outs
;
if
(
in
>=
get_irn_arity
(
node
))
{
ir_fprintf
(
stderr
,
"Warning: Invalid input %d specified in asm "
"op (%+F)
\n
"
,
num
,
node
);
return
s
;
}
reg
=
get_in_reg
(
env
,
node
,
in
);
}
if
(
reg
==
NULL
)
{
ir_fprintf
(
stderr
,
"Warning: no register assigned for %d asm op "
"(%+F)
\n
"
,
num
,
node
);
return
s
;
}
/* emit it */
be_emit_char
(
env
,
'%'
);
switch
(
modifier
)
{
case
0
:
reg_name
=
arch_register_get_name
(
reg
);
break
;
case
'b'
:
reg_name
=
ia32_get_mapped_reg_name
(
env
->
isa
->
regs_8bit
,
reg
);
break
;
case
'w'
:
reg_name
=
ia32_get_mapped_reg_name
(
env
->
isa
->
regs_16bit
,
reg
);
break
;
default:
panic
(
"Invalid asm op modifier"
);
}
be_emit_string
(
env
,
reg_name
);
return
s
;
}
/**
* Emits code for an ASM pseudo op.
*/
static
void
emit_ASM
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
)
{
/* for now, really simple */
const
char
*
s
=
get_ASM_text
(
node
);
void
emit_ia32_Asm
(
ia32_emit_env_t
*
env
,
const
ir_node
*
node
)
{
ia32_attr_t
*
attr
=
get_ia32_attr
(
node
);
ident
*
asm_text
=
attr
->
cnst_val
.
asm_text
;
const
char
*
s
=
get_id_str
(
asm_text
);
if
(
s
[
0
]
!=
'\t'
)
be_emit_cstring
(
env
,
"
\t
"
);
be_emit_string
(
env
,
s
);
be_emit_cstring
(
env
,
"# Begin ASM
\t
"
);
be_emit_finish_line_gas
(
env
,
node
);
if
(
s
[
0
]
!=
'\t'
)
be_emit_char
(
env
,
'\t'
);
while
(
*
s
!=
0
)
{
if
(
*
s
==
'%'
)
{
s
=
emit_asm_operand
(
env
,
node
,
s
);
continue
;
}
else
{
be_emit_char
(
env
,
*
s
);
}
++
s
;
}
be_emit_char
(
env
,
'\n'
);
be_emit_write_line
(
env
);
be_emit_cstring
(
env
,
"# End ASM
\n
"
);
be_emit_write_line
(
env
);
}
/**********************************
...
...
@@ -1788,6 +1905,7 @@ void ia32_register_emitters(void) {
ia32_register_spec_emitters
();
/* other ia32 emitter functions */
IA32_EMIT
(
Asm
);
IA32_EMIT
(
CondJmp
);
IA32_EMIT
(
TestJmp
);
IA32_EMIT
(
CJmp
);
...
...
@@ -1832,7 +1950,6 @@ void ia32_register_emitters(void) {
/* firm emitter */
EMIT
(
Jmp
);
EMIT
(
ASM
);
IGN
(
Proj
);
IGN
(
Phi
);
IGN
(
Start
);
...
...
ir/be/ia32/ia32_nodes_attr.h
View file @
69d4cb08
...
...
@@ -121,6 +121,7 @@ struct ia32_attr_t {
union
{
tarval
*
tv
;
/**< tarval for immediate operations */
ir_entity
*
sc
;
/**< the symconst ident */
ident
*
asm_text
;
/**< used by asm node */
}
cnst_val
;
ir_mode
*
ls_mode
;
/**< Load/Store mode: This is the mode of the value
...
...
ir/be/ia32/ia32_transform.c
View file @
69d4cb08
...
...
@@ -2392,7 +2392,71 @@ static ir_node *gen_Conv(ia32_transform_env_t *env, ir_node *node) {
return
res
;
}
static
ir_node
*
gen_ASM
(
ia32_transform_env_t
*
env
,
ir_node
*
node
)
{
int
i
,
arity
;
ir_graph
*
irg
=
env
->
irg
;
ir_node
*
block
=
transform_node
(
env
,
get_nodes_block
(
node
));
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
**
in
;
ir_node
*
res
;
int
out_arity
;
ia32_attr_t
*
attr
;
const
arch_register_req_t
**
out_reqs
;
const
arch_register_req_t
**
in_reqs
;
struct
obstack
*
obst
;
/* assembler could contain float statements */
FP_USED
(
env
->
cg
);
/* transform inputs */
arity
=
get_irn_arity
(
node
);
in
=
alloca
(
arity
*
sizeof
(
in
[
0
]));
for
(
i
=
0
;
i
<
arity
;
++
i
)
{
ir_node
*
pred
=
get_irn_n
(
node
,
i
);
ir_node
*
transformed
=
transform_node
(
env
,
pred
);
in
[
i
]
=
transformed
;
}
out_arity
=
get_ASM_n_output_constraints
(
node
)
+
get_ASM_n_clobbers
(
node
);
res
=
new_rd_ia32_Asm
(
dbgi
,
irg
,
block
,
arity
,
in
,
out_arity
);
/* construct register constraints */
obst
=
get_irg_obstack
(
irg
);
out_reqs
=
obstack_alloc
(
obst
,
out_arity
*
sizeof
(
out_reqs
[
0
]));
for
(
i
=
0
;
i
<
out_arity
;
++
i
)
{
arch_register_req_t
*
req
=
obstack_alloc
(
obst
,
sizeof
(
req
[
0
]));
memset
(
req
,
0
,
sizeof
(
req
[
0
]));
/* TODO: parse constraints */
req
->
type
=
arch_register_req_type_normal
;
req
->
cls
=
&
ia32_reg_classes
[
CLASS_ia32_gp
];
out_reqs
[
i
]
=
req
;
}
set_ia32_out_req_all
(
res
,
out_reqs
);
in_reqs
=
obstack_alloc
(
obst
,
arity
*
sizeof
(
in_reqs
[
0
]));
for
(
i
=
0
;
i
<
arity
;
++
i
)
{
arch_register_req_t
*
req
=
obstack_alloc
(
obst
,
sizeof
(
req
[
0
]));
memset
(
req
,
0
,
sizeof
(
req
[
0
]));
/* TODO: parse constraints */
req
->
type
=
arch_register_req_type_normal
;
req
->
cls
=
&
ia32_reg_classes
[
CLASS_ia32_gp
];
in_reqs
[
i
]
=
req
;
}
set_ia32_in_req_all
(
res
,
in_reqs
);
attr
=
get_ia32_attr
(
res
);
attr
->
cnst_val
.
asm_text
=
get_ASM_text
(
node
);
SET_IA32_ORIG_NODE
(
res
,
ia32_get_old_node_name
(
env
->
cg
,
node
));
return
res
;
}
/********************************************
* _ _
...
...
@@ -3703,6 +3767,7 @@ static void register_transformers(void) {
GEN
(
Store
);
GEN
(
Cond
);
GEN
(
ASM
);
GEN
(
CopyB
);
//GEN(Mux);
BAD
(
Mux
);
...
...
ir/be/test/asm_test.c
View file @
69d4cb08
double
test
(
double
angle
)
{
double
result
;
asm
(
"fsinx %1,%0"
:
"=f"
(
result
)
:
"f"
(
angle
));
return
result
;
#include <stdio.h>
static
inline
unsigned
char
inb
(
const
unsigned
short
port
)
{
unsigned
char
val
;
__asm__
__volatile__
(
"inb %w1, %0"
:
"=a"
(
val
)
:
"dN"
(
port
));
return
val
;
}
static
inline
void
outb
(
const
unsigned
short
port
,
const
unsigned
char
val
)
{
int
k
=
val
;
/* just here to test the b modifier in %b0 */
__asm__
__volatile__
(
"outb %b0, %1"
:
:
"a"
(
k
),
"dN"
(
port
));
}
static
void
sincostest
(
double
arg
)
{
double
cos
,
sin
;
__asm__
(
"fsincos"
:
"=t"
(
cos
),
"=u"
(
sin
)
:
"0"
(
arg
));
printf
(
"Arg: %f Sin: %f Cos: %f
\n
"
,
arg
,
sin
,
cos
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
printf
(
"%f
\n
"
,
test
(
0
.
5
));
static
inline
int
mov
(
int
val
)
{
int
res
;
__asm__
(
"movl %0, %1"
:
"=r"
(
res
)
:
"ri"
(
val
));
return
res
;
}
int
main
()
{
//sincostest(0.5);
//outb(123, 42);
return
mov
(
0
);
}
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