arm_new_nodes.c 18.3 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

20
/**
21
22
23
24
25
26
 * @file
 * @brief  This file implements the creation of the architecture specific firm
 *         opcodes and the corresponding node constructors for the arm
 *         assembler irg.
 * @author Oliver Richter, Tobias Gneist
 * @version $Id$
27
28
 */
#ifdef HAVE_CONFIG_H
29
#include "config.h"
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#endif

#include <stdlib.h>

#include "irprog_t.h"
#include "irgraph_t.h"
#include "irnode_t.h"
#include "irmode_t.h"
#include "ircons_t.h"
#include "iropt_t.h"
#include "irop.h"
#include "firm_common_t.h"
#include "irvrfy_t.h"
#include "irprintf.h"
44
#include "xmalloc.h"
45

46
#include "../bearch_t.h"
47
48
49
50
51
52
53

#include "arm_nodes_attr.h"
#include "arm_new_nodes.h"

#include "../beabi.h"
#include "bearch_arm_t.h"

Michael Beck's avatar
Michael Beck committed
54
55
56
57
/**
 * Returns the shift modifier string.
 */
const char *arm_shf_mod_name(arm_shift_modifier mod) {
Michael Beck's avatar
Michael Beck committed
58
  static const char *names[] = { NULL, NULL, "asr", "lsl", "lsr", "ror", "rrx" };
Michael Beck's avatar
Michael Beck committed
59
60
	return names[mod];
}
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

/***********************************************************************************
 *      _                                   _       _             __
 *     | |                                 (_)     | |           / _|
 *   __| |_   _ _ __ ___  _ __   ___ _ __   _ _ __ | |_ ___ _ __| |_ __ _  ___ ___
 *  / _` | | | | '_ ` _ \| '_ \ / _ \ '__| | | '_ \| __/ _ \ '__|  _/ _` |/ __/ _ \
 * | (_| | |_| | | | | | | |_) |  __/ |    | | | | | ||  __/ |  | || (_| | (_|  __/
 *  \__,_|\__,_|_| |_| |_| .__/ \___|_|    |_|_| |_|\__\___|_|  |_| \__,_|\___\___|
 *                       | |
 *                       |_|
 ***********************************************************************************/

/**
 * Dumps the register requirements for either in or out.
 */
Matthias Braun's avatar
Matthias Braun committed
76
77
static void dump_reg_req(FILE *F, const ir_node *node,
                         const arch_register_req_t **reqs, int inout) {
78
	char *dir = inout ? "out" : "in";
Matthias Braun's avatar
Matthias Braun committed
79
80
	int   max = inout ? get_arm_n_res(node) : get_irn_arity(node);
	char  buf[1024];
81
82
	int   i;

Matthias Braun's avatar
Matthias Braun committed
83
	memset(buf, 0, sizeof(buf));
84
85
86
87
88

	if (reqs) {
		for (i = 0; i < max; i++) {
			fprintf(F, "%sreq #%d =", dir, i);

Matthias Braun's avatar
Matthias Braun committed
89
			if (reqs[i]->type == arch_register_req_type_none) {
90
91
92
				fprintf(F, " n/a");
			}

Matthias Braun's avatar
Matthias Braun committed
93
94
			if (reqs[i]->type & arch_register_req_type_normal) {
				fprintf(F, " %s", reqs[i]->cls->name);
95
96
			}

Matthias Braun's avatar
Matthias Braun committed
97
98
99
			if (reqs[i]->type & arch_register_req_type_limited) {
				fprintf(F, " %s",
				        arch_register_req_format(buf, sizeof(buf), reqs[i], node));
100
101
			}

Matthias Braun's avatar
Matthias Braun committed
102
			if (reqs[i]->type & arch_register_req_type_should_be_same) {
103
104
105
				ir_fprintf(F, " same as %+F", get_irn_n(node, reqs[i]->other_same[0]));
				if (reqs[i]->other_same[1] != -1)
					ir_fprintf(F, " or %+F", get_irn_n(node, reqs[i]->other_same[1]));
106
107
			}

Matthias Braun's avatar
Matthias Braun committed
108
109
			if (reqs[i]->type & arch_register_req_type_should_be_different) {
				ir_fprintf(F, " different from %+F", get_irn_n(node, reqs[i]->other_different));
110
111
112
113
114
115
			}

			fprintf(F, "\n");
		}

		fprintf(F, "\n");
Matthias Braun's avatar
Matthias Braun committed
116
	} else {
117
118
119
120
121
122
123
124
125
126
127
		fprintf(F, "%sreq = N/A\n", dir);
	}
}

