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
fe2ddf0f
Commit
fe2ddf0f
authored
Mar 31, 2006
by
Christian Würdig
Browse files
fixed Jump Tables
parent
fe53f12c
Changes
2
Show whitespace changes
Inline
Side-by-side
ir/be/ia32/ia32_emitter.c
View file @
fe2ddf0f
...
...
@@ -921,19 +921,9 @@ static void emit_ia32_SwitchJmp(const ir_node *irn, ia32_emit_env_t *emit_env) {
interval
=
tbl
.
max_value
-
tbl
.
min_value
;
/* emit the table */
if
(
tbl
.
min_value
!=
0
)
{
lc_esnprintf
(
env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"sub [%1S-%d], %u"
,
irn
,
tbl
.
min_value
*
4
,
interval
);
lc_esnprintf
(
env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"cmp DWORD PTR [%1S-%d], %u"
,
irn
,
tbl
.
min_value
*
4
,
interval
);
snprintf
(
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* first switch value is not 0 */"
);
IA32_DO_EMIT
(
irn
);
}
else
{
lc_esnprintf
(
env
,
cmd_buf
,
SNPRINTF_BUF_LEN
,
"cmp %1S, %u"
,
irn
,
interval
);
snprintf
(
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* compare for switch */"
);
IA32_DO_EMIT
(
irn
);
}
snprintf
(
cmd_buf
,
SNPRINTF_BUF_LEN
,
"ja %s"
,
get_cfop_target
(
tbl
.
defProj
,
buf
));
snprintf
(
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* default jump if out of range */"
);
...
...
@@ -952,7 +942,7 @@ static void emit_ia32_SwitchJmp(const ir_node *irn, ia32_emit_env_t *emit_env) {
fprintf
(
F
,
"%s:
\n
"
,
tbl
.
label
);
snprintf
(
cmd_buf
,
SNPRINTF_BUF_LEN
,
".long %s"
,
get_cfop_target
(
tbl
.
branches
[
0
].
target
,
buf
));
snprintf
(
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* case %d */
\n
"
,
tbl
.
branches
[
0
].
value
);
snprintf
(
cmnt_buf
,
SNPRINTF_BUF_LEN
,
"/* case %d */"
,
tbl
.
branches
[
0
].
value
);
IA32_DO_EMIT
(
irn
);
last_value
=
tbl
.
branches
[
0
].
value
;
...
...
@@ -967,7 +957,7 @@ static void emit_ia32_SwitchJmp(const ir_node *irn, ia32_emit_env_t *emit_env) {
IA32_DO_EMIT
(
irn
);
}
fprintf
(
F
,
"
\t
.text"
);
fprintf
(
F
,
"
\
n\
t
.text
\n\n
"
);
}
else
{
/* one jump is enough */
...
...
ir/be/ia32/ia32_transform.c
View file @
fe2ddf0f
...
...
@@ -9,6 +9,8 @@
#include
"config.h"
#endif
#include
<limits.h>
#include
"irargs_t.h"
#include
"irnode_t.h"
#include
"irgraph_t.h"
...
...
@@ -1475,7 +1477,28 @@ static ir_node *gen_Cond(ia32_transform_env_t *env) {
set_ia32_am_support
(
res
,
ia32_am_Source
);
}
else
{
res
=
new_rd_ia32_SwitchJmp
(
dbg
,
irg
,
block
,
sel
,
mode_T
);
/* determine the smallest switch case value */
int
switch_min
=
INT_MAX
;
const
ir_edge_t
*
edge
;
char
buf
[
64
];
foreach_out_edge
(
node
,
edge
)
{
int
pn
=
get_Proj_proj
(
get_edge_src_irn
(
edge
));
switch_min
=
pn
<
switch_min
?
pn
:
switch_min
;
}
if
(
switch_min
)
{
/* if smallest switch case is not 0 we need an additional sub */
snprintf
(
buf
,
sizeof
(
buf
),
"%d"
,
switch_min
);
res
=
new_rd_ia32_Lea
(
dbg
,
irg
,
block
,
sel
,
noreg
,
mode_Is
);
SET_IA32_ORIG_NODE
(
res
,
ia32_get_old_node_name
(
env
->
cg
,
env
->
irn
));
sub_ia32_am_offs
(
res
,
buf
);
set_ia32_am_flavour
(
res
,
ia32_am_OB
);
set_ia32_am_support
(
res
,
ia32_am_Source
);
set_ia32_op_type
(
res
,
ia32_AddrModeS
);
}
res
=
new_rd_ia32_SwitchJmp
(
dbg
,
irg
,
block
,
switch_min
?
res
:
sel
,
mode_T
);
set_ia32_pncode
(
res
,
get_Cond_defaultProj
(
node
));
set_ia32_res_mode
(
res
,
get_irn_mode
(
sel
));
}
...
...
Write
Preview
Supports
Markdown
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