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,8 +221,8 @@ static void store_reg(DisasContext *s, int reg, TCGv var)
221 #define gen_op_rorl_T1_im(im) tcg_gen_rori_i32(cpu_T[1], cpu_T[1], im) 221 #define gen_op_rorl_T1_im(im) tcg_gen_rori_i32(cpu_T[1], cpu_T[1], im)
222 222
223 /* Value extensions. */ 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 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var) 226 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
227 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var) 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,7 +1446,7 @@ static void gen_op_iwmmxt_setpsr_nz(void)
1446 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn) 1446 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1447 { 1447 {
1448 iwmmxt_load_reg(cpu_V1, rn); 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 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1); 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,7 +2704,7 @@ static void gen_neon_dup_u8(TCGv var, int shift)
2704 TCGv tmp = new_tmp(); 2704 TCGv tmp = new_tmp();
2705 if (shift) 2705 if (shift)
2706 tcg_gen_shri_i32(var, var, shift); 2706 tcg_gen_shri_i32(var, var, shift);
2707 - tcg_gen_andi_i32(var, var, 0xff); 2707 + tcg_gen_ext8u_i32(var, var);
2708 tcg_gen_shli_i32(tmp, var, 8); 2708 tcg_gen_shli_i32(tmp, var, 8);
2709 tcg_gen_or_i32(var, var, tmp); 2709 tcg_gen_or_i32(var, var, tmp);
2710 tcg_gen_shli_i32(tmp, var, 16); 2710 tcg_gen_shli_i32(tmp, var, 16);
@@ -2715,7 +2715,7 @@ static void gen_neon_dup_u8(TCGv var, int shift) @@ -2715,7 +2715,7 @@ static void gen_neon_dup_u8(TCGv var, int shift)
2715 static void gen_neon_dup_low16(TCGv var) 2715 static void gen_neon_dup_low16(TCGv var)
2716 { 2716 {
2717 TCGv tmp = new_tmp(); 2717 TCGv tmp = new_tmp();
2718 - tcg_gen_andi_i32(var, var, 0xffff); 2718 + tcg_gen_ext16u_i32(var, var);
2719 tcg_gen_shli_i32(tmp, var, 16); 2719 tcg_gen_shli_i32(tmp, var, 16);
2720 tcg_gen_or_i32(var, var, tmp); 2720 tcg_gen_or_i32(var, var, tmp);
2721 dead_tmp(tmp); 2721 dead_tmp(tmp);
@@ -5862,7 +5862,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -5862,7 +5862,7 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
5862 } else { 5862 } else {
5863 /* MOVT */ 5863 /* MOVT */
5864 tmp = load_reg(s, rd); 5864 tmp = load_reg(s, rd);
5865 - tcg_gen_andi_i32(tmp, tmp, 0xffff); 5865 + tcg_gen_ext16u_i32(tmp, tmp);
5866 tcg_gen_ori_i32(tmp, tmp, val << 16); 5866 tcg_gen_ori_i32(tmp, tmp, val << 16);
5867 } 5867 }
5868 store_reg(s, rd, tmp); 5868 store_reg(s, rd, tmp);
@@ -6378,10 +6378,10 @@ static void disas_arm_insn(CPUState * env, DisasContext *s) @@ -6378,10 +6378,10 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
6378 if (insn & (1 << 6)) { 6378 if (insn & (1 << 6)) {
6379 /* pkhtb */ 6379 /* pkhtb */
6380 tcg_gen_andi_i32(tmp, tmp, 0xffff0000); 6380 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
6381 - tcg_gen_andi_i32(tmp2, tmp2, 0xffff); 6381 + tcg_gen_ext16u_i32(tmp2, tmp2);
6382 } else { 6382 } else {
6383 /* pkhbt */ 6383 /* pkhbt */
6384 - tcg_gen_andi_i32(tmp, tmp, 0xffff); 6384 + tcg_gen_ext16u_i32(tmp, tmp);
6385 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); 6385 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
6386 } 6386 }
6387 tcg_gen_or_i32(tmp, tmp, tmp2); 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,7 +7700,7 @@ static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
7700 if (insn & (1 << 23)) { 7700 if (insn & (1 << 23)) {
7701 /* movt */ 7701 /* movt */
7702 tmp = load_reg(s, rd); 7702 tmp = load_reg(s, rd);
7703 - tcg_gen_andi_i32(tmp, tmp, 0xffff); 7703 + tcg_gen_ext16u_i32(tmp, tmp);
7704 tcg_gen_ori_i32(tmp, tmp, imm << 16); 7704 tcg_gen_ori_i32(tmp, tmp, imm << 16);
7705 } else { 7705 } else {
7706 /* movw */ 7706 /* movw */
target-cris/translate.c
@@ -1165,11 +1165,10 @@ static inline void t_gen_sext(TCGv d, TCGv s, int size) @@ -1165,11 +1165,10 @@ static inline void t_gen_sext(TCGv d, TCGv s, int size)
1165 1165
1166 static inline void t_gen_zext(TCGv d, TCGv s, int size) 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 if (size == 1) 1168 if (size == 1)
1170 - tcg_gen_andi_i32(d, s, 0xff); 1169 + tcg_gen_ext8u_i32(d, s);
1171 else if (size == 2) 1170 else if (size == 2)
1172 - tcg_gen_andi_i32(d, s, 0xffff); 1171 + tcg_gen_ext16u_i32(d, s);
1173 else 1172 else
1174 tcg_gen_mov_tl(d, s); 1173 tcg_gen_mov_tl(d, s);
1175 } 1174 }
tcg/README
@@ -260,10 +260,13 @@ t0 = t1 @@ -260,10 +260,13 @@ t0 = t1
260 Move t1 to t0 (both operands must have the same type). 260 Move t1 to t0 (both operands must have the same type).
261 261
262 * ext8s_i32/i64 t0, t1 262 * ext8s_i32/i64 t0, t1
  263 +ext8u_i32/i64 t0, t1
