ia32_intrinsics.c 15.7 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
10
 * @file
 * @brief       This file implements the mapping of 64Bit intrinsic
 *              functions to code or library calls.
 * @author      Michael Beck
11
 */
12
#include "iredges.h"
13
#include "irgmod.h"
14
15
#include "irop.h"
#include "irnode_t.h"
16
#include "ircons_t.h"
17
#include "irprog_t.h"
18
#include "iroptimize.h"
19
#include "lower_dw.h"
20
#include "array.h"
Matthias Braun's avatar
Matthias Braun committed
21
#include "panic.h"
22
#include "util.h"
23
24
#include "constbits.h"
#include "tv.h"
25

26
#include "ia32_new_nodes.h"
27
28
#include "bearch_ia32_t.h"
#include "gen_ia32_regalloc_if.h"
Matthias Braun's avatar
Matthias Braun committed
29
#include "begnuas.h"
30

31
32
33
34
35
36
typedef enum {
	no_carry = 0,
	can_carry,
	must_carry
} carry_result;

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
static ir_tarval *bitinfo_max(bitinfo *info)
{
	ir_tarval *z    = info->z;
	ir_tarval *o    = info->o;
	ir_mode   *mode = get_tarval_mode(z);
	ir_tarval *min  = get_mode_min(mode);

	assert(get_mode_arithmetic(mode) == irma_twos_complement);
	return tarval_and(z, tarval_ornot(o, min));
}

static ir_tarval *bitinfo_min(bitinfo *info)
{
	ir_tarval *z    = info->z;
	ir_tarval *o    = info->o;
	ir_mode   *mode = get_tarval_mode(z);
	ir_tarval *min  = get_mode_min(mode);

	assert(get_mode_arithmetic(mode) == irma_twos_complement);
	return tarval_or(o, tarval_and(z, min));
}

59
static carry_result lower_add_carry(ir_node *left, ir_node *right, ir_mode *mode)
60
{
61
62
	assert(!mode_is_signed(mode));

63
64
65
66
67
68
69
70
71
	bitinfo *bi_left = get_bitinfo(left);
	if (!bi_left) {
		return true;
	}
	bitinfo *bi_right = get_bitinfo(right);
	// If we have bitinfo for one node, we should also have it for
	// the other
	assert(bi_right);

72
73
74
75
76
	ir_tarval    *lmin   = tarval_convert_to(bitinfo_min(bi_left),  mode);
	ir_tarval    *rmin   = tarval_convert_to(bitinfo_min(bi_right), mode);
	ir_tarval    *lmax   = tarval_convert_to(bitinfo_max(bi_left),  mode);
	ir_tarval    *rmax   = tarval_convert_to(bitinfo_max(bi_right), mode);
	carry_result  result = no_carry;
77

Matthias Braun's avatar
Matthias Braun committed
78
79
	int old_wrap_on_overflow = tarval_get_wrap_on_overflow();
	tarval_set_wrap_on_overflow(false);
80

81
82
83
84
85
	if (tarval_add(lmax, rmax) == tarval_bad) {
		result = can_carry;
		if (tarval_add(lmin, rmin) == tarval_bad) {
			result = must_carry;
		}
86
87
	}

Matthias Braun's avatar
Matthias Braun committed
88
	tarval_set_wrap_on_overflow(old_wrap_on_overflow);
89
90
91
92

	return result;
}

93
static carry_result lower_sub_borrow(ir_node *left, ir_node *right, ir_mode *mode)
94
{
95
96
	assert(!mode_is_signed(mode));

97
98
99
100
101
102
103
104
105
	bitinfo *bi_left = get_bitinfo(left);
	if (!bi_left) {
		return true;
	}
	bitinfo *bi_right = get_bitinfo(right);
	// If we have bitinfo for one node, we should also have it for
	// the other
	assert(bi_right);

106
107
108
109
110
	ir_tarval    *lmin   = tarval_convert_to(bitinfo_min(bi_left),  mode);
	ir_tarval    *rmin   = tarval_convert_to(bitinfo_min(bi_right), mode);
	ir_tarval    *lmax   = tarval_convert_to(bitinfo_max(bi_left),  mode);
	ir_tarval    *rmax   = tarval_convert_to(bitinfo_max(bi_right), mode);
	carry_result  result = no_carry;
111

Matthias Braun's avatar
Matthias Braun committed
112
113
	int old_wrap_on_overflow = tarval_get_wrap_on_overflow();
	tarval_set_wrap_on_overflow(false);
114

115
116
117
118
119
	if (tarval_sub(lmin, rmax, NULL) == tarval_bad) {
		result = can_carry;
		if (tarval_sub(lmax, rmin, NULL) == tarval_bad) {
			result = must_carry;
		}
120
121
	}

Matthias Braun's avatar
Matthias Braun committed
122
	tarval_set_wrap_on_overflow(old_wrap_on_overflow);
123
124
125
126

	return result;
}

