arm_new_nodes.c 17.4 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * 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
#include "config.h"
29
30
31
32
33
34
35
36
37
38
39
40

#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 "irvrfy_t.h"
#include "irprintf.h"
41
#include "xmalloc.h"
42

43
#include "../bearch.h"
44
45
46

#include "arm_nodes_attr.h"
#include "arm_new_nodes.h"
47
#include "arm_optimize.h"
48
49
50
51

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

Michael Beck's avatar
Michael Beck committed
52
53
54
55
/**
 * Returns the shift modifier string.
 */
const char *arm_shf_mod_name(arm_shift_modifier mod) {
Michael Beck's avatar
Michael Beck committed
56
	static const char *names[] = { NULL, NULL, "asr", "lsl", "lsr", "ror", "rrx" };
Michael Beck's avatar
Michael Beck committed
57
58
	return names[mod];
}
59

Michael Beck's avatar
Michael Beck committed
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/**
 * Return the fpa immediate from the encoding.
 */
const char *arm_get_fpa_imm_name(long imm_value) {
	static const char *fpa_imm[] = {
		"0",
		"1",
		"2",
		"3",
		"4",
		"5",
		"10",
		"0.5"
	};
	return fpa_imm[imm_value];
}

77
78
79
80
81
82
83
84
85
86
87
88
89
90
/***********************************************************************************
 *      _                                   _       _             __
 *     | |                                 (_)     | |           / _|
 *   __| |_   _ _ __ ___  _ __   ___ _ __   _ _ __ | |_ ___ _ __| |_ __ _  ___ ___
 *  / _` | | | | '_ ` _ \| '_ \ / _ \ '__| | | '_ \| __/ _ \ '__|  _/ _` |/ __/ _ \
 * | (_| | |_| | | | | | | |_) |  __/ |    | | | | | ||  __/ |  | || (_| | (_|  __/
 *  \__,_|\__,_|_| |_| |_| .__/ \___|_|    |_|_| |_|\__\___|_|  |_| \__,_|\___\___|
 *                       | |
 *                       |_|
 ***********************************************************************************/

/**
 * Dumps the register requirements for either in or out.
 */
Matthias Braun's avatar
Matthias Braun committed
91
92
static void dump_reg_req(FILE *F, const ir_node *node,
                         const arch_register_req_t **reqs, int inout) {
93
	char *dir = inout ? "out" : "in";
94
	int   max = inout ? (int) arch_irn_get_n_outs(node) : get_irn_arity(node);
Matthias Braun's avatar
Matthias Braun committed
95
	char  buf[1024];
96
97
	int   i;

Matthias Braun's avatar
Matthias Braun committed
98
	memset(buf, 0, sizeof(buf));
99
100
101
102
103

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

Matthias Braun's avatar
Matthias Braun committed
104
			if (reqs[i]->type == arch_register_req_type_none) {
105
106
107
				fprintf(F, " n/a");
			}

Matthias Braun's avatar
Matthias Braun committed
108
109
			if (reqs[i]->type & arch_register_req_type_normal) {
				fprintf(F, " %s", reqs[i]->cls->name);
110
111
			}

Matthias Braun's avatar
Matthias Braun committed
112
113
114
			if (reqs[i]->type & arch_register_req_type_limited) {
				fprintf(F, " %s",
				        arch_register_req_format(buf, sizeof(buf), reqs[i], node));
115
116
			}

Matthias Braun's avatar
Matthias Braun committed
117
			if (reqs[i]->type & arch_register_req_type_should_be_same) {
118
119
120
121
122
123
124
125
126
				const unsigned other = reqs[i]->other_same;
				int i;

				ir_fprintf(F, " same as");
				for (i = 0; 1U << i <= other; ++i) {
					if (other & (1U << i)) {
						ir_fprintf(F, " %+F", get_irn_n(node, i));
					}
				}
127
128
			}

129
			if (reqs[i]->type & arch_register_req_type_must_be_different) {
130
131
132
133
134
135
136
137
138
				const unsigned other = reqs[i]->other_different;
				int i;

				ir_fprintf(F, " different from");
				for (i = 0; 1U << i <= other; ++i) {
					if (other & (1U << i)) {
						ir_fprintf(F, " %+F", get_irn_n(node, i));
					}
				}
139
140
141
142
143
144
			}

			fprintf(F, "\n");
		}

		fprintf(F, "\n");
