@@ -2804,9 +2804,18 @@ void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg,
tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
return;
}
- /* The field is split across two words. One double-word
- shift is better than two double-word shifts. */
- goto do_shift_and;
+
+ /* The field is split across two words. */
+ tcg_gen_extract2_i32(TCGV_LOW(ret), TCGV_LOW(arg),
+ TCGV_HIGH(arg), ofs);
+ if (len <= 32) {
+ tcg_gen_extract_i32(TCGV_LOW(ret), TCGV_LOW(ret), 0, len);
+ tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
+ } else {
+ tcg_gen_extract_i32(TCGV_HIGH(ret), TCGV_HIGH(arg),
+ ofs, len - 32);
+ }
+ return;
}
if (TCG_TARGET_extract_valid(TCG_TYPE_I64, ofs, len)) {
@@ -2844,7 +2853,6 @@ void tcg_gen_extract_i64(TCGv_i64 ret, TCGv_i64 arg,
so that we get ext8u, ext16u, and ext32u. */
switch (len) {
case 1 ... 8: case 16: case 32:
- do_shift_and:
tcg_gen_shri_i64(ret, arg, ofs);
tcg_gen_andi_i64(ret, ret, (1ull << len) - 1);
break;