/**
 * Dumper interface for dumping arm nodes in vcg.
 * @param n        the node to dump
 * @param F        the output file
 * @param reason   indicates which kind of information should be dumped
 * @return 0 on success or != 0 on failure
 */
128
static int arm_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
Michael Beck's avatar
Michael Beck committed
129
	ir_mode     *mode = NULL;
130
131
	int          bad  = 0;
	int          i;
Michael Beck's avatar
Michael Beck committed
132
	arm_attr_t  *attr = get_arm_attr(n);
Matthias Braun's avatar
Matthias Braun committed
133
	const arch_register_req_t **reqs;
134
	const arch_register_t     **slots;
Michael Beck's avatar
Michael Beck committed
135
	arm_shift_modifier        mod;
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

	switch (reason) {
		case dump_node_opcode_txt:
			fprintf(F, "%s", get_irn_opname(n));
			break;

		case dump_node_mode_txt:
			mode = get_irn_mode(n);

			if (mode) {
				fprintf(F, "[%s]", get_mode_name(mode));
			}
			else {
				fprintf(F, "[?NOMODE?]");
			}
			break;

		case dump_node_nodeattr_txt:
Michael Beck's avatar
Michael Beck committed
154
155
156
157
158
159
160
161
			mod = ARM_GET_SHF_MOD(attr);
			if (ARM_HAS_SHIFT(mod)) {
				fprintf(F, "[%s #%ld]", arm_shf_mod_name(mod), get_tarval_long(attr->value));
			}
			else if (mod == ARM_SHF_IMM) {
				/* immediate */
				fprintf(F, "[#0x%X]", arm_decode_imm_w_shift(attr->value));
			}
162
163
164
165
166
167
168
169
170
171
172
173
			break;

		case dump_node_info_txt:
			fprintf(F, "=== arm attr begin ===\n");

			/* dump IN requirements */
			if (get_irn_arity(n) > 0) {
				reqs = get_arm_in_req_all(n);
				dump_reg_req(F, n, reqs, 0);
			}

			/* dump OUT requirements */
174
			if (ARR_LEN(attr->slots) > 0) {
175
176
177
178
179
180
				reqs = get_arm_out_req_all(n);
				dump_reg_req(F, n, reqs, 1);
			}

			/* dump assigned registers */
			slots = get_arm_slots(n);
181
182
			if (slots && ARR_LEN(attr->slots) > 0) {
				for (i = 0; i < ARR_LEN(attr->slots); i++) {
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
					if (slots[i]) {
						fprintf(F, "reg #%d = %s\n", i, slots[i]->name);
					}
					else {
						fprintf(F, "reg #%d = n/a\n", i);
					}
				}
			}
			fprintf(F, "\n");

			/* dump n_res */
			fprintf(F, "n_res = %d\n", get_arm_n_res(n));

			/* dump flags */
			fprintf(F, "flags =");
			if (attr->flags == arch_irn_flags_none) {
				fprintf(F, " none");
			}
			else {
				if (attr->flags & arch_irn_flags_dont_spill) {
					fprintf(F, " unspillable");
				}
				if (attr->flags & arch_irn_flags_rematerializable) {
					fprintf(F, " remat");
				}
				if (attr->flags & arch_irn_flags_ignore) {
					fprintf(F, " ignore");
				}
			}
			fprintf(F, " (%d)\n", attr->flags);

			if (get_arm_value(n)) {
				if (is_arm_CopyB(n)) {
Matthias Braun's avatar
Matthias Braun committed
216
					fprintf(F, "size = %lu\n", get_tarval_long(get_arm_value(n)));
217
218
				} else {
					if (mode_is_float(get_irn_mode(n))) {
Matthias Braun's avatar
Matthias Braun committed
219
						fprintf(F, "float value = (%f)\n", (double) get_tarval_double(get_arm_value(n)));
220
221
222
223
224
225
226
227
228
229
					} else if (mode_is_int(get_irn_mode(n))) {
						long v =  get_tarval_long(get_arm_value(n));
						fprintf(F, "long value = %ld (0x%08lx)\n", v, v);
					} else if (mode_is_reference(get_irn_mode(n))) {
						fprintf(F, "pointer\n");
					} else {
						assert(0 && "unbehandelter Typ im const-Knoten");
					}
				}
			}
230
			if (is_arm_CmpBra(n) && get_arm_CondJmp_proj_num(n) >= 0) {
Michael Beck's avatar
Michael Beck committed
231
				fprintf(F, "proj_num = (%d)\n", get_arm_CondJmp_proj_num(n));
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
			}
			/* TODO: dump all additional attributes */

			fprintf(F, "=== arm attr end ===\n");
			/* end of: case dump_node_info_txt */
			break;
	}
	return bad;
}