Matthias Braun's avatar
Matthias Braun committed
145
	} else {
146
147
148
149
150
151
152
153
154
155
156
		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
 */
157
static int arm_dump_node(ir_node *n, FILE *F, dump_reason_t reason) {
Michael Beck's avatar
Michael Beck committed
158
	ir_mode     *mode = NULL;
159
160
	int         bad  = 0;
	int         i, n_res, flags;
Michael Beck's avatar
Michael Beck committed
161
	arm_attr_t  *attr = get_arm_attr(n);
Matthias Braun's avatar
Matthias Braun committed
162
	const arch_register_req_t **reqs;
Michael Beck's avatar
Michael Beck committed
163
	arm_shift_modifier        mod;
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181

	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
182
183
			mod = ARM_GET_SHF_MOD(attr);
			if (ARM_HAS_SHIFT(mod)) {
Michael Beck's avatar
Michael Beck committed
184
				fprintf(F, "[%s #%ld]", arm_shf_mod_name(mod), attr->imm_value);
Michael Beck's avatar
Michael Beck committed
185
186
187
			}
			else if (mod == ARM_SHF_IMM) {
				/* immediate */
Michael Beck's avatar
Michael Beck committed
188
				fprintf(F, "[#0x%X]", arm_decode_imm_w_shift(attr->imm_value));
Michael Beck's avatar
Michael Beck committed
189
			}
190
191
192
193
194
195
196
197
198
199
200
			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);
			}

201
202
203
			n_res = arch_irn_get_n_outs(n);
			if (n_res > 0) {
				/* dump OUT requirements */
204
205
206
				reqs = get_arm_out_req_all(n);
				dump_reg_req(F, n, reqs, 1);

207
208
209
210
211
				/* dump assigned registers */
				for (i = 0; i < n_res; i++) {
					const arch_register_t *reg = arch_irn_get_register(n, i);

					fprintf(F, "reg #%d = %s\n", i, reg ? arch_register_get_name(reg) : "n/a");
212
				}
213
				fprintf(F, "\n");
214
215
216
217
			}
			fprintf(F, "\n");

			/* dump n_res */
218
			fprintf(F, "n_res = %d\n", n_res);
219
220
221

			/* dump flags */
			fprintf(F, "flags =");
222
223
			flags = arch_irn_get_flags(n);
			if (flags == arch_irn_flags_none) {
224
225
226
				fprintf(F, " none");
			}
			else {
227
				if (flags & arch_irn_flags_dont_spill) {
228
229
					fprintf(F, " unspillable");
				}
230
				if (flags & arch_irn_flags_rematerializable) {
231
232
					fprintf(F, " remat");
				}
233
234
235
				if (flags & arch_irn_flags_modify_flags) {
					fprintf(F, " modify_flags");
				}
236
			}
237
			fprintf(F, " (%d)\n", flags);
238

Michael Beck's avatar
Michael Beck committed
239
240
241
242
243
244
			if (is_arm_CopyB(n)) {
				fprintf(F, "size = %lu\n", get_arm_imm_value(n));
			} else {
				long v =  get_arm_imm_value(n);
				if (ARM_GET_FPA_IMM(attr)) {
					fprintf(F, "immediate float value = %s\n", arm_get_fpa_imm_name(v));
245
				} else {
Michael Beck's avatar
Michael Beck committed
246
					fprintf(F, "immediate value = %ld (0x%08lx)\n", v, v);
247
248
				}
			}
Michael Beck's avatar
Michael Beck committed
249

250
			if (is_arm_CmpBra(n) && get_arm_CondJmp_proj_num(n) >= 0) {
Michael Beck's avatar
Michael Beck committed
251
				fprintf(F, "proj_num = (%d)\n", get_arm_CondJmp_proj_num(n));
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
			}
			/* 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
275
276
277
278
279
280
281
282
283
284
285
/* 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);
}

286
/**
Michael Beck's avatar
Michael Beck committed
287
 * Returns the attributes of an ARM SymConst node.
288
 */
Michael Beck's avatar
Michael Beck committed
289
290
291
292
293
294
295
296
297
298
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);
}

