Commit a924aadd authored by Matthias Braun's avatar Matthias Braun
Browse files

amd64: Use immediate kinds

Handle this similar to the ia32 backend.
parent 9e3120b9
......@@ -203,26 +203,51 @@ ENUM_BITSET(amd64_emit_mod_t)
static void amd64_emit_immediate64(const amd64_imm64_t *const imm)
{
ir_entity *entity = imm->entity;
if (entity != NULL) {
int64_t offset = imm->offset;
switch (imm->kind) {
case X86_IMM_VALUE:
assert(entity == NULL);
be_emit_irprintf("0x%" PRIX64, offset);
return;
case X86_IMM_ADDR:
assert(entity != NULL);
be_gas_emit_entity(entity);
if (imm->offset != 0)
be_emit_irprintf("%+" PRId64, imm->offset);
} else {
be_emit_irprintf("0x%" PRIX64, imm->offset);
if (offset != 0)
be_emit_irprintf("%+" PRId64, offset);
return;
case X86_IMM_TLS_IE:
case X86_IMM_TLS_LE:
case X86_IMM_PICBASE_REL:
case X86_IMM_FRAMEOFFSET:
break;
}
panic("unexpected or invalid immediate kind");
}
static void amd64_emit_immediate32(bool const prefix, x86_imm32_t const *const imm)
{
if (prefix)
be_emit_char('$');
if (imm->entity) {
be_gas_emit_entity(imm->entity);
if (imm->offset != 0)
be_emit_irprintf("%+" PRId32, imm->offset);
} else {
be_emit_irprintf("%" PRId32, imm->offset);
ir_entity *entity = imm->entity;
int32_t offset = imm->offset;
switch (imm->kind) {
case X86_IMM_VALUE:
assert(entity == NULL);
be_emit_irprintf("%" PRId32, offset);
return;
case X86_IMM_ADDR:
assert(entity != NULL);
be_gas_emit_entity(entity);
if (offset != 0)
be_emit_irprintf("%+" PRId32, offset);
return;
case X86_IMM_TLS_IE:
case X86_IMM_TLS_LE:
case X86_IMM_PICBASE_REL:
case X86_IMM_FRAMEOFFSET:
break;
}
panic("unexpected or invalid immediate kind");
}
static bool is_fp_relative(const ir_entity *entity)
......
......@@ -140,12 +140,11 @@ static void init_amd64_cc_attributes(ir_node *node, x86_condition_code_t cc)
static void init_amd64_movimm_attributes(ir_node *node,
amd64_insn_mode_t insn_mode,
ir_entity *entity, int64_t offset)
const amd64_imm64_t *imm)
{
amd64_movimm_attr_t *attr = get_amd64_movimm_attr(node);
attr->insn_mode = insn_mode;
attr->immediate.entity = entity;
attr->immediate.offset = offset;
attr->insn_mode = insn_mode;
attr->immediate = *imm;
}
static bool imm64s_equal(const amd64_imm64_t *const imm0,
......
......@@ -67,8 +67,9 @@ enum {
};
typedef struct {
ir_entity *entity;
int64_t offset;
ir_entity *entity;
int64_t offset;
ENUMBF(x86_immediate_kind_t) kind : 8;
} amd64_imm64_t;
typedef struct {
......
......@@ -88,7 +88,7 @@ $default_copy_attr = "amd64_copy_attr";
."\tinit_amd64_cc_attributes(res, cc);",
amd64_movimm_attr_t =>
"init_amd64_attributes(res, irn_flags_, in_reqs, n_res, op_mode);\n"
."\tinit_amd64_movimm_attributes(res, insn_mode, entity, offset);",
."\tinit_amd64_movimm_attributes(res, insn_mode, imm);",
amd64_shift_attr_t =>
"be_info_init_irn(res, irn_flags_, in_reqs, n_res);\n"
."\t*attr = *attr_init;\n",
......@@ -365,7 +365,7 @@ mov_imm => {
irn_flags => [ "rematerializable" ],
out_reqs => [ "gp" ],
attr_type => "amd64_movimm_attr_t",
attr => "amd64_insn_mode_t insn_mode, int64_t offset, ir_entity *entity",
attr => "amd64_insn_mode_t insn_mode, const amd64_imm64_t *imm",
fixed => "amd64_op_mode_t op_mode = AMD64_OP_IMM64;",
emit => 'mov%MM $%C, %D0',
mode => $mode_gp,
......
......@@ -391,7 +391,11 @@ static ir_node *gen_Const(ir_node *node)
uint64_t val = get_tarval_uint64(tv);
amd64_insn_mode_t imode = val > UINT32_MAX ? INSN_MODE_64 : INSN_MODE_32;
return new_bd_amd64_mov_imm(dbgi, block, imode, val, NULL);
amd64_imm64_t const imm = {
.kind = X86_IMM_VALUE,
.offset = val,
};
return new_bd_amd64_mov_imm(dbgi, block, imode, &imm);
}
static ir_node *gen_Address(ir_node *node)
......@@ -402,8 +406,13 @@ static ir_node *gen_Address(ir_node *node)
/* do we need RIP-relative addressing because of PIC? */
reference_mode_t mode = need_relative_addressing(entity);
if (mode == REFERENCE_DIRECT)
return new_bd_amd64_mov_imm(dbgi, block, INSN_MODE_64, 0, entity);
if (mode == REFERENCE_DIRECT) {
amd64_imm64_t const imm = {
.kind = X86_IMM_ADDR,
.entity = entity,
};
return new_bd_amd64_mov_imm(dbgi, block, INSN_MODE_64, &imm);
}
amd64_addr_t addr;
memset(&addr, 0, sizeof(addr));
......@@ -459,7 +468,8 @@ static bool match_immediate_32(x86_imm32_t *imm, const ir_node *op,
bool upper32_dont_care)
{
assert(mode_needs_gp_reg(get_irn_mode(op)));
assert(imm->offset == 0 && imm->entity == NULL);
assert(imm->offset == 0 && imm->entity == NULL
&& imm->kind == X86_IMM_VALUE);
ir_tarval *tv;
ir_entity *entity;
......@@ -483,13 +493,19 @@ static bool match_immediate_32(x86_imm32_t *imm, const ir_node *op,
val = 0;
}
if (entity && !can_match_ip_relative) {
/* TODO: check if entity is in lower 4GB address space/relative */
return false;
x86_immediate_kind_t kind = X86_IMM_VALUE;
if (entity != NULL) {
if (!can_match_ip_relative) {
/* TODO: check if entity is in lower 4GB address space/relative */
return false;
}
/* TODO: use a new relocation type for ip-relative? */
kind = X86_IMM_ADDR;
}
imm->offset = val;
imm->entity = entity;
imm->offset = val;
imm->kind = kind;
return true;
}
......@@ -1637,11 +1653,13 @@ static ir_node *gen_Call(ir_node *node)
/* vararg calls need the number of SSE registers used */
if (get_method_variadicity(type) == variadicity_variadic) {
unsigned xmm_regs = cconv->n_xmm_regs;
ir_node *xmm_imm = new_bd_amd64_mov_imm(dbgi, block, INSN_MODE_32,
xmm_regs, NULL);
amd64_imm64_t const imm = {
.kind = X86_IMM_VALUE,
.offset = cconv->n_xmm_regs,
};
ir_node *nxmm = new_bd_amd64_mov_imm(dbgi, block, INSN_MODE_32, &imm);
in_req[in_arity] = amd64_registers[REG_RAX].single_req;
in[in_arity] = xmm_imm;
in[in_arity] = nxmm;
++in_arity;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment