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 280  
281 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 288 ********* Type conversions
284 289  
285 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 865 tcg_gen_op2(INDEX_op_ext8s_i32, ret, arg);
866 866 #else
867 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 869 #endif
870 870 }
871 871  
... ... @@ -875,7 +875,7 @@ static inline void tcg_gen_ext16s_i32(TCGv ret, TCGv arg)
875 875 tcg_gen_op2(INDEX_op_ext16s_i32, ret, arg);
876 876 #else
877 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 879 #endif
880 880 }
881 881  
... ... @@ -975,7 +975,7 @@ static inline void tcg_gen_ext8s_i64(TCGv ret, TCGv arg)
975 975 tcg_gen_op2(INDEX_op_ext8s_i64, ret, arg);
976 976 #else
977 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 979 #endif
980 980 }
981 981  
... ... @@ -985,7 +985,7 @@ static inline void tcg_gen_ext16s_i64(TCGv ret, TCGv arg)
985 985 tcg_gen_op2(INDEX_op_ext16s_i64, ret, arg);
986 986 #else
987 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 989 #endif
990 990 }
991 991  
... ... @@ -995,7 +995,7 @@ static inline void tcg_gen_ext32s_i64(TCGv ret, TCGv arg)
995 995 tcg_gen_op2(INDEX_op_ext32s_i64, ret, arg);
996 996 #else
997 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 999 #endif
1000 1000 }
1001 1001  
... ... @@ -1062,6 +1062,25 @@ static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg)
1062 1062  
1063 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 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 40 DEF2(macro_end, 0, 0, 2, 0)
41 41 DEF2(macro_goto, 0, 0, 3, 0)
42 42  
  43 +DEF2(discard, 1, 0, 0, 0)
  44 +
43 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 50 DEF2(mov_i32, 1, 1, 0, 0)
49 51 DEF2(movi_i32, 1, 0, 1, 0)
... ... @@ -53,9 +55,9 @@ DEF2(ld8s_i32, 1, 1, 1, 0)
53 55 DEF2(ld16u_i32, 1, 1, 1, 0)
54 56 DEF2(ld16s_i32, 1, 1, 1, 0)
55 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 61 /* arith */
60 62 DEF2(add_i32, 1, 2, 0, 0)
61 63 DEF2(sub_i32, 1, 2, 0, 0)
... ... @@ -77,11 +79,11 @@ DEF2(shl_i32, 1, 2, 0, 0)
77 79 DEF2(shr_i32, 1, 2, 0, 0)
78 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 83 #if TCG_TARGET_REG_BITS == 32
82 84 DEF2(add2_i32, 2, 4, 0, 0)
83 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 87 DEF2(mulu2_i32, 2, 2, 0, 0)
86 88 #endif
87 89 #ifdef TCG_TARGET_HAS_ext8s_i32
... ... @@ -105,10 +107,10 @@ DEF2(ld16s_i64, 1, 1, 1, 0)
105 107 DEF2(ld32u_i64, 1, 1, 1, 0)
106 108 DEF2(ld32s_i64, 1, 1, 1, 0)
107 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 114 /* arith */
113 115 DEF2(add_i64, 1, 2, 0, 0)
114 116 DEF2(sub_i64, 1, 2, 0, 0)
... ... @@ -130,7 +132,7 @@ DEF2(shl_i64, 1, 2, 0, 0)
130 132 DEF2(shr_i64, 1, 2, 0, 0)
131 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 136 #ifdef TCG_TARGET_HAS_ext8s_i64
135 137 DEF2(ext8s_i64, 1, 1, 0, 0)
136 138 #endif
... ... @@ -146,82 +148,82 @@ DEF2(bswap_i64, 1, 1, 0, 0)
146 148 #endif
147 149  
148 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 153 /* Note: even if TARGET_LONG_BITS is not defined, the INDEX_op
152 154 constants must be defined */
153 155 #if TCG_TARGET_REG_BITS == 32
154 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 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 160 #endif
159 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 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 165 #endif
164 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 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 170 #endif
169 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 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 175 #endif
174 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 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 180 #endif
179 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 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 185 #endif
184 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 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 190 #endif
189 191  
190 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 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 196 #endif
195 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 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 201 #endif
200 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 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 206 #endif
205 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 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 211 #endif
210 212  
211 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 228 #endif /* TCG_TARGET_REG_BITS != 32 */
227 229  
... ...
tcg/tcg.c
... ... @@ -401,6 +401,7 @@ TCGv tcg_temp_new(TCGType type)
401 401 ts = &s->temps[s->nb_temps];
402 402 ts->base_type = type;
403 403 ts->type = TCG_TYPE_I32;
  404 + ts->fixed_reg = 0;