127
/**
Matthias Braun's avatar
Matthias Braun committed
128
 * lower 64bit addition: an 32bit add for the lower parts, an add with
129
130
 * carry for the higher parts. If the carry's value is known, fold it
 * into the upper add.
131
 */
Matthias Braun's avatar
Matthias Braun committed
132
static void ia32_lower_add64(ir_node *node, ir_mode *mode)
133
{
134
135
136
137
138
139
140
141
142
143
144
	dbg_info     *dbg        = get_irn_dbg_info(node);
	ir_node      *block      = get_nodes_block(node);
	ir_node      *left       = get_Add_left(node);
	ir_node      *right      = get_Add_right(node);
	ir_node      *left_low   = get_lowered_low(left);
	ir_node      *left_high  = get_lowered_high(left);
	ir_node      *right_low  = get_lowered_low(right);
	ir_node      *right_high = get_lowered_high(right);
	ir_mode      *low_mode   = get_irn_mode(left_low);
	ir_mode      *high_mode  = get_irn_mode(left_high);
	carry_result  cr         = lower_add_carry(left, right, low_mode);
145
146
147

	assert(get_irn_mode(left_low)  == get_irn_mode(right_low));
	assert(get_irn_mode(left_high) == get_irn_mode(right_high));
148

149
	if (cr == no_carry) {
150
		ir_node *add_low  = new_rd_Add(dbg, block, left_low,  right_low, low_mode);
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
		ir_node *add_high = new_rd_Add(dbg, block, left_high, right_high, high_mode);
		ir_set_dw_lowered(node, add_low, add_high);
	} else if (cr == must_carry && (is_Const(left_high) || is_Const(right_high))) {
		// We cannot assume that left_high and right_high form a normalized Add.
		ir_node *constant;
		ir_node *other;

		if (is_Const(left_high)) {
			constant = left_high;
			other    = right_high;
		} else {
			constant = right_high;
			other    = left_high;
		}

		ir_graph *irg            = get_irn_irg(right_high);
		ir_node  *one            = new_rd_Const(dbg, irg, get_mode_one(high_mode));
		ir_node  *const_plus_one = new_rd_Add(dbg, block, constant, one, high_mode);
		ir_node  *add_high       = new_rd_Add(dbg, block, other, const_plus_one, high_mode);
		ir_node  *add_low        = new_rd_Add(dbg, block, left_low, right_low, low_mode);
171
172
173
174
175
176
177
178
179
180
181
182
183
		ir_set_dw_lowered(node, add_low, add_high);
	} else {
		/* l_res = a_l + b_l */
		ir_node  *add_low    = new_bd_ia32_l_Add(dbg, block, left_low, right_low);
		ir_mode  *mode_flags = ia32_reg_classes[CLASS_ia32_flags].mode;
		ir_node  *res_low    = new_r_Proj(add_low, ia32_mode_gp, pn_ia32_l_Add_res);
		ir_node  *flags      = new_r_Proj(add_low, mode_flags, pn_ia32_l_Add_flags);

		/* h_res = a_h + b_h + carry */
		ir_node  *add_high
			= new_bd_ia32_l_Adc(dbg, block, left_high, right_high, flags, mode);
		ir_set_dw_lowered(node, res_low, add_high);
	}
184
185
186
}

/**
187
188
189
 * lower 64bit subtraction: a 32bit sub for the lower parts, a sub
 * with borrow for the higher parts. If the borrow's value is known,
 * fold it into the upper sub.
190
 */