/***************************************************************************************************
 *        _   _                   _       __        _                    _   _               _
 *       | | | |                 | |     / /       | |                  | | | |             | |
 *   __ _| |_| |_ _ __   ___  ___| |_   / /_ _  ___| |_   _ __ ___   ___| |_| |__   ___   __| |___
 *  / _` | __| __| '__| / __|/ _ \ __| / / _` |/ _ \ __| | '_ ` _ \ / _ \ __| '_ \ / _ \ / _` / __|
 * | (_| | |_| |_| |    \__ \  __/ |_ / / (_| |  __/ |_  | | | | | |  __/ |_| | | | (_) | (_| \__ \
 *  \__,_|\__|\__|_|    |___/\___|\__/_/ \__, |\___|\__| |_| |_| |_|\___|\__|_| |_|\___/ \__,_|___/
 *                                        __/ |
 *                                       |___/
 ***************************************************************************************************/

Michael Beck's avatar
Michael Beck committed
255
256
257
258
259
260
261
262
263
264
265
/* Returns the attributes of a generic Arm node. */
arm_attr_t *get_arm_attr(ir_node *node) {
	assert(is_arm_irn(node) && "need arm node to get attributes");
	return get_irn_generic_attr(node);
}

const arm_attr_t *get_arm_attr_const(const ir_node *node) {
	assert(is_arm_irn(node) && "need arm node to get attributes");
	return get_irn_generic_attr_const(node);
}

266
/**
Michael Beck's avatar
Michael Beck committed
267
 * Returns the attributes of an ARM SymConst node.
268
 */
Michael Beck's avatar
Michael Beck committed
269
270
271
272
273
274
275
276
277
278
279
arm_SymConst_attr_t *get_arm_SymConst_attr(ir_node *node) {
	assert(is_arm_SymConst(node));
	return get_irn_generic_attr(node);
}

const arm_SymConst_attr_t *get_arm_SymConst_attr_const(const ir_node *node) {
	assert(is_arm_SymConst(node));
	return get_irn_generic_attr_const(node);
}

/* Returns the attributes of a CondJmp node. */
280
281
arm_CondJmp_attr_t *get_arm_CmpBra_attr(ir_node *node) {
	assert(is_arm_CmpBra(node));
Michael Beck's avatar
Michael Beck committed
282
283
284
	return get_irn_generic_attr(node);
}

