bearch_TEMPLATE.c 4.85 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
 */

Matthias Braun's avatar
Matthias Braun committed
6
7
8
9
/**
 * @file
 * @brief    The main TEMPLATE backend driver file.
 */
10
11
12
#include "TEMPLATE_emitter.h"
#include "TEMPLATE_new_nodes.h"
#include "TEMPLATE_transform.h"
13
#include "be_t.h"
14
#include "beirg.h"
15
#include "bemodule.h"
16
#include "benode.h"
17
#include "bera.h"
18
#include "besched.h"
19
#include "bestack.h"
20
#include "debug.h"
21
#include "gen_TEMPLATE_regalloc_if.h"
22
#include "iredges_t.h"
23
#include "irprog_t.h"
24
25
26
#include "lower_builtins.h"
#include "lower_calls.h"
#include "panic.h"
27
28

/**
29
 * Transforms the standard firm graph into a TEMPLATE firm graph
30
 */
31
static void TEMPLATE_select_instructions(ir_graph *irg)
32
{
33
	/* transform nodes into assembler instructions */
34
	be_timer_push(T_CODEGEN);
35
	TEMPLATE_transform_graph(irg);
36
	be_timer_pop(T_CODEGEN);
37
	be_dump(DUMP_BE, irg, "code-selection");
38
39
}

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
static ir_node *TEMPLATE_new_spill(ir_node *value, ir_node *after)
{
	(void)value;
	(void)after;
	panic("spilling not implemented yet");
}

static ir_node *TEMPLATE_new_reload(ir_node *value, ir_node *spill,
                                    ir_node *before)
{
	(void)value;
	(void)spill;
	(void)before;
	panic("reload not implemented yet");
}

static const regalloc_if_t TEMPLATE_regalloc_if = {
	.spill_cost  = 7,
	.reload_cost = 5,
	.new_spill   = TEMPLATE_new_spill,
	.new_reload  = TEMPLATE_new_reload,
};

63
64
65
66
67
static void introduce_prologue(ir_graph *const irg)
{
	arch_register_t const *const sp         = &TEMPLATE_registers[REG_SP];
	ir_node               *const start      = get_irg_start(irg);
	ir_node               *const block      = get_nodes_block(start);
Christoph Mallon's avatar
Christoph Mallon committed
68
	ir_node               *const initial_sp = be_get_Start_proj(irg, sp);
69
	ir_type               *const frame_type = get_irg_frame_type(irg);
70
	unsigned               const frame_size = get_type_size(frame_type);
71
72
73
74
75
	ir_node               *const incsp      = be_new_IncSP(sp, block, initial_sp, frame_size, 0);
	edges_reroute_except(initial_sp, incsp, incsp);
	sched_add_after(start, incsp);
}

76
77
78
static void TEMPLATE_generate_code(FILE *output, const char *cup_name)
{
	be_begin(output, cup_name);
79
	unsigned *const sp_is_non_ssa = rbitset_alloca(N_TEMPLATE_REGISTERS);
80
	rbitset_set(sp_is_non_ssa, REG_SP);
81

82
83
84
	foreach_irp_irg(i, irg) {
		if (!be_step_first(irg))
			continue;
85

86
		be_birg_from_irg(irg)->non_ssa_regs = sp_is_non_ssa;
87
		TEMPLATE_select_instructions(irg);
88

89
		be_step_schedule(irg);
90

91
		be_step_regalloc(irg, &TEMPLATE_regalloc_if);
92

93
94
		introduce_prologue(irg);

95
		be_fix_stack_nodes(irg, &TEMPLATE_registers[REG_SP]);
96
		be_birg_from_irg(irg)->non_ssa_regs = NULL;
97
98
99
100
101
102
103

		TEMPLATE_emit_function(irg);

		be_step_last(irg);
	}

	be_finish();
104
105
}

106
static void TEMPLATE_init(void)
107
{
Matthias Braun's avatar
Matthias Braun committed
108
	TEMPLATE_register_init();
109
	TEMPLATE_create_opcodes();
110
111
}

Matthias Braun's avatar
Matthias Braun committed
112
113
114
115
116
static void TEMPLATE_finish(void)
{
	TEMPLATE_free_opcodes();
}

117
118
static void TEMPLATE_lower_for_target(void)
{
119
	lower_builtins(0, NULL);
120
	be_after_irp_transform("lower-builtins");
121

122
	/* lower compound param handling */
123
	lower_calls_with_compounds(LF_RETURN_HIDDEN, NULL);
124
	be_after_irp_transform("lower-calls");
125
126
}

127
128
129
static int TEMPLATE_is_mux_allowed(ir_node *sel, ir_node *mux_false,
                                   ir_node *mux_true)
{
Matthias Braun's avatar
Matthias Braun committed
130
131
132
	(void)sel;
	(void)mux_false;
	(void)mux_true;
133
134
135
	return false;
}

136
137
138
/**
 * Returns the libFirm configuration parameter for this backend.
 */
139
140
static const backend_params *TEMPLATE_get_backend_params(void)
{
141
	static backend_params p = {
142
143
144
145
146
147
148
149
150
151
152
153
154
		.byte_order_big_endian         = false,
		.pic_supported                 = false,
		.unaligned_memaccess_supported = false,
		.modulo_shift                  = 32,
		.dep_param                     = NULL,
		.allow_ifconv                  = TEMPLATE_is_mux_allowed,
		.machine_size                  = 32,
		.mode_float_arithmetic         = NULL,
		.type_long_long                = NULL,
		.type_unsigned_long_long       = NULL,
		.type_long_double              = NULL,
		.stack_param_align             = 4,
		.float_int_overflow            = ir_overflow_min_max,
155
156
157
158
	};
	return &p;
}

159
160
161
162
163
164
165
166
167
static unsigned TEMPLATE_get_op_estimated_cost(const ir_node *node)
{
	if (is_TEMPLATE_Load(node))
		return 5;
	if (is_TEMPLATE_Store(node))
		return 7;
	return 1;
}

168
static arch_isa_if_t const TEMPLATE_isa_if = {
169
170
171
172
173
174
175
176
177
	.n_registers           = N_TEMPLATE_REGISTERS,
	.registers             = TEMPLATE_registers,
	.n_register_classes    = N_TEMPLATE_CLASSES,
	.register_classes      = TEMPLATE_reg_classes,
	.init                  = TEMPLATE_init,
	.finish                = TEMPLATE_finish,
	.get_params            = TEMPLATE_get_backend_params,
	.generate_code         = TEMPLATE_generate_code,
	.lower_for_target      = TEMPLATE_lower_for_target,
178
	.is_valid_clobber      = be_default_is_valid_clobber,
179
	.get_op_estimated_cost = TEMPLATE_get_op_estimated_cost,
180
};
181

Matthias Braun's avatar
Matthias Braun committed
182
BE_REGISTER_MODULE_CONSTRUCTOR(be_init_arch_TEMPLATE)
183
184
185
void be_init_arch_TEMPLATE(void)
{
	be_register_isa_if("TEMPLATE", &TEMPLATE_isa_if);
186
	TEMPLATE_init_transform();
187
}