404 405 ts->val_type = TEMP_VAL_DEAD;
405 406 ts->mem_allocated = 0;
406 407 ts->name = NULL;
... ... @@ -408,6 +409,7 @@ TCGv tcg_temp_new(TCGType type)
408 409 ts->base_type = TCG_TYPE_I32;
409 410 ts->type = TCG_TYPE_I32;
410 411 ts->val_type = TEMP_VAL_DEAD;
  412 + ts->fixed_reg = 0;
411 413 ts->mem_allocated = 0;
412 414 ts->name = NULL;
413 415 s->nb_temps += 2;
... ... @@ -418,6 +420,7 @@ TCGv tcg_temp_new(TCGType type)
418 420 ts = &s->temps[s->nb_temps];
419 421 ts->base_type = type;
420 422 ts->type = type;
  423 + ts->fixed_reg = 0;
421 424 ts->val_type = TEMP_VAL_DEAD;
422 425 ts->mem_allocated = 0;
423 426 ts->name = NULL;
... ... @@ -805,11 +808,12 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
805 808 assert(oarg < def->nb_oargs);
806 809 assert(def->args_ct[oarg].ct & TCG_CT_REG);
807 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 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 815 def->args_ct[i].ct |= TCG_CT_IALIAS;
  816 + def->args_ct[i].alias_index = oarg;
813 817 } else {
814 818 for(;;) {
815 819 if (*ct_str == '\0')
... ... @@ -935,6 +939,11 @@ void tcg_liveness_analysis(TCGContext *s)
935 939 nb_args = args[-1];
936 940 args -= nb_args;
937 941 break;
  942 + case INDEX_op_discard:
  943 + args--;
  944 + /* mark the temporary as dead */
  945 + dead_temps[args[0]] = 1;
  946 + break;
938 947 case INDEX_op_macro_2:
939 948 {
940 949 int dead_args[2], macro_id;
... ... @@ -1015,12 +1024,9 @@ void tcg_liveness_analysis(TCGContext *s)
1015 1024 nb_oargs = def->nb_oargs;
1016 1025  
1017 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 1030 for(i = 0; i < nb_oargs; i++) {
1025 1031 arg = args[i];
1026 1032 if (!dead_temps[arg])
... ... @@ -1164,7 +1170,7 @@ static void temp_allocate_frame(TCGContext *s, int temp)
1164 1170 ts = &s->temps[temp];
1165 1171 s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1);
1166 1172 if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
1167   - abort();
  1173 + tcg_abort();
1168 1174 ts->mem_offset = s->current_frame_offset;
1169 1175 ts->mem_reg = s->frame_reg;
1170 1176 ts->mem_allocated = 1;
... ... @@ -1350,12 +1356,19 @@ static void tcg_reg_alloc_op(TCGContext *s,
1350 1356 }
1351 1357 }
1352 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 1373 reg = ts->reg;
1361 1374 if (tcg_regset_test_reg(arg_ct->u.regs, reg)) {
... ... @@ -1404,7 +1417,7 @@ static void tcg_reg_alloc_op(TCGContext *s,
1404 1417 arg_ct = &def->args_ct[i];
1405 1418 ts = &s->temps[arg];
1406 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 1421 } else {
1409 1422 /* if fixed register, we try to use it */
1410 1423 reg = ts->reg;
... ... @@ -1694,6 +1707,18 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
1694 1707 case INDEX_op_nopn:
1695 1708 args += args[0];
1696 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 1722 case INDEX_op_macro_goto:
1698 1723 macro_op_index = op_index; /* only used for exceptions */
1699 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 275 #define TCG_CT_CONST 0x02 /* any constant of register size */
276 276  
277 277 typedef struct TCGArgConstraint {
278   - uint32_t ct;
  278 + uint16_t ct;
  279 + uint8_t alias_index;
279 280 union {
280 281 TCGRegSet regs;
281 282 } u;
... ... @@ -286,6 +287,7 @@ typedef struct TCGArgConstraint {
286 287 #define TCG_OPF_BB_END 0x01 /* instruction defines the end of a basic
287 288 block */
288 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 292 typedef struct TCGOpDef {
291 293 const char *name;
... ...