Matthias Braun's avatar
Matthias Braun committed
191
static void ia32_lower_sub64(ir_node *node, ir_mode *mode)
192
{
193
194
195
196
197
198
199
200
201
202
203
	dbg_info     *dbg        = get_irn_dbg_info(node);
	ir_node      *block      = get_nodes_block(node);
	ir_node      *left       = get_Sub_left(node);
	ir_node      *right      = get_Sub_right(node);
	ir_node      *left_low   = get_lowered_low(left);
	ir_node      *left_high  = get_lowered_high(left);
	ir_node      *right_low  = get_lowered_low(right);
	ir_node      *right_high = get_lowered_high(right);
	ir_mode      *low_mode   = get_irn_mode(left_low);
	ir_mode      *high_mode  = get_irn_mode(left_high);
	carry_result  cr         = lower_sub_borrow(left, right, low_mode);
204
205
206
207

	assert(get_irn_mode(left_low)  == get_irn_mode(right_low));
	assert(get_irn_mode(left_high) == get_irn_mode(right_high));

208
	if (cr == no_carry) {
209
		ir_node *sub_low  = new_rd_Sub(dbg, block, left_low,  right_low, low_mode);
210
211
212
213
214
215
216
217
218
219
220
221
222
223
		ir_node *sub_high = new_rd_Sub(dbg, block, left_high, right_high, high_mode);
		ir_set_dw_lowered(node, sub_low, sub_high);
	} else if (cr == must_carry && (is_Const(left_high) || is_Const(right_high))) {
		ir_node  *sub_high;
		ir_graph *irg        = get_irn_irg(right_high);
		ir_node  *one        = new_rd_Const(dbg, irg, get_mode_one(high_mode));

		if (is_Const(right_high)) {
			ir_node *new_const = new_rd_Add(dbg, block, right_high, one, high_mode);
			sub_high = new_rd_Sub(dbg, block, left_high, new_const, high_mode);
		} else if (is_Const(left_high)) {
			ir_node *new_const = new_rd_Sub(dbg, block, left_high, one, high_mode);
			sub_high = new_rd_Sub(dbg, block, new_const, right_high, high_mode);
		} else {
224
			panic("logic error");
225
226
227
		}

		ir_node  *sub_low  = new_rd_Sub(dbg, block, left_low, right_low, low_mode);
228
229
230
231
232
233
234
		ir_set_dw_lowered(node, sub_low, sub_high);
	} else {
		/* l_res = a_l - b_l */
		ir_node  *sub_low    = new_bd_ia32_l_Sub(dbg, block, left_low, right_low);
		ir_mode  *mode_flags = ia32_reg_classes[CLASS_ia32_flags].mode;
		ir_node  *res_low    = new_r_Proj(sub_low, ia32_mode_gp, pn_ia32_l_Sub_res);
		ir_node  *flags      = new_r_Proj(sub_low, mode_flags, pn_ia32_l_Sub_flags);
235

236
237
238
239
240
		/* h_res = a_h - b_h - carry */
		ir_node  *sub_high
			= new_bd_ia32_l_Sbb(dbg, block, left_high, right_high, flags, mode);
		ir_set_dw_lowered(node, res_low, sub_high);
	}
241
242
}

243
/**
Matthias Braun's avatar
Matthias Braun committed
244
 * Checks whether node high is a sign extension of low.
245
 */
Matthias Braun's avatar
Matthias Braun committed
246
static bool is_sign_extend(ir_node *low, ir_node *high)
247
248
{
	if (is_Shrs(high)) {
Matthias Braun's avatar
Matthias Braun committed
249
250
		ir_node *high_r = get_Shrs_right(high);
		if (!is_Const(high_r)) return false;
251

Matthias Braun's avatar
Matthias Braun committed
252
253
254
		ir_tarval *shift_count = get_Const_tarval(high_r);
		if (!tarval_is_long(shift_count))       return false;
		if (get_tarval_long(shift_count) != 31) return false;
255

Matthias Braun's avatar
Matthias Braun committed
256
		ir_node *high_l = get_Shrs_left(high);
257

Matthias Braun's avatar
Matthias Braun committed
258
259
		if (is_Conv(low)    && get_Conv_op(low)    == high_l) return true;
		if (is_Conv(high_l) && get_Conv_op(high_l) == low)    return true;
260
	} else if (is_Const(low) && is_Const(high)) {
Matthias Braun's avatar
Matthias Braun committed
261
262
		ir_tarval *tl = get_Const_tarval(low);
		ir_tarval *th = get_Const_tarval(high);
263
264
265
266
267
268
269
270
271

		if (tarval_is_long(th) && tarval_is_long(tl)) {
			long l = get_tarval_long(tl);
			long h = get_tarval_long(th);

			return (h == 0  && l >= 0) || (h == -1 && l <  0);
		}
	}

Matthias Braun's avatar
Matthias Braun committed
272
	return false;
273
274
}