Michael Beck's avatar
Michael Beck committed
299
300
301
302
303
304
305
306
307
308
309
310
311
312
static const arm_fpaConst_attr_t *get_arm_fpaConst_attr_const(const ir_node *node) {
	const arm_attr_t          *attr     = get_arm_attr_const(node);
	const arm_fpaConst_attr_t *fpa_attr = CONST_CAST_ARM_ATTR(arm_fpaConst_attr_t, attr);

	return fpa_attr;
}

static arm_fpaConst_attr_t *get_arm_fpaConst_attr(ir_node *node) {
	arm_attr_t          *attr     = get_arm_attr(node);
	arm_fpaConst_attr_t *fpa_attr = CAST_ARM_ATTR(arm_fpaConst_attr_t, attr);

	return fpa_attr;
}

313
#ifndef NDEBUG
Michael Beck's avatar
Michael Beck committed
314
315
316
317
318
319
320
static int is_arm_CondJmp(const ir_node *node) {
	int code = get_arm_irn_opcode(node);

	return (code == iro_arm_CmpBra || code == iro_arm_fpaCmfBra ||
	        code == iro_arm_fpaCnfBra || iro_arm_fpaCmfeBra ||
	        code == iro_arm_fpaCnfeBra);
}
321
#endif
Michael Beck's avatar
Michael Beck committed
322

Michael Beck's avatar
Michael Beck committed
323
/* Returns the attributes of a CondJmp node. */
Michael Beck's avatar
Michael Beck committed
324
325
arm_CondJmp_attr_t *get_arm_CondJmp_attr(ir_node *node) {
	assert(is_arm_CondJmp(node));
Michael Beck's avatar
Michael Beck committed
326
327
328
	return get_irn_generic_attr(node);
}

Michael Beck's avatar
Michael Beck committed
329
330
const arm_CondJmp_attr_t *get_arm_CondJmp_attr_const(const ir_node *node) {
	assert(is_arm_CondJmp(node));
Michael Beck's avatar
Michael Beck committed
331
332
333
334
335
336
337
338
339
340
341
342
	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);
343
344
345
346
347
}

/**
 * Returns the argument register requirements of a arm node.
 */
Matthias Braun's avatar
Matthias Braun committed
348
const arch_register_req_t **get_arm_in_req_all(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
349
	const arm_attr_t *attr = get_arm_attr_const(node);
350
351
352
353
354
355
	return attr->in_req;
}

/**
 * Returns the result register requirements of an arm node.
 */
Matthias Braun's avatar
Matthias Braun committed
356
const arch_register_req_t **get_arm_out_req_all(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
357
	const arm_attr_t *attr = get_arm_attr_const(node);
358
359
360
361
362
363
	return attr->out_req;
}

/**
 * Returns the argument register requirement at position pos of an arm node.
 */
Matthias Braun's avatar
Matthias Braun committed
364
const arch_register_req_t *get_arm_in_req(const ir_node *node, int pos) {
Michael Beck's avatar
Michael Beck committed
365
	const arm_attr_t *attr = get_arm_attr_const(node);
366
367
368
369
370
371
	return attr->in_req[pos];
}

/**
 * Returns the result register requirement at position pos of an arm node.
 */
Matthias Braun's avatar
Matthias Braun committed
372
const arch_register_req_t *get_arm_out_req(const ir_node *node, int pos) {
Michael Beck's avatar
Michael Beck committed
373
	const arm_attr_t *attr = get_arm_attr_const(node);
374
375
376
377
378
379
	return attr->out_req[pos];
}

/**
 * Sets the OUT register requirements at position pos.
 */
