Commit 5ff9d6a469fbbd3861ea49e241b0ccd09aedd62b

Authored by bellard
1 parent bb210e78

fixed sign extensions - added explicit side effect op flag - added discard instruction


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3963 c046a42c-6fe2-441c-8c8c-71466251a162
tcg/README
@@ -280,6 +280,11 @@ to zero. @@ -280,6 +280,11 @@ to zero.
280 280
281 64 bit byte swap 281 64 bit byte swap
282 282
  283 +* discard_i32/i64 t0
  284 +
  285 +Indicate that the value of t0 won't be used later. It is useful to
  286 +force dead code elimination.
  287 +
283 ********* Type conversions 288 ********* Type conversions
284 289
285 * ext_i32_i64 t0, t1 290 * ext_i32_i64 t0, t1
tcg/tcg-op.h
@@ -865,7 +865,7 @@ static inline void tcg_gen_ext8s_i32(TCGv ret, TCGv arg) @@ -865,7 +865,7 @@ static inline void tcg_gen_ext8s_i32(TCGv ret, TCGv arg)
865 tcg_gen_op2(INDEX_op_ext8s_i32, ret, arg); 865 tcg_gen_op2(INDEX_op_ext8s_i32, ret, arg);
866 #else 866 #else
867 tcg_gen_shli_i32(ret, arg, 24); 867 tcg_gen_shli_i32(ret, arg, 24);
868 - tcg_gen_sari_i32(ret, arg, 24); 868 + tcg_gen_sari_i32(ret, ret, 24);
869 #endif 869 #endif
870 } 870 }
871 871
@@ -875,7 +875,7 @@ static inline void tcg_gen_ext16s_i32(TCGv ret, TCGv arg) @@ -875,7 +875,7 @@ static inline void tcg_gen_ext16s_i32(TCGv ret, TCGv arg)
875 tcg_gen_op2(INDEX_op_ext16s_i32, ret, arg); 875 tcg_gen_op2(INDEX_op_ext16s_i32, ret, arg);
876 #else 876 #else
877 tcg_gen_shli_i32(ret, arg, 16); 877 tcg_gen_shli_i32(ret, arg, 16);
878 - tcg_gen_sari_i32(ret, arg, 16); 878 + tcg_gen_sari_i32(ret, ret, 16);
879 #endif 879 #endif
880 } 880 }
881 881
@@ -975,7 +975,7 @@ static inline void tcg_gen_ext8s_i64(TCGv ret, TCGv arg) @@ -975,7 +975,7 @@ static inline void tcg_gen_ext8s_i64(TCGv ret, TCGv arg)
975 tcg_gen_op2(INDEX_op_ext8s_i64, ret, arg); 975 tcg_gen_op2(INDEX_op_ext8s_i64, ret, arg);
976 #else 976 #else
977 tcg_gen_shli_i64(ret, arg, 56); 977 tcg_gen_shli_i64(ret, arg, 56);
978 - tcg_gen_sari_i64(ret, arg, 56); 978 + tcg_gen_sari_i64(ret, ret, 56);
979 #endif 979 #endif
980 } 980 }
981 981
@@ -985,7 +985,7 @@ static inline void tcg_gen_ext16s_i64(TCGv ret, TCGv arg) @@ -985,7 +985,7 @@ static inline void tcg_gen_ext16s_i64(TCGv ret, TCGv arg)
985 tcg_gen_op2(INDEX_op_ext16s_i64, ret, arg); 985 tcg_gen_op2(INDEX_op_ext16s_i64, ret, arg);
986 #else 986 #else
987 tcg_gen_shli_i64(ret, arg, 48); 987 tcg_gen_shli_i64(ret, arg, 48);
988 - tcg_gen_sari_i64(ret, arg, 48); 988 + tcg_gen_sari_i64(ret, ret, 48);
989 #endif 989 #endif
990 } 990 }
991 991
@@ -995,7 +995,7 @@ static inline void tcg_gen_ext32s_i64(TCGv ret, TCGv arg) @@ -995,7 +995,7 @@ static inline void tcg_gen_ext32s_i64(TCGv ret, TCGv arg)
995 tcg_gen_op2(INDEX_op_ext32s_i64, ret, arg); 995 tcg_gen_op2(INDEX_op_ext32s_i64, ret, arg);
996 #else 996 #else
997 tcg_gen_shli_i64(ret, arg, 32); 997 tcg_gen_shli_i64(ret, arg, 32);
998 - tcg_gen_sari_i64(ret, arg, 32); 998 + tcg_gen_sari_i64(ret, ret, 32);
999 #endif 999 #endif
1000 } 1000 }
1001 1001
@@ -1062,6 +1062,25 @@ static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg) @@ -1062,6 +1062,25 @@ static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg)
1062 1062
1063 #endif 1063 #endif
1064 1064
  1065 +
  1066 +static inline void tcg_gen_discard_i32(TCGv arg)
  1067 +{
  1068 + tcg_gen_op1(INDEX_op_discard, arg);
  1069 +}
  1070 +
  1071 +#if TCG_TARGET_REG_BITS == 32
  1072 +static inline void tcg_gen_discard_i64(TCGv arg)
  1073 +{
  1074 + tcg_gen_discard_i32(arg);
  1075 + tcg_gen_discard_i32(TCGV_HIGH(arg));
  1076 +}
  1077 +#else
  1078 +static inline void tcg_gen_discard_i64(TCGv arg)
  1079 +{
  1080 + tcg_gen_op1(INDEX_op_discard, arg);
  1081 +}
  1082 +#endif
  1083 +