275
/**
Matthias Braun's avatar
Matthias Braun committed
276
 * lower 64bit Mul operation.
277
 */
Matthias Braun's avatar
Matthias Braun committed
278
static void ia32_lower_mul64(ir_node *node, ir_mode *mode)
279
{
Matthias Braun's avatar
Matthias Braun committed
280
281
282
283
284
285
286
287
	dbg_info *dbg        = get_irn_dbg_info(node);
	ir_node  *block      = get_nodes_block(node);
	ir_node  *left       = get_Mul_left(node);
	ir_node  *right      = get_Mul_right(node);
	ir_node  *left_low   = get_lowered_low(left);
	ir_node  *left_high  = get_lowered_high(left);
	ir_node  *right_low  = get_lowered_low(right);
	ir_node  *right_high = get_lowered_high(right);
288
289

	/*
Matthias Braun's avatar
Matthias Braun committed
290
		EDX:EAX = left_low * right_low
291
292
		l_res   = EAX

Matthias Braun's avatar
Matthias Braun committed
293
		t1 = right_low * left_high
294
		t2 = t1 + EDX
Matthias Braun's avatar
Matthias Braun committed
295
		t3 = left_low * right_high
296
297
		h_res = t2 + t3
	*/
Michael Beck's avatar
Michael Beck committed
298

299
	/* handle the often used case of 32x32=64 mul */
Matthias Braun's avatar
Matthias Braun committed
300
301
302
303
304
305
	ir_node *h_res;
	ir_node *l_res;
	if (is_sign_extend(left_low, left_high)
	    && is_sign_extend(right_low, right_high)) {
		ir_node *mul = new_bd_ia32_l_IMul(dbg, block, left_low, right_low);
		h_res = new_rd_Proj(dbg, mul, mode, pn_ia32_l_IMul_res_high);
306
		l_res = new_rd_Proj(dbg, mul, ia32_mode_gp, pn_ia32_l_IMul_res_low);
307
308
	} else {
		/* note that zero extension is handled hare efficiently */
Matthias Braun's avatar
Matthias Braun committed
309
310
		ir_node *mul  = new_bd_ia32_l_Mul(dbg, block, left_low, right_low);
		ir_node *pEDX = new_rd_Proj(dbg, mul, mode, pn_ia32_l_Mul_res_high);
311
		l_res = new_rd_Proj(dbg, mul, ia32_mode_gp, pn_ia32_l_Mul_res_low);
Matthias Braun's avatar
Matthias Braun committed
312
313
314
315
316
317
318

		ir_node *right_lowc = new_rd_Conv(dbg, block, right_low, mode);
		ir_node *mul1 = new_rd_Mul(dbg, block, left_high, right_lowc, mode);
		ir_node *add        = new_rd_Add(dbg, block, mul1, pEDX, mode);
		ir_node *left_lowc  = new_rd_Conv(dbg, block, left_low, mode);
		ir_node *mul2 = new_rd_Mul(dbg, block, left_lowc, right_high, mode);
		h_res = new_rd_Add(dbg, block, add, mul2, mode);
319
	}
Matthias Braun's avatar
Matthias Braun committed
320
	ir_set_dw_lowered(node, l_res, h_res);
321
322
}

323
/**
Matthias Braun's avatar
Matthias Braun committed
324
 * lower 64bit minus operation
325
 */
Matthias Braun's avatar
Matthias Braun committed
326
static void ia32_lower_minus64(ir_node *node, ir_mode *mode)
327
{
Matthias Braun's avatar
Matthias Braun committed
328
329
330
331
332
333
	dbg_info *dbg     = get_irn_dbg_info(node);
	ir_node  *block   = get_nodes_block(node);
	ir_node  *op      = get_Minus_op(node);
	ir_node  *op_low  = get_lowered_low(op);
	ir_node  *op_high = get_lowered_high(op);
	ir_node  *minus   = new_bd_ia32_l_Minus64(dbg, block, op_low, op_high);
334
	ir_node  *l_res   = new_r_Proj(minus, ia32_mode_gp, pn_ia32_Minus64_res_low);
Matthias Braun's avatar
Matthias Braun committed
335
336
	ir_node  *h_res   = new_r_Proj(minus, mode, pn_ia32_Minus64_res_high);
	ir_set_dw_lowered(node, l_res, h_res);
337
338
339
}