285
286
const arm_CondJmp_attr_t *get_arm_CmpBra_attr_const(const ir_node *node) {
	assert(is_arm_CmpBra(node));
Michael Beck's avatar
Michael Beck committed
287
288
289
290
291
292
293
294
295
296
297
298
	return get_irn_generic_attr_const(node);
}

/* Returns the attributes of a SwitchJmp node. */
arm_SwitchJmp_attr_t *get_arm_SwitchJmp_attr(ir_node *node) {
	assert(is_arm_SwitchJmp(node));
	return get_irn_generic_attr(node);
}

const arm_SwitchJmp_attr_t *get_arm_SwitchJmp_attr_const(const ir_node *node) {
	assert(is_arm_SwitchJmp(node));
	return get_irn_generic_attr_const(node);
299
300
301
302
303
}

/**
 * Returns the argument register requirements of a arm node.
 */
Matthias Braun's avatar
Matthias Braun committed
304
const arch_register_req_t **get_arm_in_req_all(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
305
	const arm_attr_t *attr = get_arm_attr_const(node);
306
307
308
309
310
311
	return attr->in_req;
}

/**
 * Returns the result register requirements of an arm node.
 */
Matthias Braun's avatar
Matthias Braun committed
312
const arch_register_req_t **get_arm_out_req_all(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
313
	const arm_attr_t *attr = get_arm_attr_const(node);
314
315
316
317
318
319
	return attr->out_req;
}

/**
 * Returns the argument register requirement at position pos of an arm node.
 */
Matthias Braun's avatar
Matthias Braun committed
320
const arch_register_req_t *get_arm_in_req(const ir_node *node, int pos) {
Michael Beck's avatar
Michael Beck committed
321
	const arm_attr_t *attr = get_arm_attr_const(node);
322
323
324
325
326
327
	return attr->in_req[pos];
}

/**
 * Returns the result register requirement at position pos of an arm node.
 */
Matthias Braun's avatar
Matthias Braun committed
328
const arch_register_req_t *get_arm_out_req(const ir_node *node, int pos) {
Michael Beck's avatar
Michael Beck committed
329
	const arm_attr_t *attr = get_arm_attr_const(node);
330
331
332
333
334
335
	return attr->out_req[pos];
}

/**
 * Sets the OUT register requirements at position pos.
 */
Matthias Braun's avatar
Matthias Braun committed
336
void set_arm_req_out(ir_node *node, const arch_register_req_t *req, int pos) {
337
338
339
340
341
342
343
	arm_attr_t *attr   = get_arm_attr(node);
	attr->out_req[pos] = req;
}

/**
 * Sets the complete OUT requirements of node.
 */
Matthias Braun's avatar
Matthias Braun committed
344
void set_arm_req_out_all(ir_node *node, const arch_register_req_t **reqs) {
345
346
347
348
349
350
351
	arm_attr_t *attr = get_arm_attr(node);
	attr->out_req    = reqs;
}

/**
 * Sets the IN register requirements at position pos.
 */
Matthias Braun's avatar
Matthias Braun committed
352
void set_arm_req_in(ir_node *node, const arch_register_req_t *req, int pos) {
353
354
355
356
357
358
359
360
	arm_attr_t *attr  = get_arm_attr(node);
	attr->in_req[pos] = req;
}

/**
 * Returns the register flag of an arm node.
 */
arch_irn_flags_t get_arm_flags(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
361
	const arm_attr_t *attr = get_arm_attr_const(node);
362
363
364
365
366
367
	return attr->flags;
}

/**
 * Sets the register flag of an arm node.
 */
Michael Beck's avatar
Michael Beck committed
368
void set_arm_flags(ir_node *node, arch_irn_flags_t flags) {
369
370
371
372
373
374
375
376
	arm_attr_t *attr = get_arm_attr(node);
	attr->flags      = flags;
}

/**
 * Returns the result register slots of an arm node.
 */
const arch_register_t **get_arm_slots(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
377
	const arm_attr_t *attr = get_arm_attr_const(node);
378
379
380
381
382
383
384
	return attr->slots;
}