Matthias Braun's avatar
Matthias Braun committed
380
void set_arm_req_out(ir_node *node, const arch_register_req_t *req, int pos) {
381
382
383
384
385
386
387
	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
388
void set_arm_req_out_all(ir_node *node, const arch_register_req_t **reqs) {
389
390
391
392
393
394
395
	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
396
void set_arm_req_in(ir_node *node, const arch_register_req_t *req, int pos) {
397
398
399
400
401
	arm_attr_t *attr  = get_arm_attr(node);
	attr->in_req[pos] = req;
}

/**
Michael Beck's avatar
Michael Beck committed
402
 * Returns the immediate value
403
 */
Michael Beck's avatar
Michael Beck committed
404
long get_arm_imm_value(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
405
	const arm_attr_t *attr = get_arm_attr_const(node);
Michael Beck's avatar
Michael Beck committed
406
	return attr->imm_value;
407
408
409
}

/**
Michael Beck's avatar
Michael Beck committed
410
 * Sets the tarval value
411
 */
Michael Beck's avatar
Michael Beck committed
412
void set_arm_imm_value(ir_node *node, long imm_value) {
413
	arm_attr_t *attr = get_arm_attr(node);
Michael Beck's avatar
Michael Beck committed
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
	attr->imm_value = imm_value;
}

/**
 * Returns the fpaConst value
 */
tarval *get_fpaConst_value(const ir_node *node) {
	const arm_fpaConst_attr_t *attr = get_arm_fpaConst_attr_const(node);
	return attr->tv;
}

/**
 * Sets the tarval value
 */
void set_fpaConst_value(ir_node *node, tarval *tv) {
	arm_fpaConst_attr_t *attr = get_arm_fpaConst_attr(node);
	attr->tv = tv;
431
432
433
434
435
}

/**
 * Returns the proj num
 */
Michael Beck's avatar
Michael Beck committed
436
int get_arm_CondJmp_proj_num(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
437
	const arm_CondJmp_attr_t *attr = get_arm_CondJmp_attr_const(node);
438
439
440
441
442
443
	return attr->proj_num;
}

/**
 * Sets the proj num
 */
Michael Beck's avatar
Michael Beck committed
444
void set_arm_CondJmp_proj_num(ir_node *node, int proj_num) {
Michael Beck's avatar
Michael Beck committed
445
	arm_CondJmp_attr_t *attr = get_arm_CondJmp_attr(node);
Michael Beck's avatar
Michael Beck committed
446
	attr->proj_num   = proj_num;
447
448
449
450
451
}

/**
 * Returns the SymConst label
 */
Michael Beck's avatar
Michael Beck committed
452
ident *get_arm_symconst_id(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
453
	const arm_SymConst_attr_t *attr = get_arm_SymConst_attr_const(node);
Michael Beck's avatar
Michael Beck committed
454
	return attr->symconst_id;
455
456
457
458
459
}

/**
 * Sets the SymConst label
 */
Michael Beck's avatar
Michael Beck committed
460
void set_arm_symconst_id(ir_node *node, ident *symconst_id) {
Michael Beck's avatar
Michael Beck committed
461
	arm_SymConst_attr_t *attr = get_arm_SymConst_attr(node);
Michael Beck's avatar
Michael Beck committed
462
	attr->symconst_id = symconst_id;
463
464
465
}

/**
Michael Beck's avatar
Michael Beck committed
466
 * Returns the number of projs of a SwitchJmp.
467
 */
Michael Beck's avatar
Michael Beck committed
468
469
int get_arm_SwitchJmp_n_projs(const ir_node *node) {
	const arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr_const(node);
470
471
472
473
474
475
	return attr->n_projs;
}

/**
 * Sets the number of projs.
 */
Michael Beck's avatar
Michael Beck committed
476
477
void set_arm_SwitchJmp_n_projs(ir_node *node, int n_projs) {
	arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr(node);
478
479
480
481
482
483
	attr->n_projs = n_projs;
}

/**
 * Returns the default_proj_num.
 */
Michael Beck's avatar
Michael Beck committed
484
485
long get_arm_SwitchJmp_default_proj_num(const ir_node *node) {
	const arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr_const(node);
486
487
488
489
490
491
	return attr->default_proj_num;
}

/**
 * Sets the default_proj_num.
 */
Michael Beck's avatar
Michael Beck committed
492
493
void set_arm_SwitchJmp_default_proj_num(ir_node *node, long default_proj_num) {
	arm_SwitchJmp_attr_t *attr = get_arm_SwitchJmp_attr(node);
494
495
496
	attr->default_proj_num = default_proj_num;
}

Michael Beck's avatar
Michael Beck committed
497
498
499
/**
 * Gets the shift modifier attribute.
 */
Michael Beck's avatar
Michael Beck committed
500
arm_shift_modifier get_arm_shift_modifier(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
501
	const arm_attr_t *attr = get_arm_attr_const(node);
Michael Beck's avatar
Michael Beck committed
502
503
	return ARM_GET_SHF_MOD(attr);
}
504

Michael Beck's avatar
Michael Beck committed
505
/* Set the ARM machine node attributes to default values. */
Christoph Mallon's avatar
static    
Christoph Mallon committed
506
static void init_arm_attributes(ir_node *node, int flags,
507
508
509
                         const arch_register_req_t ** in_reqs,
						 const arch_register_req_t ** out_reqs,
                         const be_execution_unit_t ***execution_units,
510
						 int n_res) {
511
512
513
	ir_graph       *irg  = get_irn_irg(node);
	struct obstack *obst = get_irg_obstack(irg);
	arm_attr_t     *attr = get_arm_attr(node);
514
	backend_info_t *info;
515
	(void) execution_units;
516

517
	arch_irn_set_flags(node, flags);
Michael Beck's avatar
Michael Beck committed
518
519
520
	attr->in_req           = in_reqs;
	attr->out_req          = out_reqs;
	attr->instr_fl         = (ARM_COND_AL << 3) | ARM_SHF_NONE;
Michael Beck's avatar
Michael Beck committed
521
	attr->imm_value        = 0;
522

523
524
525
	info            = be_get_info(node);
	info->out_infos = NEW_ARR_D(reg_out_info_t, obst, n_res);
	memset(info->out_infos, 0, n_res * sizeof(info->out_infos[0]));
526
527
}

Michael Beck's avatar
Michael Beck committed
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
/************************************************
 *   ___        _   _           _               *
 *  / _ \ _ __ | |_(_)_ __ ___ (_)_______ _ __  *
 * | | | | '_ \| __| | '_ ` _ \| |_  / _ \ '__| *
 * | |_| | |_) | |_| | | | | | | |/ /  __/ |    *
 *  \___/| .__/ \__|_|_| |_| |_|_/___\___|_|    *
 *       |_|                                    *
 ************************************************/

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
544
//static const opt_tuple *opt_ops[iro_arm_last];
Michael Beck's avatar
Michael Beck committed
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573

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);
	*/
574
575
}

