Commit 868314358ea3f3009fb72d2867dc73af54338ae7

Authored by pbrook
1 parent c96402b1

Add zero extension (pseudo-)ops.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4424 c046a42c-6fe2-441c-8c8c-71466251a162
target-arm/translate.c
... ... @@ -221,8 +221,8 @@ static void store_reg(DisasContext *s, int reg, TCGv var)
221 221 #define gen_op_rorl_T1_im(im) tcg_gen_rori_i32(cpu_T[1], cpu_T[1], im)
222 222  
223 223 /* Value extensions. */
224   -#define gen_uxtb(var) tcg_gen_andi_i32(var, var, 0xff)
225   -#define gen_uxth(var) tcg_gen_andi_i32(var, var, 0xffff)
  224 +#define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
  225 +#define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
226 226 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
227 227 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
228 228  
... ... @@ -1446,7 +1446,7 @@ static void gen_op_iwmmxt_setpsr_nz(void)
1446 1446 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1447 1447 {
1448 1448 iwmmxt_load_reg(cpu_V1, rn);
1449   - tcg_gen_andi_i64(cpu_V1, cpu_V1, 0xffffffffu);
  1449 + tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1450 1450 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1451 1451 }
1452 1452  
... ... @@ -2704,7 +2704,7 @@ static void gen_neon_dup_u8(TCGv var, int shift)
2704 2704 TCGv tmp = new_tmp();
2705 2705 if (shift)
2706 2706 tcg_gen_shri_i32(var, var, shift);
2707   - tcg_gen_andi_i32(var, var, 0xff);
  2707 + tcg_gen_ext8u_i32(var, var);
2708 2708 tcg_gen_shli_i32(tmp, var, 8);
2709 2709 tcg_gen_or_i32(var, var, tmp);
2710 2710 tcg_gen_shli_i32(tmp, var, 16);
... ... @@ -2715,7 +2715,7 @@ static void gen_neon_dup_u8(TCGv var, int shift)
2715 2715 static void gen_neon_dup_low16(TCGv var)
2716 2716 {
2717 2717 TCGv tmp = new_tmp();
2718   - tcg_gen_andi_i32(var, var, 0xffff);
  2718 + tcg_gen_ext16u_i32(var, var);
2719 2719 tcg_gen_shli_i32(tmp, var, 16);
2720 2720 tcg_gen_or_i32(var, var, tmp);
2721 2721 dead_tmp(tmp);
... ... @@ -5862,7 +5862,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5862 5862 } else {
5863 5863 /* MOVT */
5864 5864 tmp = load_reg(s, rd);
5865   - tcg_gen_andi_i32(tmp, tmp, 0xffff);
  5865 + tcg_gen_ext16u_i32(tmp, tmp);
5866 5866 tcg_gen_ori_i32(tmp, tmp, val << 16);
5867 5867 }
5868 5868 store_reg(s, rd, tmp);
... ... @@ -6378,10 +6378,10 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
6378 6378 if (insn & (1 << 6)) {
6379 6379 /* pkhtb */
6380 6380 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6381   - tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
  6381 + tcg_gen_ext16u_i32(tmp2, tmp2);
6382 6382 } else {
6383 6383 /* pkhbt */
6384   - tcg_gen_andi_i32(tmp, tmp, 0xffff);
  6384 + tcg_gen_ext16u_i32(tmp, tmp);
6385 6385 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6386 6386 }
6387 6387 tcg_gen_or_i32(tmp, tmp, tmp2);
... ... @@ -7700,7 +7700,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7700 7700 if (insn & (1 << 23)) {
7701 7701 /* movt */
7702 7702 tmp = load_reg(s, rd);
7703   - tcg_gen_andi_i32(tmp, tmp, 0xffff);
  7703 + tcg_gen_ext16u_i32(tmp, tmp);
7704 7704 tcg_gen_ori_i32(tmp, tmp, imm << 16);
7705 7705 } else {
7706 7706 /* movw */
... ...
target-cris/translate.c
... ... @@ -1165,11 +1165,10 @@ static inline void t_gen_sext(TCGv d, TCGv s, int size)
1165 1165  
1166 1166 static inline void t_gen_zext(TCGv d, TCGv s, int size)
1167 1167 {
1168   - /* TCG-FIXME: this is not optimal. Many archs have fast zext insns. */
1169 1168 if (size == 1)
1170   - tcg_gen_andi_i32(d, s, 0xff);
  1169 + tcg_gen_ext8u_i32(d, s);
1171 1170 else if (size == 2)
1172   - tcg_gen_andi_i32(d, s, 0xffff);
  1171 + tcg_gen_ext16u_i32(d, s);
1173 1172 else
1174 1173 tcg_gen_mov_tl(d, s);
1175 1174 }
... ...
tcg/README
... ... @@ -260,10 +260,13 @@ t0 = t1
260 260 Move t1 to t0 (both operands must have the same type).
261 261  
262 262 * ext8s_i32/i64 t0, t1
  263 +ext8u_i32/i64 t0, t1
263 264 ext16s_i32/i64 t0, t1
  265 +ext16u_i32/i64 t0, t1
264 266 ext32s_i64 t0, t1
  267 +ext32u_i64 t0, t1
265 268  
266   -8, 16 or 32 bit sign extension (both operands must have the same type)
  269 +8, 16 or 32 bit sign/zero extension (both operands must have the same type)
267 270  
268 271 * bswap16_i32 t0, t1
269 272  
... ...
tcg/tcg-op.h
... ... @@ -980,6 +980,18 @@ static inline void tcg_gen_ext16s_i32(TCGv ret, TCGv arg)
980 980 #endif
981 981 }
982 982  
  983 +/* These are currently just for convenience.
  984 + We assume a target will recognise these automatically . */
  985 +static inline void tcg_gen_ext8u_i32(TCGv ret, TCGv arg)
  986 +{
  987 + tcg_gen_andi_i32(ret, arg, 0xffu);
  988 +}
  989 +
  990 +static inline void tcg_gen_ext16u_i32(TCGv ret, TCGv arg)
  991 +{
  992 + tcg_gen_andi_i32(ret, arg, 0xffffu);
  993 +}
  994 +