/**
 * Returns the name of the OUT register at position pos.
 */
const char *get_arm_out_reg_name(const ir_node *node, int pos) {
Michael Beck's avatar
Michael Beck committed
385
	const arm_attr_t *attr = get_arm_attr_const(node);
386
387

	assert(is_arm_irn(node) && "Not an arm node.");
388
	assert(pos < ARR_LEN(attr->slots) && "Invalid OUT position.");
389
390
391
392
393
394
395
396
397
	assert(attr->slots[pos]  && "No register assigned");

	return arch_register_get_name(attr->slots[pos]);
}

/**
 * Returns the index of the OUT register at position pos within its register class.
 */
int get_arm_out_regnr(const ir_node *node, int pos) {
Michael Beck's avatar
Michael Beck committed
398
	const arm_attr_t *attr = get_arm_attr_const(node);
399
400

	assert(is_arm_irn(node) && "Not an arm node.");
401
	assert(pos < ARR_LEN(attr->slots) && "Invalid OUT position.");
402
403
404
405
406
407
408
409
410
	assert(attr->slots[pos]  && "No register assigned");

	return arch_register_get_index(attr->slots[pos]);
}

/**
 * Returns the OUT register at position pos.
 */
const arch_register_t *get_arm_out_reg(const ir_node *node, int pos) {
Michael Beck's avatar
Michael Beck committed
411
	const arm_attr_t *attr = get_arm_attr_const(node);
412
413

	assert(is_arm_irn(node) && "Not an arm node.");
414
	assert(pos < ARR_LEN(attr->slots) && "Invalid OUT position.");
415
416
417
418
419
	assert(attr->slots[pos]  && "No register assigned");

	return attr->slots[pos];
}

420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
/**
 * Sets the flags for the n'th out.
 */
void set_arm_out_flags(ir_node *node, arch_irn_flags_t flags, int pos) {
	arm_attr_t *attr = get_arm_attr(node);
	assert(pos < ARR_LEN(attr->out_flags) && "Invalid OUT position.");
	attr->out_flags[pos] = flags;
}

/**
 * Gets the flags for the n'th out.
 */
arch_irn_flags_t get_arm_out_flags(const ir_node *node, int pos) {
	const arm_attr_t *attr = get_arm_attr_const(node);
	assert(pos < ARR_LEN(attr->out_flags) && "Invalid OUT position.");
	return attr->out_flags[pos];
}

438
439
440
441
/**
 * Returns the number of results.
 */
int get_arm_n_res(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
442
	const arm_attr_t *attr = get_arm_attr_const(node);
443
	return ARR_LEN(attr->slots);
444
445
446
447
448
}
/**
 * Returns the tarvalue
 */
tarval *get_arm_value(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
449
	const arm_attr_t *attr = get_arm_attr_const(node);
450
451
452
453
454
455
456
457
458
459
460
461
462
463
	return attr->value;
}

/**
 * Sets the tarvalue
 */
void set_arm_value(ir_node *node, tarval *tv) {
	arm_attr_t *attr = get_arm_attr(node);
	attr->value = tv;
}

/**
 * Returns the proj num
 */
Michael Beck's avatar
Michael Beck committed
464
int get_arm_CondJmp_proj_num(const ir_node *node) {
465
	const arm_CondJmp_attr_t *attr = get_arm_CmpBra_attr_const(node);
466
467
468
469
470
471
	return attr->proj_num;
}

/**
 * Sets the proj num
 */
Michael Beck's avatar
Michael Beck committed
472
void set_arm_CondJmp_proj_num(ir_node *node, int proj_num) {
473
	arm_CondJmp_attr_t *attr = get_arm_CmpBra_attr(node);
Michael Beck's avatar
Michael Beck committed
474
	attr->proj_num   = proj_num;
475
476
477
478
479
}

/**
 * Returns the SymConst label
 */