263 ext16s_i32/i64 t0, t1 264 ext16s_i32/i64 t0, t1
  265 +ext16u_i32/i64 t0, t1
264 ext32s_i64 t0, t1 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 * bswap16_i32 t0, t1 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,6 +980,18 @@ static inline void tcg_gen_ext16s_i32(TCGv ret, TCGv arg)
980 #endif 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 /* Note: we assume the two high bytes are set to zero */ 995 /* Note: we assume the two high bytes are set to zero */
984 static inline void tcg_gen_bswap16_i32(TCGv ret, TCGv arg) 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,6 +1052,24 @@ static inline void tcg_gen_ext32s_i64(TCGv ret, TCGv arg)
1040 tcg_gen_sari_i32(TCGV_HIGH(ret), ret, 31); 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 static inline void tcg_gen_trunc_i64_i32(TCGv ret, TCGv arg) 1073 static inline void tcg_gen_trunc_i64_i32(TCGv ret, TCGv arg)
1044 { 1074 {
1045 tcg_gen_mov_i32(ret, arg); 1075 tcg_gen_mov_i32(ret, arg);
@@ -1100,6 +1130,21 @@ static inline void tcg_gen_ext32s_i64(TCGv ret, TCGv arg) @@ -1100,6 +1130,21 @@ static inline void tcg_gen_ext32s_i64(TCGv ret, TCGv arg)
1100 #endif 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 /* Note: we assume the target supports move between 32 and 64 bit 1148 /* Note: we assume the target supports move between 32 and 64 bit
1104 registers. This will probably break MIPS64 targets. */ 1149 registers. This will probably break MIPS64 targets. */
1105 static inline void tcg_gen_trunc_i64_i32(TCGv ret, TCGv arg) 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,7 +1156,7 @@ static inline void tcg_gen_trunc_i64_i32(TCGv ret, TCGv arg)
1111 registers */ 1156 registers */
1112 static inline void tcg_gen_extu_i32_i64(TCGv ret, TCGv arg) 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 /* Note: we assume the target supports move between 32 and 64 bit 1162 /* Note: we assume the target supports move between 32 and 64 bit