+ env->entries[idx]->low_word = new_r_Proj(irg, block, irn, env->params->low_unsigned, 0);
+ env->entries[idx]->high_word = new_r_Proj(irg, block, irn, mode, 1);
+} /* lower_Shiftop */
+
+/**
+ * Translate a Shr and handle special cases.
+ */
+static void lower_Shr(ir_node *node, ir_mode *mode, lower_env_t *env) {
+ ir_node *right = get_Shr_right(node);
+ ir_graph *irg = current_ir_graph;
+
+ if (get_mode_arithmetic(mode) == irma_twos_complement && is_Const(right)) {
+ tarval *tv = get_Const_tarval(right);
+
+ if (tarval_is_long(tv) &&
+ get_tarval_long(tv) >= (int) get_mode_size_bits(mode)) {
+ ir_node *block = get_nodes_block(node);
+ ir_node *left = get_Shr_left(node);
+ ir_node *c;
+ long shf_cnt = get_tarval_long(tv) - get_mode_size_bits(mode);
+ int idx = get_irn_idx(left);
+
+ left = env->entries[idx]->high_word;
+ idx = get_irn_idx(node);
+
+ if (shf_cnt > 0) {
+ c = new_r_Const_long(irg, block, mode_Iu, shf_cnt);
+ env->entries[idx]->low_word = new_r_Shr(irg, block, left, c, mode);
+ } else {
+ env->entries[idx]->low_word = left;
+ } /* if */
+ env->entries[idx]->high_word = new_r_Const(irg, block, mode, get_mode_null(mode));
+
+ return;
+ } /* if */
+ } /* if */
+ lower_Shiftop(node, mode, env);
+} /* lower_Shr */
+
+/**
+ * Translate a Shl and handle special cases.
+ */
+static void lower_Shl(ir_node *node, ir_mode *mode, lower_env_t *env) {
+ ir_node *right = get_Shl_right(node);
+ ir_graph *irg = current_ir_graph;
+
+ if (get_mode_arithmetic(mode) == irma_twos_complement && is_Const(right)) {
+ tarval *tv = get_Const_tarval(right);
+
+ if (tarval_is_long(tv) &&
+ get_tarval_long(tv) >= (int) get_mode_size_bits(mode)) {
+ ir_mode *mode_l;
+ ir_node *block = get_nodes_block(node);
+ ir_node *left = get_Shl_left(node);
+ ir_node *c;
+ long shf_cnt = get_tarval_long(tv) - get_mode_size_bits(mode);
+ int idx = get_irn_idx(left);
+
+ left = new_r_Conv(irg, block, env->entries[idx]->low_word, mode);
+ idx = get_irn_idx(node);
+
+ if (shf_cnt > 0) {
+ c = new_r_Const_long(irg, block, mode_Iu, shf_cnt);
+ env->entries[idx]->high_word = new_r_Shl(irg, block, left, c, mode);
+ } else {
+ env->entries[idx]->high_word = left;
+ } /* if */
+ mode_l = env->params->low_unsigned;
+ env->entries[idx]->low_word = new_r_Const(irg, block, mode_l, get_mode_null(mode_l));
+
+ return;
+ } /* if */
+ } /* if */
+ lower_Shiftop(node, mode, env);
+} /* lower_Shl */
+
+/**
+ * Translate a Shrs and handle special cases.
+ */
+static void lower_Shrs(ir_node *node, ir_mode *mode, lower_env_t *env) {
+ ir_node *right = get_Shrs_right(node);
+ ir_graph *irg = current_ir_graph;
+
+ if (get_mode_arithmetic(mode) == irma_twos_complement && is_Const(right)) {
+ tarval *tv = get_Const_tarval(right);
+
+ if (tarval_is_long(tv) &&
+ get_tarval_long(tv) >= (int) get_mode_size_bits(mode)) {
+ ir_node *block = get_nodes_block(node);
+ ir_node *left = get_Shrs_left(node);
+ long shf_cnt = get_tarval_long(tv) - get_mode_size_bits(mode);
+ ir_node *c;
+ int idx = get_irn_idx(left);
+
+ left = env->entries[idx]->high_word;
+ idx = get_irn_idx(node);
+
+ if (shf_cnt > 0) {
+ c = new_r_Const_long(irg, block, mode_Iu, shf_cnt);
+ env->entries[idx]->low_word = new_r_Shrs(irg, block, left, c, mode);
+ } else {
+ env->entries[idx]->low_word = left;
+ } /* if */
+ c = new_r_Const_long(irg, block, mode_Iu, get_mode_size_bits(mode) - 1);
+ env->entries[idx]->high_word = new_r_Shrs(irg, block, left, c, mode);
+
+ return;
+ } /* if */
+ } /* if */
+ lower_Shiftop(node, mode, env);
+} /* lower_Shrs */
+
+/**
+ * Translate a Rot and handle special cases.
+ */
+static void lower_Rot(ir_node *node, ir_mode *mode, lower_env_t *env) {
+ ir_node *right = get_Rot_right(node);
+
+ if (get_mode_arithmetic(mode) == irma_twos_complement && is_Const(right)) {
+ tarval *tv = get_Const_tarval(right);
+
+ if (tarval_is_long(tv) &&
+ get_tarval_long(tv) == (int) get_mode_size_bits(mode)) {
+ ir_node *left = get_Rot_left(node);
+ ir_node *h, *l;
+ int idx = get_irn_idx(left);
+
+ l = env->entries[idx]->low_word;
+ h = env->entries[idx]->high_word;
+ idx = get_irn_idx(node);
+
+ env->entries[idx]->low_word = h;
+ env->entries[idx]->high_word = l;
+
+ return;
+ } /* if */
+ } /* if */
+ lower_Shiftop(node, mode, env);
+} /* lower_Rot */