Michael Beck's avatar
Michael Beck committed
480
ident *get_arm_symconst_id(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
481
	const arm_SymConst_attr_t *attr = get_arm_SymConst_attr_const(node);
Michael Beck's avatar
Michael Beck committed
482
	return attr->symconst_id;
483
484
485
486
487
}

/**
 * Sets the SymConst label
 */
Michael Beck's avatar
Michael Beck committed
488
void set_arm_symconst_id(ir_node *node, ident *symconst_id) {
Michael Beck's avatar
Michael Beck committed
489
	arm_SymConst_attr_t *attr = get_arm_SymConst_attr(node);
Michael Beck's avatar
Michael Beck committed
490
	attr->symconst_id = symconst_id;
491
492
493
}

/**
Michael Beck's avatar
Michael Beck committed
494
 * Returns the number of projs of a SwitchJmp.
495
 */
Michael Beck's avatar
Michael Beck committed
496
497
int get_arm_SwitchJmp_n_projs(const ir_node *node) {
	const arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr_const(node);
498
499
500
501
502
503
	return attr->n_projs;
}

/**
 * Sets the number of projs.
 */
Michael Beck's avatar
Michael Beck committed
504
505
void set_arm_SwitchJmp_n_projs(ir_node *node, int n_projs) {
	arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr(node);
506
507
508
509
510
511
	attr->n_projs = n_projs;
}

/**
 * Returns the default_proj_num.
 */
Michael Beck's avatar
Michael Beck committed
512
513
long get_arm_SwitchJmp_default_proj_num(const ir_node *node) {
	const arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr_const(node);
514
515
516
517
518
519
	return attr->default_proj_num;
}

/**
 * Sets the default_proj_num.
 */
Michael Beck's avatar
Michael Beck committed
520
521
void set_arm_SwitchJmp_default_proj_num(ir_node *node, long default_proj_num) {
	arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr(node);
522
523
524
	attr->default_proj_num = default_proj_num;
}

Michael Beck's avatar
Michael Beck committed
525
526
527
/**
 * Gets the shift modifier attribute.
 */
Michael Beck's avatar
Michael Beck committed
528
arm_shift_modifier get_arm_shift_modifier(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
529
	const arm_attr_t *attr = get_arm_attr_const(node);
Michael Beck's avatar
Michael Beck committed
530
531
	return ARM_GET_SHF_MOD(attr);
}
532

Michael Beck's avatar
Michael Beck committed
533
/* Set the ARM machine node attributes to default values. */
Christoph Mallon's avatar
static    
Christoph Mallon committed
534
static void init_arm_attributes(ir_node *node, int flags,
535
536
537
                         const arch_register_req_t ** in_reqs,
						 const arch_register_req_t ** out_reqs,
                         const be_execution_unit_t ***execution_units,
538
						 int n_res, unsigned latency) {
539
540
541
	ir_graph       *irg  = get_irn_irg(node);
	struct obstack *obst = get_irg_obstack(irg);
	arm_attr_t     *attr = get_arm_attr(node);
542
543
	(void) execution_units;
	(void) latency;
544

Michael Beck's avatar
Michael Beck committed
545
546
547
548
549
	attr->in_req           = in_reqs;
	attr->out_req          = out_reqs;
	attr->flags            = flags;
	attr->instr_fl         = (ARM_COND_AL << 3) | ARM_SHF_NONE;
	attr->value            = NULL;
550

551
552
553
	attr->out_flags = NEW_ARR_D(int, obst, n_res);
	memset(attr->out_flags, 0, n_res * sizeof(attr->out_flags[0]));

554
	attr->slots = NEW_ARR_D(const arch_register_t*, obst, n_res);
555
	memset(attr->slots, 0, n_res * sizeof(attr->slots[0]));
556
557
}