1065 /***************************************/ 1084 /***************************************/
1066 static inline void tcg_gen_macro_2(TCGv ret0, TCGv ret1, int macro_id) 1085 static inline void tcg_gen_macro_2(TCGv ret0, TCGv ret1, int macro_id)
1067 { 1086 {
tcg/tcg-opc.h
@@ -40,10 +40,12 @@ DEF2(macro_start, 0, 0, 2, 0) @@ -40,10 +40,12 @@ DEF2(macro_start, 0, 0, 2, 0)
40 DEF2(macro_end, 0, 0, 2, 0) 40 DEF2(macro_end, 0, 0, 2, 0)
41 DEF2(macro_goto, 0, 0, 3, 0) 41 DEF2(macro_goto, 0, 0, 3, 0)
42 42
  43 +DEF2(discard, 1, 0, 0, 0)
  44 +
43 DEF2(set_label, 0, 0, 1, 0) 45 DEF2(set_label, 0, 0, 1, 0)
44 -DEF2(call, 0, 1, 2, 0) /* variable number of parameters */  
45 -DEF2(jmp, 0, 1, 0, TCG_OPF_BB_END)  
46 -DEF2(br, 0, 0, 1, TCG_OPF_BB_END) 46 +DEF2(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) /* variable number of parameters */
  47 +DEF2(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
  48 +DEF2(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
47 49
48 DEF2(mov_i32, 1, 1, 0, 0) 50 DEF2(mov_i32, 1, 1, 0, 0)
49 DEF2(movi_i32, 1, 0, 1, 0) 51 DEF2(movi_i32, 1, 0, 1, 0)
@@ -53,9 +55,9 @@ DEF2(ld8s_i32, 1, 1, 1, 0) @@ -53,9 +55,9 @@ DEF2(ld8s_i32, 1, 1, 1, 0)
53 DEF2(ld16u_i32, 1, 1, 1, 0) 55 DEF2(ld16u_i32, 1, 1, 1, 0)
54 DEF2(ld16s_i32, 1, 1, 1, 0) 56 DEF2(ld16s_i32, 1, 1, 1, 0)
55 DEF2(ld_i32, 1, 1, 1, 0) 57 DEF2(ld_i32, 1, 1, 1, 0)
56 -DEF2(st8_i32, 0, 2, 1, 0)  
57 -DEF2(st16_i32, 0, 2, 1, 0)  
58 -DEF2(st_i32, 0, 2, 1, 0) 58 +DEF2(st8_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
  59 +DEF2(st16_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
  60 +DEF2(st_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
59 /* arith */ 61 /* arith */
60 DEF2(add_i32, 1, 2, 0, 0) 62 DEF2(add_i32, 1, 2, 0, 0)
61 DEF2(sub_i32, 1, 2, 0, 0) 63 DEF2(sub_i32, 1, 2, 0, 0)
@@ -77,11 +79,11 @@ DEF2(shl_i32, 1, 2, 0, 0) @@ -77,11 +79,11 @@ DEF2(shl_i32, 1, 2, 0, 0)
77 DEF2(shr_i32, 1, 2, 0, 0) 79 DEF2(shr_i32, 1, 2, 0, 0)
78 DEF2(sar_i32, 1, 2, 0, 0) 80 DEF2(sar_i32, 1, 2, 0, 0)
79 81
80 -DEF2(brcond_i32, 0, 2, 2, TCG_OPF_BB_END) 82 +DEF2(brcond_i32, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
81 #if TCG_TARGET_REG_BITS == 32 83 #if TCG_TARGET_REG_BITS == 32
82 DEF2(add2_i32, 2, 4, 0, 0) 84 DEF2(add2_i32, 2, 4, 0, 0)
83 DEF2(sub2_i32, 2, 4, 0, 0) 85 DEF2(sub2_i32, 2, 4, 0, 0)
84 -DEF2(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END) 86 +DEF2(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
85 DEF2(mulu2_i32, 2, 2, 0, 0) 87 DEF2(mulu2_i32, 2, 2, 0, 0)
86 #endif 88 #endif
87 #ifdef TCG_TARGET_HAS_ext8s_i32 89 #ifdef TCG_TARGET_HAS_ext8s_i32
@@ -105,10 +107,10 @@ DEF2(ld16s_i64, 1, 1, 1, 0) @@ -105,10 +107,10 @@ DEF2(ld16s_i64, 1, 1, 1, 0)
105 DEF2(ld32u_i64, 1, 1, 1, 0) 107 DEF2(ld32u_i64, 1, 1, 1, 0)
106 DEF2(ld32s_i64, 1, 1, 1, 0) 108 DEF2(ld32s_i64, 1, 1, 1, 0)
107 DEF2(ld_i64, 1, 1, 1, 0) 109 DEF2(ld_i64, 1, 1, 1, 0)
108 -DEF2(st8_i64, 0, 2, 1, 0)  
109 -DEF2(st16_i64, 0, 2, 1, 0)  
110 -DEF2(st32_i64, 0, 2, 1, 0)  
111 -DEF2(st_i64, 0, 2, 1, 0) 110 +DEF2(st8_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
  111 +DEF2(st16_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
  112 +DEF2(st32_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
  113 +DEF2(st_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
112 /* arith */ 114 /* arith */
113 DEF2(add_i64, 1, 2, 0, 0) 115 DEF2(add_i64, 1, 2, 0, 0)
114 DEF2(sub_i64, 1, 2, 0, 0) 116 DEF2(sub_i64, 1, 2, 0, 0)
@@ -130,7 +132,7 @@ DEF2(shl_i64, 1, 2, 0, 0) @@ -130,7 +132,7 @@ DEF2(shl_i64, 1, 2, 0, 0)
130 DEF2(shr_i64, 1, 2, 0, 0) 132 DEF2(shr_i64, 1, 2, 0, 0)
131 DEF2(sar_i64, 1, 2, 0, 0) 133 DEF2(sar_i64, 1, 2, 0, 0)
132 134
133 -DEF2(brcond_i64, 0, 2, 2, TCG_OPF_BB_END) 135 +DEF2(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
134 #ifdef TCG_TARGET_HAS_ext8s_i64 136 #ifdef TCG_TARGET_HAS_ext8s_i64
135 DEF2(ext8s_i64, 1, 1, 0, 0) 137 DEF2(ext8s_i64, 1, 1, 0, 0)
136 #endif 138 #endif
@@ -146,82 +148,82 @@ DEF2(bswap_i64, 1, 1, 0, 0) @@ -146,82 +148,82 @@ DEF2(bswap_i64, 1, 1, 0, 0)
146 #endif 148 #endif
147 149
148 /* QEMU specific */ 150 /* QEMU specific */
149 -DEF2(exit_tb, 0, 0, 1, TCG_OPF_BB_END)  
150 -DEF2(goto_tb, 0, 0, 1, TCG_OPF_BB_END) 151 +DEF2(exit_tb, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
  152 +DEF2(goto_tb, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
151 /* Note: even if TARGET_LONG_BITS is not defined, the INDEX_op 153 /* Note: even if TARGET_LONG_BITS is not defined, the INDEX_op
152 constants must be defined */ 154 constants must be defined */
153 #if TCG_TARGET_REG_BITS == 32 155 #if TCG_TARGET_REG_BITS == 32
154 #if TARGET_LONG_BITS == 32 156 #if TARGET_LONG_BITS == 32
155 -DEF2(qemu_ld8u, 1, 1, 1, TCG_OPF_CALL_CLOBBER) 157 +DEF2(qemu_ld8u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
156 #else 158 #else
157 -DEF2(qemu_ld8u, 1, 2, 1, TCG_OPF_CALL_CLOBBER) 159 +DEF2(qemu_ld8u, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
158 #endif 160 #endif
159 #if TARGET_LONG_BITS == 32 161 #if TARGET_LONG_BITS == 32
160 -DEF2(qemu_ld8s, 1, 1, 1, TCG_OPF_CALL_CLOBBER) 162 +DEF2(qemu_ld8s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
161 #else 163 #else
162 -DEF2(qemu_ld8s, 1, 2, 1, TCG_OPF_CALL_CLOBBER) 164 +DEF2(qemu_ld8s, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
163 #endif 165 #endif
164 #if TARGET_LONG_BITS == 32 166 #if TARGET_LONG_BITS == 32
165 -DEF2(qemu_ld16u, 1, 1, 1, TCG_OPF_CALL_CLOBBER) 167 +DEF2(qemu_ld16u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
166 #else 168 #else
167 -DEF2(qemu_ld16u, 1, 2, 1, TCG_OPF_CALL_CLOBBER) 169 +DEF2(qemu_ld16u, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
168 #endif 170 #endif
169 #if TARGET_LONG_BITS == 32 171 #if TARGET_LONG_BITS == 32
170 -DEF2(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER) 172 +DEF2(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
171 #else 173 #else
172 -DEF2(qemu_ld16s, 1, 2, 1, TCG_OPF_CALL_CLOBBER) 174 +DEF2(qemu_ld16s, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
173 #endif 175 #endif
174 #if TARGET_LONG_BITS == 32 176 #if TARGET_LONG_BITS == 32
175 -DEF2(qemu_ld32u, 1, 1, 1, TCG_OPF_CALL_CLOBBER) 177 +DEF2(qemu_ld32u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
176 #else 178 #else
177 -DEF2(qemu_ld32u, 1, 2, 1, TCG_OPF_CALL_CLOBBER) 179 +DEF2(qemu_ld32u, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
178 #endif 180 #endif
179 #if TARGET_LONG_BITS == 32 181 #if TARGET_LONG_BITS == 32
180 -DEF2(qemu_ld32s, 1, 1, 1, TCG_OPF_CALL_CLOBBER) 182 +DEF2(qemu_ld32s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
181 #else 183 #else
182 -DEF2(qemu_ld32s, 1, 2, 1, TCG_OPF_CALL_CLOBBER) 184 +DEF2(qemu_ld32s, 1, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
183 #endif 185 #endif
184 #if TARGET_LONG_BITS == 32 186 #if TARGET_LONG_BITS == 32
185 -DEF2(qemu_ld64, 2, 1, 1, TCG_OPF_CALL_CLOBBER) 187 +DEF2(qemu_ld64, 2, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
186 #else 188 #else
187 -DEF2(qemu_ld64, 2, 2, 1, TCG_OPF_CALL_CLOBBER) 189 +DEF2(qemu_ld64, 2, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
188 #endif 190 #endif
189 191
190 #if TARGET_LONG_BITS == 32 192 #if TARGET_LONG_BITS == 32
191 -DEF2(qemu_st8, 0, 2, 1, TCG_OPF_CALL_CLOBBER) 193 +DEF2(qemu_st8, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
192 #else 194 #else
193 -DEF2(qemu_st8, 0, 3, 1, TCG_OPF_CALL_CLOBBER) 195 +DEF2(qemu_st8, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
194 #endif 196 #endif
195 #if TARGET_LONG_BITS == 32 197 #if TARGET_LONG_BITS == 32
196 -DEF2(qemu_st16, 0, 2, 1, TCG_OPF_CALL_CLOBBER) 198 +DEF2(qemu_st16, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
197 #else 199 #else
198 -DEF2(qemu_st16, 0, 3, 1, TCG_OPF_CALL_CLOBBER) 200 +DEF2(qemu_st16, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
199 #endif 201 #endif
200 #if TARGET_LONG_BITS == 32 202 #if TARGET_LONG_BITS == 32
201 -DEF2(qemu_st32, 0, 2, 1, TCG_OPF_CALL_CLOBBER) 203 +DEF2(qemu_st32, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
202 #else 204 #else
203 -DEF2(qemu_st32, 0, 3, 1, TCG_OPF_CALL_CLOBBER) 205 +DEF2(qemu_st32, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
204 #endif 206 #endif
205 #if TARGET_LONG_BITS == 32 207 #if TARGET_LONG_BITS == 32
206 -DEF2(qemu_st64, 0, 3, 1, TCG_OPF_CALL_CLOBBER) 208 +DEF2(qemu_st64, 0, 3, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
207 #else 209 #else
208 -DEF2(qemu_st64, 0, 4, 1, TCG_OPF_CALL_CLOBBER) 210 +DEF2(qemu_st64, 0, 4, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
209 #endif 211 #endif
210 212
211 #else /* TCG_TARGET_REG_BITS == 32 */ 213 #else /* TCG_TARGET_REG_BITS == 32 */
212 214
213 -DEF2(qemu_ld8u, 1, 1, 1, TCG_OPF_CALL_CLOBBER)  
214 -DEF2(qemu_ld8s, 1, 1, 1, TCG_OPF_CALL_CLOBBER)  
215 -DEF2(qemu_ld16u, 1, 1, 1, TCG_OPF_CALL_CLOBBER)  
216 -DEF2(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER)  
217 -DEF2(qemu_ld32u, 1, 1, 1, TCG_OPF_CALL_CLOBBER)  
218 -DEF2(qemu_ld32s, 1, 1, 1, TCG_OPF_CALL_CLOBBER)  
219 -DEF2(qemu_ld64, 1, 1, 1, TCG_OPF_CALL_CLOBBER) 215 +DEF2(qemu_ld8u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
  216 +DEF2(qemu_ld8s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
  217 +DEF2(qemu_ld16u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
  218 +DEF2(qemu_ld16s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
  219 +DEF2(qemu_ld32u, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
  220 +DEF2(qemu_ld32s, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
  221 +DEF2(qemu_ld64, 1, 1, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
220 222
221 -DEF2(qemu_st8, 0, 2, 1, TCG_OPF_CALL_CLOBBER)  
222 -DEF2(qemu_st16, 0, 2, 1, TCG_OPF_CALL_CLOBBER)  
223 -DEF2(qemu_st32, 0, 2, 1, TCG_OPF_CALL_CLOBBER)  
224 -DEF2(qemu_st64, 0, 2, 1, TCG_OPF_CALL_CLOBBER) 223 +DEF2(qemu_st8, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
  224 +DEF2(qemu_st16, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
  225 +DEF2(qemu_st32, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
  226 +DEF2(qemu_st64, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
225 227
226 #endif /* TCG_TARGET_REG_BITS != 32 */ 228 #endif /* TCG_TARGET_REG_BITS != 32 */
227 229
tcg/tcg.c
@@ -401,6 +401,7 @@ TCGv tcg_temp_new(TCGType type) @@ -401,6 +401,7 @@ TCGv tcg_temp_new(TCGType type)
401 ts = &s->temps[s->nb_temps]; 401 ts = &s->temps[s->nb_temps];
402 ts->base_type = type; 402 ts->base_type = type;
403 ts->type = TCG_TYPE_I32; 403 ts->type = TCG_TYPE_I32;
  404 + ts->fixed_reg = 0;
404 ts->val_type = TEMP_VAL_DEAD; 405 ts->val_type = TEMP_VAL_DEAD;
405 ts->mem_allocated = 0; 406 ts->mem_allocated = 0;
406 ts->name = NULL; 407 ts->name = NULL;
@@ -408,6 +409,7 @@ TCGv tcg_temp_new(TCGType type) @@ -408,6 +409,7 @@ TCGv tcg_temp_new(TCGType type)
408 ts->base_type = TCG_TYPE_I32; 409 ts->base_type = TCG_TYPE_I32;
409 ts->type = TCG_TYPE_I32; 410 ts->type = TCG_TYPE_I32;
410 ts->val_type = TEMP_VAL_DEAD; 411 ts->val_type = TEMP_VAL_DEAD;
  412 + ts->fixed_reg = 0;
411 ts->mem_allocated = 0; 413 ts->mem_allocated = 0;
412 ts->name = NULL; 414 ts->name = NULL;
413 s->nb_temps += 2; 415 s->nb_temps += 2;
@@ -418,6 +420,7 @@ TCGv tcg_temp_new(TCGType type) @@ -418,6 +420,7 @@ TCGv tcg_temp_new(TCGType type)
418 ts = &s->temps[s->nb_temps]; 420 ts = &s->temps[s->nb_temps];
419 ts->base_type = type; 421 ts->base_type = type;
420 ts->type = type; 422 ts->type = type;
  423 + ts->fixed_reg = 0;
421 ts->val_type = TEMP_VAL_DEAD; 424 ts->val_type = TEMP_VAL_DEAD;
422 ts->mem_allocated = 0; 425 ts->mem_allocated = 0;
423 ts->name = NULL; 426 ts->name = NULL;
@@ -805,11 +808,12 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs) @@ -805,11 +808,12 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
805 assert(oarg < def->nb_oargs); 808 assert(oarg < def->nb_oargs);
806 assert(def->args_ct[oarg].ct & TCG_CT_REG); 809 assert(def->args_ct[oarg].ct & TCG_CT_REG);
807 /* TCG_CT_ALIAS is for the output arguments. The input 810 /* TCG_CT_ALIAS is for the output arguments. The input
808 - argument is tagged with TCG_CT_IALIAS for  
809 - informative purposes. */ 811 + argument is tagged with TCG_CT_IALIAS. */
810 def->args_ct[i] = def->args_ct[oarg]; 812 def->args_ct[i] = def->args_ct[oarg];
811 - def->args_ct[oarg].ct = i | TCG_CT_ALIAS; 813 + def->args_ct[oarg].ct = TCG_CT_ALIAS;
  814 + def->args_ct[oarg].alias_index = i;
812 def->args_ct[i].ct |= TCG_CT_IALIAS; 815 def->args_ct[i].ct |= TCG_CT_IALIAS;
  816 + def->args_ct[i].alias_index = oarg;
813 } else { 817 } else {
814 for(;;) { 818 for(;;) {
815 if (*ct_str == '\0') 819 if (*ct_str == '\0')
@@ -935,6 +939,11 @@ void tcg_liveness_analysis(TCGContext *s) @@ -935,6 +939,11 @@ void tcg_liveness_analysis(TCGContext *s)
935 nb_args = args[-1]; 939 nb_args = args[-1];
936 args -= nb_args; 940 args -= nb_args;
937 break; 941 break;
  942 + case INDEX_op_discard:
  943 + args--;
  944 + /* mark the temporary as dead */
  945 + dead_temps[args[0]] = 1;
  946 + break;
938 case INDEX_op_macro_2: 947 case INDEX_op_macro_2:
939 { 948 {
940 int dead_args[2], macro_id; 949 int dead_args[2], macro_id;
@@ -1015,12 +1024,9 @@ void tcg_liveness_analysis(TCGContext *s) @@ -1015,12 +1024,9 @@ void tcg_liveness_analysis(TCGContext *s)
1015 nb_oargs = def->nb_oargs; 1024 nb_oargs = def->nb_oargs;
1016 1025
1017 /* Test if the operation can be removed because all 1026 /* Test if the operation can be removed because all
1018 - its outputs are dead. We may add a flag to  
1019 - explicitely tell if the op has side  
1020 - effects. Currently we assume that if nb_oargs == 0  
1021 - or OPF_BB_END is set, the operation has side  
1022 - effects and cannot be removed */  
1023 - if (nb_oargs != 0 && !(def->flags & TCG_OPF_BB_END)) { 1027 + its outputs are dead. We assume that nb_oargs == 0
  1028 + implies side effects */
  1029 + if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
1024 for(i = 0; i < nb_oargs; i++) { 1030 for(i = 0; i < nb_oargs; i++) {
1025 arg = args[i]; 1031 arg = args[i];
1026 if (!dead_temps[arg]) 1032 if (!dead_temps[arg])
@@ -1164,7 +1170,7 @@ static void temp_allocate_frame(TCGContext *s, int temp) @@ -1164,7 +1170,7 @@ static void temp_allocate_frame(TCGContext *s, int temp)
1164 ts = &s->temps[temp]; 1170 ts = &s->temps[temp];
1165 s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1); 1171 s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1);
1166 if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end) 1172 if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
1167 - abort(); 1173 + tcg_abort();
1168 ts->mem_offset = s->current_frame_offset; 1174 ts->mem_offset = s->current_frame_offset;
1169 ts->mem_reg = s->frame_reg; 1175 ts->mem_reg = s->frame_reg;
1170 ts->mem_allocated = 1; 1176 ts->mem_allocated = 1;
@@ -1350,12 +1356,19 @@ static void tcg_reg_alloc_op(TCGContext *s, @@ -1350,12 +1356,19 @@ static void tcg_reg_alloc_op(TCGContext *s,
1350 } 1356 }
1351 } 1357 }
1352 assert(ts->val_type == TEMP_VAL_REG); 1358 assert(ts->val_type == TEMP_VAL_REG);
1353 - if ((arg_ct->ct & TCG_CT_IALIAS) &&  
1354 - !IS_DEAD_IARG(i - nb_oargs)) {  
1355 - /* if the input is aliased to an output and if it is  
1356 - not dead after the instruction, we must allocate  
1357 - a new register and move it */  
1358 - goto allocate_in_reg; 1359 + if (arg_ct->ct & TCG_CT_IALIAS) {
  1360 + if (ts->fixed_reg) {
  1361 + /* if fixed register, we must allocate a new register
  1362 + if the alias is not the same register */
  1363 + if (arg != args[arg_ct->alias_index])
  1364 + goto allocate_in_reg;
  1365 + } else {
  1366 + /* if the input is aliased to an output and if it is
  1367 + not dead after the instruction, we must allocate
  1368 + a new register and move it */
  1369 + if (!IS_DEAD_IARG(i - nb_oargs))
  1370 + goto allocate_in_reg;
  1371 + }
1359 } 1372 }
1360 reg = ts->reg; 1373 reg = ts->reg;
1361 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) { 1374 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
@@ -1404,7 +1417,7 @@ static void tcg_reg_alloc_op(TCGContext *s, @@ -1404,7 +1417,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
1404 arg_ct = &def->args_ct[i]; 1417 arg_ct = &def->args_ct[i];
1405 ts = &s->temps[arg]; 1418 ts = &s->temps[arg];
1406 if (arg_ct->ct & TCG_CT_ALIAS) { 1419 if (arg_ct->ct & TCG_CT_ALIAS) {
1407 - reg = new_args[arg_ct->ct & ~TCG_CT_ALIAS]; 1420 + reg = new_args[arg_ct->alias_index];
1408 } else { 1421 } else {
1409 /* if fixed register, we try to use it */ 1422 /* if fixed register, we try to use it */
1410 reg = ts->reg; 1423 reg = ts->reg;
@@ -1694,6 +1707,18 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, @@ -1694,6 +1707,18 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
1694 case INDEX_op_nopn: 1707 case INDEX_op_nopn:
1695 args += args[0]; 1708 args += args[0];
1696 goto next; 1709 goto next;
  1710 + case INDEX_op_discard:
  1711 + {
  1712 + TCGTemp *ts;
  1713 + ts = &s->temps[args[0]];
  1714 + /* mark the temporary as dead */
  1715 + if (ts->val_type != TEMP_VAL_CONST && !ts->fixed_reg) {
  1716 + if (ts->val_type == TEMP_VAL_REG)
  1717 + s->reg_to_temp[ts->reg] = -1;
  1718 + ts->val_type = TEMP_VAL_DEAD;
  1719 + }
  1720 + }
  1721 + break;
1697 case INDEX_op_macro_goto: 1722 case INDEX_op_macro_goto:
1698 macro_op_index = op_index; /* only used for exceptions */ 1723 macro_op_index = op_index; /* only used for exceptions */
1699 op_index = args[0] - 1; 1724 op_index = args[0] - 1;
tcg/tcg.h
@@ -275,7 +275,8 @@ char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg); @@ -275,7 +275,8 @@ char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg);
275 #define TCG_CT_CONST 0x02 /* any constant of register size */ 275 #define TCG_CT_CONST 0x02 /* any constant of register size */
276 276
277 typedef struct TCGArgConstraint { 277 typedef struct TCGArgConstraint {
278 - uint32_t ct; 278 + uint16_t ct;
  279 + uint8_t alias_index;
279 union { 280 union {
280 TCGRegSet regs; 281 TCGRegSet regs;
281 } u; 282 } u;
@@ -286,6 +287,7 @@ typedef struct TCGArgConstraint { @@ -286,6 +287,7 @@ typedef struct TCGArgConstraint {
286 #define TCG_OPF_BB_END 0x01 /* instruction defines the end of a basic 287 #define TCG_OPF_BB_END 0x01 /* instruction defines the end of a basic
287 block */ 288 block */
288 #define TCG_OPF_CALL_CLOBBER 0x02 /* instruction clobbers call registers */ 289 #define TCG_OPF_CALL_CLOBBER 0x02 /* instruction clobbers call registers */
  290 +#define TCG_OPF_SIDE_EFFECTS 0x04 /* instruction has side effects */
289 291
290 typedef struct TCGOpDef { 292 typedef struct TCGOpDef {
291 const char *name; 293 const char *name;