bearch.c 3.51 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Christian Würdig's avatar
Christian Würdig committed
4
5
 */

6
/**
Christian Würdig's avatar
Christian Würdig committed
7
8
9
 * @file
 * @brief       Processor architecture specification.
 * @author      Sebastian Hack
10
 */
11
#include "be_t.h"
12
#include "bearch.h"
13
#include "benode.h"
14
#include "beinfo.h"
Sebastian Hack's avatar
Sebastian Hack committed
15
#include "ircons_t.h"
Daniel Grund's avatar
Daniel Grund committed
16
#include "irnode_t.h"
17
#include "irop_t.h"
Matthias Braun's avatar
Matthias Braun committed
18
#include "raw_bitset.h"
19

20
arch_register_req_t const arch_no_requirement = {
21
22
23
24
25
26
	.cls             = NULL,
	.limited         = NULL,
	.type            = arch_register_req_type_none,
	.other_same      = 0,
	.other_different = 0,
	.width           = 0,
27
28
};

29
static reg_out_info_t *get_out_info_n(const ir_node *node, unsigned pos)
30
{
31
	const backend_info_t *info = be_get_info(node);
32
	assert(pos < (unsigned)ARR_LEN(info->out_infos));
33
	return &info->out_infos[pos];
34
}
35

36
37

const arch_register_t *arch_get_irn_register(const ir_node *node)
38
{
39
40
	const reg_out_info_t *out = get_out_info(node);
	return out->reg;
41
}
Sebastian Hack's avatar
Sebastian Hack committed
42

43
44
const arch_register_t *arch_get_irn_register_out(const ir_node *node,
                                                 unsigned pos)
Sebastian Hack's avatar
Sebastian Hack committed
45
{
46
47
48
49
	const reg_out_info_t *out = get_out_info_n(node, pos);
	return out->reg;
}

50
51
52
53
54
55
const arch_register_t *arch_get_irn_register_in(const ir_node *node, int pos)
{
	ir_node *op = get_irn_n(node, pos);
	return arch_get_irn_register(op);
}

56
void arch_set_irn_register_out(ir_node *node, unsigned pos,
57
                               const arch_register_t *reg)
58
59
60
61
62
63
64
65
66
67
68
{
	reg_out_info_t *out = get_out_info_n(node, pos);
	out->reg            = reg;
}

void arch_set_irn_register(ir_node *node, const arch_register_t *reg)
{
	reg_out_info_t *out = get_out_info(node);
	out->reg = reg;
}

69
70
71
bool arch_reg_is_allocatable(const arch_register_req_t *req,
                             const arch_register_t *reg)
{
72
	if (req->cls != reg->cls)
73
		return false;
74
	if (reg->type & arch_register_type_virtual)
75
		return true;
76
	if (arch_register_req_is(req, limited))
77
		return rbitset_is_set(req->limited, reg->index);
78
	return true;
79
80
}

81
arch_register_t const *arch_find_register(char const *const name)
82
{
83
84
85
	arch_register_t const *const regs = isa_if->registers;
	for (size_t i = 0, n = isa_if->n_registers; i < n; ++i) {
		arch_register_t const *const reg = &regs[i];
86
87
88
89
90
91
		if (strcmp(reg->name, name) == 0)
			return reg;
	}
	return NULL;
}

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
void be_make_start_mem(be_start_info_t *const info, ir_node *const start, unsigned const pos)
{
  info->pos = pos;
  info->irn = NULL;
  arch_set_irn_register_req_out(start, pos, arch_no_register_req);
}

void be_make_start_out(be_start_info_t *const info, struct obstack *const obst, ir_node *const start, unsigned const pos, arch_register_t const *const reg, arch_register_req_type_t const flags)
{
	info->pos = pos;
	info->irn = NULL;
	arch_register_req_t const *const req =
		flags == arch_register_req_type_none ? reg->single_req :
		be_create_reg_req(obst, reg, flags);
	arch_set_irn_register_req_out(start, pos, req);
	arch_set_irn_register_out(start, pos, reg);
}

ir_node *be_get_start_proj(ir_graph *const irg, be_start_info_t *const info)
{
	if (!info->irn) {
		/* This is already the transformed start node. */
		ir_node                     *const start = get_irg_start(irg);
		arch_register_class_t const *const cls   = arch_get_irn_register_req_out(start, info->pos)->cls;
		info->irn = new_r_Proj(start, cls ? cls->mode : mode_M, info->pos);
	}
	return info->irn;
}
120
121
122
123
124
125
126

void arch_copy_irn_out_info(ir_node *const dst, unsigned const dst_pos, ir_node const *const src)
{
	reg_out_info_t *const src_info = get_out_info(src);
	reg_out_info_t *const dst_info = get_out_info_n(dst, dst_pos);
	*dst_info = *src_info;
}