Michael Beck's avatar
Michael Beck committed
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
/************************************************
 *   ___        _   _           _               *
 *  / _ \ _ __ | |_(_)_ __ ___ (_)_______ _ __  *
 * | | | | '_ \| __| | '_ ` _ \| |_  / _ \ '__| *
 * | |_| | |_) | |_| | | | | | | |/ /  __/ |    *
 *  \___/| .__/ \__|_|_| |_| |_|_/___\___|_|    *
 *       |_|                                    *
 ************************************************/

typedef struct _opt_tuple {
	ir_op *op_imm_left;		/**< immediate is left */
	ir_op *op_imm_right;	/**< immediate is right */
	ir_op *op_shf_left;		/**< shift operand on left */
	ir_op *op_shf_right;	/**< shift operand on right */
} opt_tuple;

Matthias Braun's avatar
Matthias Braun committed
574
//static const opt_tuple *opt_ops[iro_arm_last];
Michael Beck's avatar
Michael Beck committed
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603

void arm_set_optimizers(void) {
	/*
#define STD(op)		p_##op = { op_arm_##op##_i, op_arm_##op##_i, op_arm_##op, op_arm_##op }
#define LEFT(op)	p_##op = { op_arm_##op##_i, NULL, op_arm_##op, NULL }
#define SET(op)   opt_ops[iro_arm_##op] = &p_##op;

	static const opt_tuple
		STD(Add),
		STD(And),
		STD(Or),
		STD(Eor),
		LEFT(Bic),
		LEFT(Shl),
		LEFT(Shr),
		LEFT(Shrs),
		p_Sub = { op_arm_Sub_i, op_arm_Rsb_i, op_arm_Sub, op_arm_Rsb },

	memset(opt_ops, 0, sizeof(opt_ops));
	SET(Add);
	SET(And);
	SET(Or);
	SET(Eor);
	SET(Sub);
	SET(Bic);
	SET(Shl);
	SET(Shr);
	SET(Shrs);
	*/
604
605
}

Michael Beck's avatar
Michael Beck committed
606
607
608
609
610
611
612
613
614
615
616
617
618
static int cmp_attr_arm_SymConst(ir_node *a, ir_node *b) {
	const arm_SymConst_attr_t *attr_a = get_irn_generic_attr_const(a);
	const arm_SymConst_attr_t *attr_b = get_irn_generic_attr_const(b);
	return attr_a->symconst_id != attr_b->symconst_id;
}

static int cmp_attr_arm(ir_node *a, ir_node *b) {
	arm_attr_t *attr_a = get_irn_generic_attr(a);
	arm_attr_t *attr_b = get_irn_generic_attr(b);
	return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->value != attr_b->value);
}

static int cmp_attr_arm_CondJmp(ir_node *a, ir_node *b) {
619
620
	(void) a;
	(void) b;
Michael Beck's avatar
Michael Beck committed
621
622
623
624
625
	/* never identical */
	return 1;
}

static int cmp_attr_arm_SwitchJmp(ir_node *a, ir_node *b) {
626
627
	(void) a;
	(void) b;
Michael Beck's avatar
Michael Beck committed
628
629
630
631
	/* never identical */
	return 1;
}

632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
/** copies the ARM attributes of a node. */
static void arm_copy_attr(const ir_node *old_node, ir_node *new_node) {
	ir_graph          *irg     = get_irn_irg(new_node);
	struct obstack    *obst    = get_irg_obstack(irg);
	const arm_attr_t *attr_old = get_arm_attr_const(old_node);
	arm_attr_t       *attr_new = get_arm_attr(new_node);

	/* copy the attributes */
	memcpy(attr_new, attr_old, get_op_attr_size(get_irn_op(old_node)));

	/* copy out flags */
	attr_new->out_flags =
		DUP_ARR_D(int, obst, attr_old->out_flags);
	/* copy register assignments */
	attr_new->slots =
		DUP_ARR_D(arch_register_t*, obst, attr_old->slots);
}

Michael Beck's avatar
Michael Beck committed
650
651


652
653
/* Include the generated constructor functions */
#include "gen_arm_new_nodes.c.inl"