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
2dd358a8
Commit
2dd358a8
authored
Apr 03, 2016
by
Matthias Braun
Browse files
ia32, amd64: Share code to emit immediates.
parent
d13cb0a6
Changes
4
Hide whitespace changes
Inline
Side-by-side
ir/be/amd64/amd64_emitter.c
View file @
2dd358a8
...
...
@@ -212,29 +212,6 @@ typedef enum amd64_emit_mod_t {
}
amd64_emit_mod_t
;
ENUM_BITSET
(
amd64_emit_mod_t
)
static
void
emit_relocation_no_offset
(
x86_immediate_kind_t
const
kind
,
ir_entity
const
*
const
entity
)
{
be_gas_emit_entity
(
entity
);
switch
(
kind
)
{
case
X86_IMM_ADDR
:
case
X86_IMM_PCREL
:
return
;
case
X86_IMM_GOTPCREL
:
be_emit_cstring
(
"@GOTPCREL"
);
return
;
case
X86_IMM_PLT
:
be_emit_cstring
(
"@PLT"
);
return
;
case
X86_IMM_VALUE
:
case
X86_IMM_TLS_IE
:
case
X86_IMM_TLS_LE
:
case
X86_IMM_PICBASE_REL
:
case
X86_IMM_FRAMEENT
:
case
X86_IMM_FRAMEOFFSET
:
case
X86_IMM_GOT
:
case
X86_IMM_GOTOFF
:
break
;
}
panic
(
"unexpected or invalid immediate kind"
);
}
static
void
amd64_emit_immediate64
(
const
amd64_imm64_t
*
const
imm
)
{
if
(
imm
->
kind
==
X86_IMM_VALUE
)
{
...
...
@@ -242,26 +219,11 @@ static void amd64_emit_immediate64(const amd64_imm64_t *const imm)
be_emit_irprintf
(
"0x%"
PRIX64
,
imm
->
offset
);
return
;
}
emit_relocation_no_offset
(
imm
->
kind
,
imm
->
entity
);
x86_
emit_relocation_no_offset
(
imm
->
kind
,
imm
->
entity
);
if
(
imm
->
offset
!=
0
)
be_emit_irprintf
(
"%+"
PRId64
,
imm
->
offset
);
}
static
void
amd64_emit_immediate32
(
bool
const
prefix
,
x86_imm32_t
const
*
const
imm
)
{
if
(
prefix
)
be_emit_char
(
'$'
);
if
(
imm
->
kind
==
X86_IMM_VALUE
)
{
assert
(
imm
->
entity
==
NULL
);
be_emit_irprintf
(
"%"
PRId32
,
imm
->
offset
);
return
;
}
emit_relocation_no_offset
(
imm
->
kind
,
imm
->
entity
);
if
(
imm
->
offset
!=
0
)
be_emit_irprintf
(
"%+"
PRId32
,
imm
->
offset
);
}
static
void
amd64_emit_addr
(
const
ir_node
*
const
node
,
const
x86_addr_t
*
const
addr
)
{
...
...
@@ -273,7 +235,7 @@ static void amd64_emit_addr(const ir_node *const node,
if
(
entity
!=
NULL
)
{
assert
(
addr
->
immediate
.
kind
!=
X86_IMM_VALUE
);
assert
(
!
is_frame_type
(
get_entity_owner
(
entity
)));
emit_relocation_no_offset
(
addr
->
immediate
.
kind
,
entity
);
x86_
emit_relocation_no_offset
(
addr
->
immediate
.
kind
,
entity
);
if
(
offset
!=
0
)
be_emit_irprintf
(
"%+"
PRId32
,
offset
);
}
else
if
(
offset
!=
0
||
variant
==
X86_ADDR_JUST_IMM
)
{
...
...
@@ -316,7 +278,8 @@ static void amd64_emit_am(const ir_node *const node, bool indirect_star)
case
AMD64_OP_REG_IMM
:
{
const
amd64_binop_addr_attr_t
*
const
binop_attr
=
(
const
amd64_binop_addr_attr_t
*
)
attr
;
amd64_emit_immediate32
(
true
,
&
binop_attr
->
u
.
immediate
);
be_emit_char
(
'$'
);
x86_emit_imm32
(
&
binop_attr
->
u
.
immediate
);
be_emit_cstring
(
", "
);
goto
emit_addr_reg
;
}
...
...
@@ -339,7 +302,8 @@ static void amd64_emit_am(const ir_node *const node, bool indirect_star)
case
AMD64_OP_ADDR_IMM
:
{
const
amd64_binop_addr_attr_t
*
const
binop_attr
=
(
const
amd64_binop_addr_attr_t
*
)
attr
;
amd64_emit_immediate32
(
true
,
&
binop_attr
->
u
.
immediate
);
be_emit_char
(
'$'
);
x86_emit_imm32
(
&
binop_attr
->
u
.
immediate
);
be_emit_cstring
(
", "
);
goto
emit_addr
;
}
...
...
@@ -368,7 +332,7 @@ emit_addr_reg:
return
;
}
case
AMD64_OP_IMM32
:
amd64
_emit_imm
ediate32
(
false
,
&
attr
->
addr
.
immediate
);
x86
_emit_imm
32
(
&
attr
->
addr
.
immediate
);
return
;
case
AMD64_OP_X87
:
...
...
@@ -725,11 +689,12 @@ static void emit_amd64_asm_operand(ir_node const *const node, char const modifie
return
;
}
case
ASM_OP_IMMEDIATE
:
{
amd64_emit_immediate32
(
modifier
!=
'c'
,
&
op
->
u
.
imm32
);
case
ASM_OP_IMMEDIATE
:
if
(
modifier
!=
'c'
)
be_emit_char
(
'$'
);
x86_emit_imm32
(
&
op
->
u
.
imm32
);
return
;
}
}
panic
(
"invalid asm operand kind"
);
}
...
...
ir/be/ia32/ia32_emitter.c
View file @
2dd358a8
...
...
@@ -184,53 +184,14 @@ static void emit_register(const arch_register_t *reg, ir_mode *mode)
be_emit_string
(
name
);
}
static
void
ia32_emit_relocation
(
x86_imm32_t
const
*
const
imm
)
{
ir_entity
*
entity
=
imm
->
entity
;
be_gas_emit_entity
(
entity
);
switch
(
imm
->
kind
)
{
case
X86_IMM_ADDR
:
case
X86_IMM_PCREL
:
return
;
case
X86_IMM_TLS_IE
:
be_emit_cstring
(
"@INDNTPOFF"
);
return
;
case
X86_IMM_TLS_LE
:
be_emit_cstring
(
"@NTPOFF"
);
return
;
case
X86_IMM_GOT
:
be_emit_cstring
(
"@GOT"
);
return
;
case
X86_IMM_GOTOFF
:
be_emit_cstring
(
"@GOTOFF"
);
return
;
case
X86_IMM_PLT
:
be_emit_cstring
(
"@PLT"
);
return
;
case
X86_IMM_PICBASE_REL
:
be_emit_char
(
'-'
);
be_emit_string
(
pic_base_label
);
return
;
case
X86_IMM_FRAMEENT
:
case
X86_IMM_FRAMEOFFSET
:
case
X86_IMM_GOTPCREL
:
case
X86_IMM_VALUE
:
break
;
}
panic
(
"Unexpected immediate kind"
);
}
static
void
emit_ia32_immediate
(
bool
const
prefix
,
x86_imm32_t
const
*
const
imm
)
static
void
emit_ia32_immediate_attr
(
bool
const
prefix
,
ir_node
const
*
const
node
)
{
ia32_immediate_attr_t
const
*
const
attr
=
get_ia32_immediate_attr_const
(
node
);
if
(
prefix
)
be_emit_char
(
'$'
);
ir_entity
const
*
const
entity
=
imm
->
entity
;
int32_t
const
offset
=
imm
->
offset
;
if
(
entity
!=
NULL
)
{
assert
(
imm
->
kind
!=
X86_IMM_VALUE
);
ia32_emit_relocation
(
imm
);
if
(
offset
!=
0
)
be_emit_irprintf
(
"%+"
PRId32
,
offset
);
}
else
{
assert
(
imm
->
kind
==
X86_IMM_VALUE
);
be_emit_irprintf
(
"0x%"
PRIX32
,
(
uint32_t
)
offset
);
}
}
static
void
emit_ia32_immediate_attr
(
bool
const
prefix
,
ir_node
const
*
const
node
)
{
ia32_immediate_attr_t
const
*
const
attr
=
get_ia32_immediate_attr_const
(
node
);
emit_ia32_immediate
(
prefix
,
&
attr
->
imm
);
x86_emit_imm32
(
&
attr
->
imm
);
}
static
void
ia32_emit_mode_suffix_mode
(
const
ir_mode
*
mode
)
...
...
@@ -383,9 +344,7 @@ static void ia32_emit_am(ir_node const *const node)
int32_t
const
offset
=
attr
->
addr
.
immediate
.
offset
;
ir_entity
const
*
const
entity
=
attr
->
addr
.
immediate
.
entity
;
if
(
entity
)
{
assert
(
attr
->
addr
.
immediate
.
kind
!=
X86_IMM_VALUE
);
const
ia32_attr_t
*
attr
=
get_ia32_attr_const
(
node
);
ia32_emit_relocation
(
&
attr
->
addr
.
immediate
);
x86_emit_relocation_no_offset
(
attr
->
addr
.
immediate
.
kind
,
entity
);
if
(
offset
!=
0
)
be_emit_irprintf
(
"%+"
PRId32
,
offset
);
}
else
if
(
offset
!=
0
||
(
!
base
&&
!
idx
))
{
...
...
@@ -1002,7 +961,9 @@ static void emit_ia32_asm_operand(ir_node const *const node, char const modifier
}
case
ASM_OP_IMMEDIATE
:
emit_ia32_immediate
(
modifier
!=
'c'
,
&
op
->
u
.
imm32
);
if
(
modifier
!=
'c'
)
be_emit_char
(
'$'
);
x86_emit_imm32
(
&
op
->
u
.
imm32
);
return
;
}
panic
(
"invalid asm operand kind"
);
...
...
@@ -1644,11 +1605,6 @@ static unsigned emit_jit_entity_relocation_asm(char *const buffer,
return
4
;
}
x86_imm32_t
imm
=
{
.
kind
=
be_kind
,
.
entity
=
entity
,
.
offset
=
offset
,
};
unsigned
res
=
4
;
if
(
be_kind
==
X86_IMM_PCREL
)
{
/* cheat... */
...
...
@@ -1657,7 +1613,9 @@ static unsigned emit_jit_entity_relocation_asm(char *const buffer,
}
else
{
be_emit_cstring
(
"
\t
.long "
);
}
ia32_emit_relocation
(
&
imm
);
x86_emit_relocation_no_offset
(
be_kind
,
entity
);
if
(
offset
!=
0
)
be_emit_irprintf
(
"%+"
PRId32
,
offset
);
be_emit_char
(
'\n'
);
be_emit_write_line
();
return
res
;
...
...
@@ -1689,6 +1647,7 @@ void ia32_emit_function(ir_graph *const irg)
}
get_unique_label
(
pic_base_label
,
sizeof
(
pic_base_label
),
"PIC_BASE"
);
x86_pic_base_label
=
pic_base_label
;
if
(
ia32_cg_config
.
emit_machcode
)
{
/* For debugging we can jit the code and output it embedded into a
...
...
ir/be/ia32/x86_imm.c
View file @
2dd358a8
...
...
@@ -13,13 +13,17 @@
#include <inttypes.h>
#include "bediagnostic.h"
#include "begnuas.h"
#include "betranshlp.h"
#include "beemitter.h"
#include "irmode_t.h"
#include "irnode_t.h"
#include "irprintf.h"
#include "panic.h"
#include "tv_t.h"
char
const
*
x86_pic_base_label
;
static
bool
check_immediate_constraint
(
long
val
,
char
immediate_constraint_type
)
{
/* Workaround for warning about always true comparison when long has 32 bits. */
...
...
@@ -114,3 +118,48 @@ void x86_dump_imm32(x86_imm32_t const *const imm, FILE *const F)
if
(
imm
->
kind
!=
X86_IMM_VALUE
&&
imm
->
kind
!=
X86_IMM_ADDR
)
fprintf
(
F
,
" [%s]"
,
x86_get_immediate_kind_str
(
imm
->
kind
));
}
void
x86_emit_relocation_no_offset
(
x86_immediate_kind_t
const
kind
,
ir_entity
const
*
const
entity
)
{
be_gas_emit_entity
(
entity
);
switch
(
kind
)
{
case
X86_IMM_ADDR
:
case
X86_IMM_PCREL
:
return
;
case
X86_IMM_PICBASE_REL
:
be_emit_char
(
'-'
);
be_emit_string
(
x86_pic_base_label
);
return
;
char
const
*
rstr
;
case
X86_IMM_GOTPCREL
:
rstr
=
"@GOTPCREL"
;
goto
emit_str
;
case
X86_IMM_PLT
:
rstr
=
"@PLT"
;
goto
emit_str
;
case
X86_IMM_TLS_IE
:
rstr
=
"@INDNTPOFF"
;
goto
emit_str
;
case
X86_IMM_TLS_LE
:
rstr
=
"@NTPOFF"
;
goto
emit_str
;
case
X86_IMM_GOT
:
rstr
=
"@GOT"
;
goto
emit_str
;
case
X86_IMM_GOTOFF
:
rstr
=
"@GOTOFF"
;
goto
emit_str
;
emit_str:
be_emit_string
(
rstr
);
return
;
case
X86_IMM_VALUE
:
case
X86_IMM_FRAMEENT
:
case
X86_IMM_FRAMEOFFSET
:
break
;
}
panic
(
"unexpected or invalid immediate kind"
);
}
void
x86_emit_imm32
(
x86_imm32_t
const
*
const
imm
)
{
x86_immediate_kind_t
const
kind
=
imm
->
kind
;
int32_t
const
offset
=
imm
->
offset
;
if
(
kind
==
X86_IMM_VALUE
)
{
assert
(
imm
->
entity
==
NULL
);
be_emit_irprintf
(
"%"
PRId32
,
(
uint32_t
)
offset
);
}
else
{
x86_emit_relocation_no_offset
(
kind
,
imm
->
entity
);
if
(
offset
!=
0
)
be_emit_irprintf
(
"%+"
PRId32
,
offset
);
}
}
ir/be/ia32/x86_imm.h
View file @
2dd358a8
...
...
@@ -17,6 +17,8 @@
#include "compiler.h"
#include "firm_types.h"
extern
char
const
*
x86_pic_base_label
;
/** immediate/relocation types (see also ELF file format) */
typedef
enum
x86_immediate_kind_t
{
X86_IMM_VALUE
,
/**< no relocation, just a value */
...
...
@@ -49,6 +51,10 @@ char const *x86_get_immediate_kind_str(x86_immediate_kind_t const kind);
void
x86_dump_imm32
(
x86_imm32_t
const
*
imm
,
FILE
*
F
);
void
x86_emit_imm32
(
x86_imm32_t
const
*
imm
);
void
x86_emit_relocation_no_offset
(
x86_immediate_kind_t
kind
,
ir_entity
const
*
entity
);
static
inline
bool
x86_imm32_equal
(
x86_imm32_t
const
*
const
imm0
,
x86_imm32_t
const
*
const
imm1
)
{
...
...
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