コード例 #1
0
ファイル: amd64_emitter.c プロジェクト: mj3-16/libfirm
static void emit_shiftop(const ir_node *const node)
{
	amd64_shift_attr_t const *const attr = get_amd64_shift_attr_const(node);

	switch (attr->base.op_mode) {
	case AMD64_OP_SHIFT_IMM: {
		be_emit_irprintf("$%u, ", attr->immediate);
		const arch_register_t *reg = arch_get_irn_register_in(node, 0);
		emit_register_mode(reg, attr->base.size);
		return;
	}
	case AMD64_OP_SHIFT_REG: {
		const arch_register_t *reg0 = arch_get_irn_register_in(node, 0);
		const arch_register_t *reg1 = arch_get_irn_register_in(node, 1);
		emit_register_mode(reg1, X86_SIZE_8);
		be_emit_cstring(", ");
		emit_register_mode(reg0, attr->base.size);
		return;
	}
	default:
		break;
	}
	panic("invalid op_mode for shiftop");
}
コード例 #2
0
static bool node_has_sp_base(ir_node const *const node)
{
	int input;
	if (is_sparc_FrameAddr(node)) {
		input = n_sparc_FrameAddr_base;
	} else if (is_sparc_Ld(node)) {
		input = n_sparc_Ld_ptr;
	} else if (is_sparc_St(node)) {
		input = n_sparc_St_ptr;
	} else if (is_sparc_Ldf(node)) {
		input = n_sparc_Ldf_ptr;
	} else if (is_sparc_Stf(node)) {
		input = n_sparc_Stf_ptr;
	} else {
		panic("Unexpected node %+F", node);
	}
	arch_register_t const *const reg = arch_get_irn_register_in(node, input);
	return reg == &sparc_registers[REG_SP];
}
コード例 #3
0
ファイル: amd64_emitter.c プロジェクト: qznc/libfirm
void amd64_emitf(ir_node const *const node, char const *fmt, ...)
{
	va_list ap;
	va_start(ap, fmt);

	be_emit_char('\t');
	for (;;) {
		char const *start = fmt;

		while (*fmt != '%' && *fmt != '\n' && *fmt != '\0')
			++fmt;
		if (fmt != start) {
			be_emit_string_len(start, fmt - start);
		}

		if (*fmt == '\n') {
			be_emit_char('\n');
			be_emit_write_line();
			be_emit_char('\t');
			++fmt;
			continue;
		}

		if (*fmt == '\0')
			break;

		++fmt;
		amd64_emit_mod_t mod = EMIT_NONE;
		for (;;) {
			switch (*fmt) {
			case '#': mod |= EMIT_RESPECT_LS;  break;
			case '^': mod |= EMIT_IGNORE_MODE; break;
			default:
				goto end_of_mods;
			}
			++fmt;
		}
end_of_mods:

		switch (*fmt++) {
			arch_register_t const *reg;

			case '%':
				be_emit_char('%');
				break;

			case 'C': {
				amd64_attr_t const *const attr = get_amd64_attr_const(node);
				/* FIXME: %d is a hack... we must emit 64bit constants, or sign
				 * extended 32bit constants... */
				be_emit_irprintf("$%d", attr->ext.imm_value);
				break;
			}

			case 'D':
				if (*fmt < '0' || '9' <= *fmt)
					goto unknown;
				reg = arch_get_irn_register_out(node, *fmt++ - '0');
				goto emit_R;

			case 'E': {
				ir_entity const *const ent = va_arg(ap, ir_entity const*);
				be_gas_emit_entity(ent);
				break;
			}

			case 'L': {
				ir_node *const block = get_cfop_target_block(node);
				be_gas_emit_block_name(block);
				break;
			}

			case 'O': {
				amd64_SymConst_attr_t const *const attr = get_amd64_SymConst_attr_const(node);
				if (attr->fp_offset)
					be_emit_irprintf("%d", attr->fp_offset);
				break;
			}

			case 'R':
				reg = va_arg(ap, arch_register_t const*);
emit_R:
				if (mod & EMIT_IGNORE_MODE) {
					emit_register(reg);
				} else {
					amd64_attr_t const *const attr = get_amd64_attr_const(node);
					if (mod & EMIT_RESPECT_LS) {
						emit_register_mode(reg, attr->ls_mode);
					} else {
						emit_register_insn_mode(reg, attr->data.insn_mode);
					}
				}
				break;

			case 'S': {
				int pos;
				if ('0' <= *fmt && *fmt <= '9') {
					pos = *fmt++ - '0';
				} else {
					goto unknown;
				}
				reg = arch_get_irn_register_in(node, pos);
				goto emit_R;
			}

			case 'M': {
				amd64_attr_t const *const attr = get_amd64_attr_const(node);
				if (mod & EMIT_RESPECT_LS) {
					amd64_emit_mode_suffix(attr->ls_mode);
				} else {
					amd64_emit_insn_mode_suffix(attr->data.insn_mode);
				}
				break;
			}

			case 'd': {
				int const num = va_arg(ap, int);
				be_emit_irprintf("%d", num);
				break;
			}

			case 's': {
				char const *const str = va_arg(ap, char const*);
				be_emit_string(str);
				break;
			}

			case 'u': {
				unsigned const num = va_arg(ap, unsigned);
				be_emit_irprintf("%u", num);
				break;
			}

			case 'c': {
				amd64_attr_t const *const attr = get_amd64_attr_const(node);
				ir_mode                  *mode = attr->ls_mode;
				if (get_mode_size_bits(mode) == 64)
					break;
				if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)
				 && attr->data.insn_mode == INSN_MODE_32)
					break;
				be_emit_char(mode_is_signed(mode) ? 's' : 'z');
				amd64_emit_mode_suffix(mode);
				break;
			}

			default:
unknown:
				panic("unknown format conversion");
		}
	}

	be_emit_finish_line_gas(node);
	va_end(ap);
}
コード例 #4
0
ファイル: amd64_emitter.c プロジェクト: mj3-16/libfirm
static void amd64_emit_am(const ir_node *const node, bool indirect_star)
{
	const amd64_addr_attr_t *const attr = get_amd64_addr_attr_const(node);

	switch ((amd64_op_mode_t)attr->base.op_mode) {
	case AMD64_OP_REG_IMM: {
		const amd64_binop_addr_attr_t *const binop_attr
			= (const amd64_binop_addr_attr_t*)attr;
		be_emit_char('$');
		x86_emit_imm32(&binop_attr->u.immediate);
		be_emit_cstring(", ");
		goto emit_addr_reg;
	}
	case AMD64_OP_REG_REG: {
		const arch_register_t *reg1 = arch_get_irn_register_in(node, 1);
		emit_register_mode(reg1, attr->base.size);
		be_emit_cstring(", ");
		goto emit_addr_reg;
	}
	case AMD64_OP_REG_ADDR: {
		const amd64_binop_addr_attr_t *const binop_attr
			= (const amd64_binop_addr_attr_t*)attr;
		x86_emit_addr(node, &attr->addr);
		be_emit_cstring(", ");
		const arch_register_t *reg
			= arch_get_irn_register_in(node, binop_attr->u.reg_input);
		emit_register_mode(reg, binop_attr->base.base.size);
		return;
	}
	case AMD64_OP_ADDR_IMM: {
		const amd64_binop_addr_attr_t *const binop_attr
			= (const amd64_binop_addr_attr_t*)attr;
		be_emit_char('$');
		x86_emit_imm32(&binop_attr->u.immediate);
		be_emit_cstring(", ");
		goto emit_addr;
	}
	case AMD64_OP_ADDR:
	case AMD64_OP_X87_ADDR_REG:
		if (indirect_star)
			be_emit_char('*');
		goto emit_addr;
	case AMD64_OP_ADDR_REG: {
		amd64_binop_addr_attr_t const *const binop_attr = (amd64_binop_addr_attr_t const*)attr;
		arch_register_t const *const reg = arch_get_irn_register_in(node, binop_attr->u.reg_input);
		emit_register_mode(reg, binop_attr->base.base.size);
		be_emit_cstring(", ");
emit_addr:
		x86_emit_addr(node, &attr->addr);
		return;
	}
	case AMD64_OP_REG: {
		if (indirect_star)
			be_emit_char('*');
emit_addr_reg:
		assert(attr->addr.variant == X86_ADDR_REG);
		arch_register_t const *const reg
			= arch_get_irn_register_in(node, attr->addr.base_input);
		emit_register_mode(reg, attr->base.size);
		return;
	}
	case AMD64_OP_IMM32:
		x86_emit_imm32(&attr->addr.immediate);
		return;

	case AMD64_OP_X87:
		return;
	case AMD64_OP_IMM64:
	case AMD64_OP_NONE:
	case AMD64_OP_SHIFT_REG:
	case AMD64_OP_SHIFT_IMM:
	case AMD64_OP_CC:
		break;
	}
	panic("invalid op_mode");
}