Michael Beck's avatar
Michael Beck committed
576
577
578
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);
Michael Beck's avatar
Michael Beck committed
579
580
581
582
583
584
585
586
587
588
589
590
591
	return (attr_a->instr_fl != attr_b->instr_fl) || (attr_a->imm_value != attr_b->imm_value);
}

static int cmp_attr_arm_SymConst(ir_node *a, ir_node *b) {
	const arm_SymConst_attr_t *attr_a;
	const arm_SymConst_attr_t *attr_b;

	if (cmp_attr_arm(a, b))
		return 1;

	attr_a = get_irn_generic_attr_const(a);
	attr_b = get_irn_generic_attr_const(b);
	return attr_a->symconst_id != attr_b->symconst_id;
Michael Beck's avatar
Michael Beck committed
592
593
594
}

static int cmp_attr_arm_CondJmp(ir_node *a, ir_node *b) {
595
596
	(void) a;
	(void) b;
Michael Beck's avatar
Michael Beck committed
597
598
599
600
601
	/* never identical */
	return 1;
}

static int cmp_attr_arm_SwitchJmp(ir_node *a, ir_node *b) {
602
603
	(void) a;
	(void) b;
Michael Beck's avatar
Michael Beck committed
604
605
606
607
	/* never identical */
	return 1;
}

Michael Beck's avatar
Michael Beck committed
608
609
610
611
612
613
614
615
616
617
618
619
620
static int cmp_attr_arm_fpaConst(ir_node *a, ir_node *b) {
	const arm_fpaConst_attr_t *attr_a;
	const arm_fpaConst_attr_t *attr_b;

	if (cmp_attr_arm(a, b))
		return 1;

	attr_a = get_arm_fpaConst_attr_const(a);
	attr_b = get_arm_fpaConst_attr_const(b);

	return attr_a->tv != attr_b->tv;
}

621
622
623
624
625
626
/** 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);
627
628
	backend_info_t    *old_info = be_get_info(old_node);
	backend_info_t    *new_info = be_get_info(new_node);
629
630
631
632
633

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

	/* copy out flags */
634
635
	new_info->out_infos =
		DUP_ARR_D(reg_out_info_t, obst, old_info->out_infos);
636
637
}

Michael Beck's avatar
Michael Beck committed
638
639


640
641
/* Include the generated constructor functions */
#include "gen_arm_new_nodes.c.inl"