Exemplo n.º 1
0
static void fix_address_pic_elf(ir_node *const node, void *const data)
{
	(void)data;
	foreach_irn_in(node, i, pred) {
		if (!is_Address(pred))
			continue;
		ir_entity *const entity = get_Address_entity(pred);
		if (is_tls_entity(entity))
			continue;

		ir_graph *const irg         = get_irn_irg(node);
		bool      const ext_visible = is_externally_visible(entity);
		ir_node  *      res;
		if (i == n_Call_ptr && is_Call(node)) {
			/* We can compilation-unit local functions directly, everything else
			 * goes through the PLT */
			x86_immediate_kind_t const reloc
				= ext_visible ? X86_IMM_PLT : X86_IMM_PCREL;
			res = be_new_Relocation(irg, reloc, entity, mode_P);
		} else if (!ext_visible) {
			res = be_new_Relocation(irg, X86_IMM_PCREL, entity, mode_P);
		} else {
			res = create_gotpcrel_load(irg, entity);
		}
		set_irn_n(node, i, res);
	}
}
Exemplo n.º 2
0
static void fix_address_pic_mach_o(ir_node *const node, void *const data)
{
	(void)data;
	foreach_irn_in(node, i, pred) {
		if (!is_Address(pred))
			continue;
		ir_entity *const entity = get_Address_entity(pred);
		if (is_tls_entity(entity))
			continue;

		ir_graph *const irg = get_irn_irg(node);
		ir_node  *      res;
		if (i == n_Call_ptr && is_Call(node)) {
			// Somehow we can always call PC relative. Are there trampolines
			// involved?
			res = be_new_Relocation(irg, X86_IMM_PCREL, entity, mode_P);
		} else if (entity_has_definition(entity)
		        && !(get_entity_linkage(entity) & IR_LINKAGE_MERGE)) {
			res = be_new_Relocation(irg, X86_IMM_PCREL, entity, mode_P);
		} else {
			res = create_gotpcrel_load(irg, entity);
		}
		set_irn_n(node, i, res);
	}
}
Exemplo n.º 3
0
static bool eat_imm(x86_address_t *const addr, ir_node const *const node,
                    bool basereg_usable)
{
	switch (get_irn_opcode(node)) {
	case iro_Add:
		/* Add is supported as long as both operands are immediates. */
		return
			!x86_is_non_address_mode_node(node) &&
			eat_imm(addr, get_Add_left(node), basereg_usable) &&
			eat_imm(addr, get_Add_right(node), basereg_usable);

	case iro_Address:
		/* The first Address of a DAG can be folded into an immediate. */
		if (addr->imm.entity)
			return false;
		addr->imm.entity = get_Address_entity(node);
		addr->imm.kind = X86_IMM_ADDR;
		if (is_tls_entity(addr->imm.entity))
			addr->tls_segment = true;
		return true;

	case iro_Const: {
		/* Add the value to the offset. */
		ir_tarval *const tv = get_Const_tarval(node);
		if (!tarval_possible(tv))
			return false;
		addr->imm.offset += get_tarval_long(tv);
		return true;
	}

	case iro_Unknown:
		/* Use '0' for Unknowns. */
		return true;

	default:
		if (be_is_Relocation(node)) {
			if (addr->imm.entity)
				return false;
			addr->imm.entity = be_get_Relocation_entity(node);
			x86_immediate_kind_t const kind
				= (x86_immediate_kind_t)be_get_Relocation_kind(node);
			addr->imm.kind = kind;
			if (kind == X86_IMM_GOTPCREL || kind == X86_IMM_PCREL) {
				if (!basereg_usable)
					return false;
				addr->ip_base = true;
			}
			return true;
		}
		/* All other nodes are no immediates. */
		return false;
	}
}