/*
- * Project: libFIRM
- * File name: ir/lower/lower_dw.c
- * Purpose: Lower Double word operations, ie Mode L -> I.
- * Author: Michael Beck
- * Created: 8.10.2004
- * CVS-ID: $Id$
- * Copyright: (c) 1998-2006 Universität Karlsruhe
- * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
+ * 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.
+ */
+
+/**
+ * @file
+ * @brief Lower Double word operations, ie 64bit -> 32bit, 32bit -> 16bit etc.
+ * @date 8.10.2004
+ * @author Michael Beck
+ * @version $Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-#ifdef HAVE_MALLOC_H
-# include <malloc.h>
-#endif
-#ifdef HAVE_ALLOCA_H
-# include <alloca.h>
-#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#include <assert.h>
+#include "lowering.h"
#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
#include "firmstat.h"
#include "irgwalk.h"
#include "ircons.h"
-#include "lower_dw.h"
#include "irflag.h"
#include "irtools.h"
#include "debug.h"
#include "pmap.h"
#include "pdeq.h"
#include "irdump.h"
+#include "xmalloc.h"
/** A map from mode to a primitive type. */
static pmap *prim_types;
dbg_info *dbg;
int idx;
node_entry_t *entry;
+ (void) node;
+ (void) mode;
irn = get_Store_value(node);
entry = env->entries[get_irn_idx(irn)];
env->entries[idx]->high_word = new_rd_Not(dbg, current_ir_graph, block, op_h, mode);
} /* lower_Not */
-/**
- * Translate a Minus.
- *
- * Create two Minus'.
- */
-static void lower_Minus(ir_node *node, ir_mode *mode, lower_env_t *env) {
- ir_node *block, *irn;
- ir_node *op_l, *op_h;
- dbg_info *dbg;
- int idx;
- ir_graph *irg;
- node_entry_t *entry;
-
- irn = get_Minus_op(node);
- entry = env->entries[get_irn_idx(irn)];
- assert(entry);
-
- if (! entry->low_word) {
- /* not ready yet, wait */
- pdeq_putr(env->waitq, node);
- return;
- } /* if */
-
- op_l = entry->low_word;
- op_h = entry->high_word;
-
- dbg = get_irn_dbg_info(node);
- block = get_nodes_block(node);
- irg = current_ir_graph;
-
- idx = get_irn_idx(node);
- assert(idx < env->n_entries);
- env->entries[idx]->low_word = new_rd_Minus(dbg, current_ir_graph, block, op_l, mode);
- env->entries[idx]->high_word = new_rd_Minus(dbg, current_ir_graph, block, op_h, mode);
-} /* lower_Minus */
-
/**
* Translate a Cond.
*/
ir_node *sel = get_Cond_selector(node);
ir_mode *m = get_irn_mode(sel);
int idx;
+ (void) mode;
if (m == mode_b) {
node_entry_t *lentry, *rentry;
pn_Cmp pnc;
dbg_info *dbg;
+ if(!is_Proj(sel))
+ return;
+
cmp = get_Proj_pred(sel);
+ if(!is_Cmp(cmp))
+ return;
+
left = get_Cmp_left(cmp);
idx = get_irn_idx(left);
lentry = env->entries[idx];
op = new_rd_Conv(dbg, irg, block, op, dst_mode);
env->entries[idx]->low_word = op;
- env->entries[idx]->high_word = new_rd_Shrs(dbg, irg, block, op,
- new_Const_long(mode_Iu, get_mode_size_bits(dst_mode) - 1), dst_mode);
+
+ if (mode_is_signed(imode)) {
+ env->entries[idx]->high_word = new_rd_Shrs(dbg, irg, block, op,
+ new_Const_long(mode_Iu, get_mode_size_bits(dst_mode) - 1), dst_mode);
+ } else {
+ env->entries[idx]->high_word = new_Const(dst_mode, get_mode_null(dst_mode));
+ } /* if */
} /* if */
} else {
ir_node *irn, *call;
op = new_rd_Conv(dbg, irg, block, op, dst_mode);
env->entries[idx]->low_word = op;
- env->entries[idx]->high_word = new_Const(dst_mode, get_mode_null(dst_mode));
+
+ if (mode_is_signed(imode)) {
+ env->entries[idx]->high_word = new_rd_Shrs(dbg, irg, block, op,
+ new_Const_long(mode_Iu, get_mode_size_bits(dst_mode) - 1), dst_mode);
+ } else {
+ env->entries[idx]->high_word = new_Const(dst_mode, get_mode_null(dst_mode));
+ } /* if */
} /* if */
} else {
ir_node *irn, *call;
assert(idx < env->n_entries);
+ if (! env->entries[idx]->low_word) {
+ /* not ready yet, wait */
+ pdeq_putr(env->waitq, node);
+ return;
+ } /* if */
+
if (mode_is_int(omode) || mode_is_reference(omode)) {
op = env->entries[idx]->low_word;
assert(idx < env->n_entries);
+ if (! env->entries[idx]->low_word) {
+ /* not ready yet, wait */
+ pdeq_putr(env->waitq, node);
+ return;
+ } /* if */
+
if (mode_is_int(omode) || mode_is_reference(omode)) {
op = env->entries[idx]->low_word;
ir_node **in;
int i, j, n, idx;
int need_conv = 0;
+ (void) mode;
/* check if this return must be lowered */
for (i = 0, n = get_Return_n_ress(node); i < n; ++i) {
long *new_projs;
int i, j, n_params, rem;
ir_node *proj, *args;
+ (void) mode;
if (is_lowered_type(tp)) {
mtp = get_associated_type(tp);
int n_params, n_res, need_lower = 0;
int i, j;
long *res_numbers = NULL;
+ (void) mode;
if (is_lowered_type(tp)) {
call_tp = get_associated_type(tp);
/**
* check for opcodes that must always be lowered.
*/
-static int always_lower(opcode code) {
+static int always_lower(ir_opcode code) {
switch (code) {
case iro_Proj:
case iro_Start:
static int cmp_op_mode(const void *elt, const void *key, size_t size) {
const op_mode_entry_t *e1 = elt;
const op_mode_entry_t *e2 = key;
+ (void) size;
return (e1->op - e2->op) | (e1->imode - e2->imode) | (e1->omode - e2->omode);
} /* cmp_op_mode */
static int cmp_conv_tp(const void *elt, const void *key, size_t size) {
const conv_tp_entry_t *e1 = elt;
const conv_tp_entry_t *e2 = key;
+ (void) size;
return (e1->imode - e2->imode) | (e1->omode - e2->omode);
} /* static int cmp_conv_tp */
LOWER(Shr);
LOWER(Shrs);
LOWER(Rot);
- LOWER(Minus);
LOWER(DivMod);
LOWER(Div);
LOWER(Mod);
LOWER_UN(Abs);
+ LOWER_UN(Minus);
LOWER(Conv);
char buf[64];
ident *id;
ir_entity *ent;
+ (void) context;
if (imode == omode) {
snprintf(buf, sizeof(buf), "__l%s%s", get_op_name(op), get_mode_name(imode));