/**
Matthias Braun's avatar
Matthias Braun committed
340
 * lower 64bit conversions
341
 */
Matthias Braun's avatar
Matthias Braun committed
342
static void ia32_lower_conv64(ir_node *node, ir_mode *mode)
343
{
Matthias Braun's avatar
Matthias Braun committed
344
345
346
347
	dbg_info  *dbg       = get_irn_dbg_info(node);
	ir_node   *op        = get_Conv_op(node);
	ir_mode   *mode_from = get_irn_mode(op);
	ir_mode   *mode_to   = get_irn_mode(node);
348

Matthias Braun's avatar
Matthias Braun committed
349
350
	if (mode_is_float(mode_from) && get_mode_size_bits(mode_to) == 64
	    && get_mode_arithmetic(mode_to) == irma_twos_complement) {
351
		/* We have a Conv float -> long long here */
Matthias Braun's avatar
Matthias Braun committed
352
353
354
355
		ir_node *float_to_ll;
		ir_node *l_res;
		ir_node *h_res;
		if (mode_is_signed(mode)) {
356
			/* convert from float to signed 64bit */
Matthias Braun's avatar
Matthias Braun committed
357
358
			ir_node *block = get_nodes_block(node);
			float_to_ll = new_bd_ia32_l_FloattoLL(dbg, block, op);
359
			l_res = new_r_Proj(float_to_ll, ia32_mode_gp,
360
			                   pn_ia32_l_FloattoLL_res_low);
Matthias Braun's avatar
Matthias Braun committed
361
			h_res = new_r_Proj(float_to_ll, mode,
362
363
							   pn_ia32_l_FloattoLL_res_high);
		} else {
Christoph Mallon's avatar
Christoph Mallon committed
364
			/* Convert from float to unsigned 64bit. */
Matthias Braun's avatar
Matthias Braun committed
365
366
367
368
369
370
371
			ir_graph  *irg = get_irn_irg(node);
			ir_tarval *flt_tv
				= new_tarval_from_str("9223372036854775808", 19, ia32_mode_E);
			ir_node   *flt_corr  = new_r_Const(irg, flt_tv);

			ir_node *lower_blk = part_block_dw(node);
			ir_node *upper_blk = get_nodes_block(node);
372
			set_dw_control_flow_changed();
Matthias Braun's avatar
Matthias Braun committed
373
374
375
376
377
378
379
380
381
382

			ir_node *opc  = new_rd_Conv(dbg, upper_blk, op, ia32_mode_E);
			ir_node *cmp  = new_rd_Cmp(dbg, upper_blk, opc, flt_corr,
			                           ir_relation_less);
			ir_node *cond = new_rd_Cond(dbg, upper_blk, cmp);
			ir_node *in[] = {
				new_r_Proj(cond, mode_X, pn_Cond_true),
				new_r_Proj(cond, mode_X, pn_Cond_false)
			};
			ir_node *blk   = new_r_Block(irg, 1, &in[1]);
383
			in[1] = new_r_Jmp(blk);
384
385
386
387

			set_irn_in(lower_blk, 2, in);

			/* create to Phis */
Matthias Braun's avatar
Matthias Braun committed
388
			ir_node *phi_in[] = {
389
				new_r_Const_null(irg, mode),
Matthias Braun's avatar
Matthias Braun committed
390
391
392
393
394
395
396
397
398
399
400
401
				new_r_Const_long(irg, mode, 0x80000000)
			};
			ir_node *int_phi
				= new_r_Phi(lower_blk, ARRAY_SIZE(phi_in), phi_in, mode);

			ir_node *fphi_in[] = {
				opc,
				new_rd_Sub(dbg, upper_blk, opc, flt_corr, ia32_mode_E)
			};
			ir_node *flt_phi
				= new_r_Phi(lower_blk, ARRAY_SIZE(fphi_in), fphi_in,
				            ia32_mode_E);
402

403
			/* fix Phi links for next part_block() */
404
405
406
407
			if (is_Phi(int_phi))
				add_Block_phi(lower_blk, int_phi);
			if (is_Phi(flt_phi))
				add_Block_phi(lower_blk, flt_phi);
408
409

			float_to_ll = new_bd_ia32_l_FloattoLL(dbg, lower_blk, flt_phi);
410
			l_res = new_r_Proj(float_to_ll, ia32_mode_gp,
411
							   pn_ia32_l_FloattoLL_res_low);
Matthias Braun's avatar
Matthias Braun committed
412
			h_res = new_r_Proj(float_to_ll, mode,
413
							   pn_ia32_l_FloattoLL_res_high);
Matthias Braun's avatar
Matthias Braun committed
414
			h_res = new_rd_Add(dbg, lower_blk, h_res, int_phi, mode);
415
416

			/* move the call and its Proj's to the lower block */
Matthias Braun's avatar
Matthias Braun committed
417
418
			set_nodes_block(node, lower_blk);
			for (ir_node *proj = (ir_node*)get_irn_link(node); proj != NULL;
419
			     proj = (ir_node*)get_irn_link(proj)) {
420
				set_nodes_block(proj, lower_blk);
421
			}
422
		}
Matthias Braun's avatar
Matthias Braun committed
423
424
425
426
		ir_set_dw_lowered(node, l_res, h_res);
	} else if (get_mode_size_bits(mode_from) == 64
	           && get_mode_arithmetic(mode_from) == irma_twos_complement
	           && mode_is_float(mode_to)) {
427
		/* We have a Conv long long -> float here */
Matthias Braun's avatar
Matthias Braun committed
428
429
430
431
432
		ir_node *op_low  = get_lowered_low(op);
		ir_node *op_high = get_lowered_high(op);
		ir_node *block   = get_nodes_block(node);
		ir_node *ll_to_float
			= new_bd_ia32_l_LLtoFloat(dbg, block, op_high, op_low, mode_to);
433

Matthias Braun's avatar
Matthias Braun committed
434
		exchange(node, ll_to_float);
435
	} else {
Matthias Braun's avatar
Matthias Braun committed
436
		ir_default_lower_dw_Conv(node, mode);
437
438
439
	}
}