983 995 /* Note: we assume the two high bytes are set to zero */
984 996 static inline void tcg_gen_bswap16_i32(TCGv ret, TCGv arg)
985 997 {
... ... @@ -1040,6 +1052,24 @@ static inline void tcg_gen_ext32s_i64(TCGv ret, TCGv arg)
1040 1052 tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31);
1041 1053 }
1042 1054  
  1055 +static inline void tcg_gen_ext8u_i64(TCGv ret, TCGv arg)
  1056 +{
  1057 + tcg_gen_ext8u_i32(ret, arg);
  1058 + tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
  1059 +}
  1060 +
  1061 +static inline void tcg_gen_ext16u_i64(TCGv ret, TCGv arg)
  1062 +{
  1063 + tcg_gen_ext16u_i32(ret, arg);
  1064 + tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
  1065 +}
  1066 +
  1067 +static inline void tcg_gen_ext32u_i64(TCGv ret, TCGv arg)
  1068 +{
  1069 + tcg_gen_mov_i32(ret, arg);
  1070 + tcg_gen_movi_i32(TCGV_HIGH(ret), 0);
  1071 +}
  1072 +
1043 1073 static inline void tcg_gen_trunc_i64_i32(TCGv ret, TCGv arg)
1044 1074 {
1045 1075 tcg_gen_mov_i32(ret, arg);
... ... @@ -1100,6 +1130,21 @@ static inline void tcg_gen_ext32s_i64(TCGv ret, TCGv arg)
1100 1130 #endif
1101 1131 }
1102 1132  
  1133 +static inline void tcg_gen_ext8u_i64(TCGv ret, TCGv arg)
  1134 +{
  1135 + tcg_gen_andi_i64(ret, arg, 0xffu);
  1136 +}
  1137 +
  1138 +static inline void tcg_gen_ext16u_i64(TCGv ret, TCGv arg)
  1139 +{
  1140 + tcg_gen_andi_i64(ret, arg, 0xffffu);
  1141 +}
  1142 +
  1143 +static inline void tcg_gen_ext32u_i64(TCGv ret, TCGv arg)
  1144 +{
  1145 + tcg_gen_andi_i64(ret, arg, 0xffffffffu);
  1146 +}
  1147 +
1103 1148 /* Note: we assume the target supports move between 32 and 64 bit
1104 1149 registers. This will probably break MIPS64 targets. */
1105 1150 static inline void tcg_gen_trunc_i64_i32(TCGv ret, TCGv arg)
... ... @@ -1111,7 +1156,7 @@ static inline void tcg_gen_trunc_i64_i32(TCGv ret, TCGv arg)
1111 1156 registers */
1112 1157 static inline void tcg_gen_extu_i32_i64(TCGv ret, TCGv arg)
1113 1158 {
1114   - tcg_gen_andi_i64(ret, arg, 0xffffffff);
  1159 + tcg_gen_andi_i64(ret, arg, 0xffffffffu);
1115 1160 }
1116 1161  
1117 1162 /* Note: we assume the target supports move between 32 and 64 bit
... ...