Matthias Braun's avatar
Matthias Braun committed
440
441
442
static ir_entity *ia32_create_intrinsic_fkt(ir_type *method, const ir_op *op,
                                            const ir_mode *imode,
                                            const ir_mode *omode, void *context)
443
{
Matthias Braun's avatar
Matthias Braun committed
444
445
446
447
448
449
450
451
452
453
	(void)omode;
	(void)context;

	const char *name;
	if (op == op_Div) {
		name = mode_is_signed(imode) ? "__divdi3" : "__udivdi3";
	} else if (op == op_Mod) {
		name = mode_is_signed(imode) ? "__moddi3" : "__umoddi3";
	} else {
		panic("ia32: Unexpected lowering of 64bit op %s", get_op_name(op));
454
	}
Matthias Braun's avatar
Matthias Braun committed
455
456
	return create_compilerlib_entity(new_id_from_str(name), method);
}
457

Matthias Braun's avatar
Matthias Braun committed
458
459
460
void ia32_lower64(void)
{
	/* perform doubleword lowering */
461
462
	ir_mode *word_unsigned = ia32_reg_classes[CLASS_ia32_gp].mode;
	ir_mode *word_signed   = find_signed_mode(word_unsigned);
Matthias Braun's avatar
Matthias Braun committed
463
464
	lwrdw_param_t lower_dw_params = {
		ia32_create_intrinsic_fkt,
Matthias Braun's avatar
Matthias Braun committed
465
		NULL,
466
467
		word_unsigned,
		word_signed,
Matthias Braun's avatar
Matthias Braun committed
468
469
		64,    /* doubleword size */
		be_is_big_endian(),
Matthias Braun's avatar
Matthias Braun committed
470
471
472
473
474
475
476
477
478
	};

	ir_prepare_dw_lowering(&lower_dw_params);
	ir_register_dw_lower_function(op_Add,   ia32_lower_add64);
	ir_register_dw_lower_function(op_Sub,   ia32_lower_sub64);
	ir_register_dw_lower_function(op_Mul,   ia32_lower_mul64);
	ir_register_dw_lower_function(op_Minus, ia32_lower_minus64);
	ir_register_dw_lower_function(op_Conv,  ia32_lower_conv64);
	ir_lower_dw_ops();
479
}