Commit e8996ee012e957cf8456d41ee6a7bbaf1f9b888b

Authored by bellard
1 parent d7e4036e

added tcg_temp_free() and improved the handling of constants

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4544 c046a42c-6fe2-441c-8c8c-71466251a162
tcg/tcg-op.h
... ... @@ -178,88 +178,115 @@ static inline void tcg_gen_movi_i32(TCGv ret, int32_t arg)
178 178  
179 179 static inline void tcg_gen_helper_0_0(void *func)
180 180 {
  181 + TCGv t0;
  182 + t0 = tcg_const_ptr((tcg_target_long)func);
181 183 tcg_gen_call(&tcg_ctx,
182   - tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
  184 + t0, TCG_HELPER_CALL_FLAGS,
183 185 0, NULL, 0, NULL);
  186 + tcg_temp_free(t0);
184 187 }
185 188  
186 189 static inline void tcg_gen_helper_0_1(void *func, TCGv arg)
187 190 {
  191 + TCGv t0;
  192 + t0 = tcg_const_ptr((tcg_target_long)func);
188 193 tcg_gen_call(&tcg_ctx,
189   - tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
  194 + t0, TCG_HELPER_CALL_FLAGS,
190 195 0, NULL, 1, &arg);
  196 + tcg_temp_free(t0);
191 197 }
192 198  
193 199 static inline void tcg_gen_helper_0_2(void *func, TCGv arg1, TCGv arg2)
194 200 {
195 201 TCGv args[2];
  202 + TCGv t0;
196 203 args[0] = arg1;
197 204 args[1] = arg2;
  205 + t0 = tcg_const_ptr((tcg_target_long)func);
198 206 tcg_gen_call(&tcg_ctx,
199   - tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
  207 + t0, TCG_HELPER_CALL_FLAGS,
200 208 0, NULL, 2, args);
  209 + tcg_temp_free(t0);
201 210 }
202 211  
203 212 static inline void tcg_gen_helper_0_3(void *func,
204 213 TCGv arg1, TCGv arg2, TCGv arg3)
205 214 {
206 215 TCGv args[3];
  216 + TCGv t0;
207 217 args[0] = arg1;
208 218 args[1] = arg2;
209 219 args[2] = arg3;
  220 + t0 = tcg_const_ptr((tcg_target_long)func);
210 221 tcg_gen_call(&tcg_ctx,
211   - tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
  222 + t0, TCG_HELPER_CALL_FLAGS,
212 223 0, NULL, 3, args);
  224 + tcg_temp_free(t0);
213 225 }
214 226  
215 227 static inline void tcg_gen_helper_0_4(void *func, TCGv arg1, TCGv arg2,
216 228 TCGv arg3, TCGv arg4)
217 229 {
218 230 TCGv args[4];
  231 + TCGv t0;
219 232 args[0] = arg1;
220 233 args[1] = arg2;
221 234 args[2] = arg3;
222 235 args[3] = arg4;
  236 + t0 = tcg_const_ptr((tcg_target_long)func);
223 237 tcg_gen_call(&tcg_ctx,
224   - tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
  238 + t0, TCG_HELPER_CALL_FLAGS,
225 239 0, NULL, 4, args);
  240 + tcg_temp_free(t0);
226 241 }
227 242  
228 243 static inline void tcg_gen_helper_1_0(void *func, TCGv ret)
229 244 {
  245 + TCGv t0;
  246 + t0 = tcg_const_ptr((tcg_target_long)func);
230 247 tcg_gen_call(&tcg_ctx,
231   - tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
  248 + t0, TCG_HELPER_CALL_FLAGS,
232 249 1, &ret, 0, NULL);
  250 + tcg_temp_free(t0);
233 251 }
234 252  
235 253 static inline void tcg_gen_helper_1_1(void *func, TCGv ret, TCGv arg1)
236 254 {
  255 + TCGv t0;
  256 + t0 = tcg_const_ptr((tcg_target_long)func);
237 257 tcg_gen_call(&tcg_ctx,
238   - tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
  258 + t0, TCG_HELPER_CALL_FLAGS,
239 259 1, &ret, 1, &arg1);
  260 + tcg_temp_free(t0);
240 261 }
241 262  
242 263 static inline void tcg_gen_helper_1_2(void *func, TCGv ret,
243 264 TCGv arg1, TCGv arg2)
244 265 {
245 266 TCGv args[2];
  267 + TCGv t0;
246 268 args[0] = arg1;
247 269 args[1] = arg2;
  270 + t0 = tcg_const_ptr((tcg_target_long)func);
248 271 tcg_gen_call(&tcg_ctx,
249   - tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
  272 + t0, TCG_HELPER_CALL_FLAGS,
250 273 1, &ret, 2, args);
  274 + tcg_temp_free(t0);
251 275 }
252 276  
253 277 static inline void tcg_gen_helper_1_3(void *func, TCGv ret,
254 278 TCGv arg1, TCGv arg2, TCGv arg3)
255 279 {
256 280 TCGv args[3];
  281 + TCGv t0;
257 282 args[0] = arg1;
258 283 args[1] = arg2;
259 284 args[2] = arg3;
  285 + t0 = tcg_const_ptr((tcg_target_long)func);
260 286 tcg_gen_call(&tcg_ctx,
261   - tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
  287 + t0, TCG_HELPER_CALL_FLAGS,
262 288 1, &ret, 3, args);
  289 + tcg_temp_free(t0);
263 290 }
264 291  
265 292 static inline void tcg_gen_helper_1_4(void *func, TCGv ret,
... ... @@ -267,13 +294,16 @@ static inline void tcg_gen_helper_1_4(void *func, TCGv ret,
267 294 TCGv arg4)
268 295 {
269 296 TCGv args[4];
  297 + TCGv t0;
270 298 args[0] = arg1;
271 299 args[1] = arg2;
272 300 args[2] = arg3;
273 301 args[3] = arg4;
  302 + t0 = tcg_const_ptr((tcg_target_long)func);
274 303 tcg_gen_call(&tcg_ctx,
275   - tcg_const_ptr((tcg_target_long)func), TCG_HELPER_CALL_FLAGS,
  304 + t0, TCG_HELPER_CALL_FLAGS,
276 305 1, &ret, 4, args);
  306 + tcg_temp_free(t0);
277 307 }
278 308  
279 309 /* 32 bit ops */
... ... @@ -329,7 +359,9 @@ static inline void tcg_gen_addi_i32(TCGv ret, TCGv arg1, int32_t arg2)
329 359 if (arg2 == 0) {
330 360 tcg_gen_mov_i32(ret, arg1);
331 361 } else {
332   - tcg_gen_add_i32(ret, arg1, tcg_const_i32(arg2));
  362 + TCGv t0 = tcg_const_i32(arg2);
  363 + tcg_gen_add_i32(ret, arg1, t0);
  364 + tcg_temp_free(t0);
333 365 }
334 366 }
335 367  
... ... @@ -344,7 +376,9 @@ static inline void tcg_gen_subi_i32(TCGv ret, TCGv arg1, int32_t arg2)
344 376 if (arg2 == 0) {
345 377 tcg_gen_mov_i32(ret, arg1);
346 378 } else {
347   - tcg_gen_sub_i32(ret, arg1, tcg_const_i32(arg2));
  379 + TCGv t0 = tcg_const_i32(arg2);
  380 + tcg_gen_sub_i32(ret, arg1, t0);
  381 + tcg_temp_free(t0);
348 382 }
349 383 }
350 384  
... ... @@ -361,7 +395,9 @@ static inline void tcg_gen_andi_i32(TCGv ret, TCGv arg1, int32_t arg2)
361 395 } else if (arg2 == 0xffffffff) {
362 396 tcg_gen_mov_i32(ret, arg1);
363 397 } else {
364   - tcg_gen_and_i32(ret, arg1, tcg_const_i32(arg2));
  398 + TCGv t0 = tcg_const_i32(arg2);
  399 + tcg_gen_and_i32(ret, arg1, t0);
  400 + tcg_temp_free(t0);
365 401 }
366 402 }
367 403  
... ... @@ -378,7 +414,9 @@ static inline void tcg_gen_ori_i32(TCGv ret, TCGv arg1, int32_t arg2)
378 414 } else if (arg2 == 0) {
379 415 tcg_gen_mov_i32(ret, arg1);
380 416 } else {
381   - tcg_gen_or_i32(ret, arg1, tcg_const_i32(arg2));
  417 + TCGv t0 = tcg_const_i32(arg2);
  418 + tcg_gen_or_i32(ret, arg1, t0);
  419 + tcg_temp_free(t0);
382 420 }
383 421 }
384 422  
... ... @@ -393,7 +431,9 @@ static inline void tcg_gen_xori_i32(TCGv ret, TCGv arg1, int32_t arg2)
393 431 if (arg2 == 0) {
394 432 tcg_gen_mov_i32(ret, arg1);
395 433 } else {
396   - tcg_gen_xor_i32(ret, arg1, tcg_const_i32(arg2));
  434 + TCGv t0 = tcg_const_i32(arg2);
  435 + tcg_gen_xor_i32(ret, arg1, t0);
  436 + tcg_temp_free(t0);
397 437 }
398 438 }
399 439  
... ... @@ -407,7 +447,9 @@ static inline void tcg_gen_shli_i32(TCGv ret, TCGv arg1, int32_t arg2)
407 447 if (arg2 == 0) {
408 448 tcg_gen_mov_i32(ret, arg1);
409 449 } else {
410   - tcg_gen_shl_i32(ret, arg1, tcg_const_i32(arg2));
  450 + TCGv t0 = tcg_const_i32(arg2);
  451 + tcg_gen_shl_i32(ret, arg1, t0);
  452 + tcg_temp_free(t0);
411 453 }
412 454 }
413 455  
... ... @@ -421,7 +463,9 @@ static inline void tcg_gen_shri_i32(TCGv ret, TCGv arg1, int32_t arg2)
421 463 if (arg2 == 0) {
422 464 tcg_gen_mov_i32(ret, arg1);
423 465 } else {
424   - tcg_gen_shr_i32(ret, arg1, tcg_const_i32(arg2));
  466 + TCGv t0 = tcg_const_i32(arg2);
  467 + tcg_gen_shr_i32(ret, arg1, t0);
  468 + tcg_temp_free(t0);
425 469 }
426 470 }
427 471  
... ... @@ -435,7 +479,9 @@ static inline void tcg_gen_sari_i32(TCGv ret, TCGv arg1, int32_t arg2)
435 479 if (arg2 == 0) {
436 480 tcg_gen_mov_i32(ret, arg1);
437 481 } else {
438   - tcg_gen_sar_i32(ret, arg1, tcg_const_i32(arg2));
  482 + TCGv t0 = tcg_const_i32(arg2);
  483 + tcg_gen_sar_i32(ret, arg1, t0);
  484 + tcg_temp_free(t0);
439 485 }
440 486 }
441 487  
... ... @@ -452,7 +498,9 @@ static inline void tcg_gen_mul_i32(TCGv ret, TCGv arg1, TCGv arg2)
452 498  
453 499 static inline void tcg_gen_muli_i32(TCGv ret, TCGv arg1, int32_t arg2)
454 500 {
455   - tcg_gen_mul_i32(ret, arg1, tcg_const_i32(arg2));
  501 + TCGv t0 = tcg_const_i32(arg2);
  502 + tcg_gen_mul_i32(ret, arg1, t0);
  503 + tcg_temp_free(t0);
456 504 }
457 505  
458 506 #ifdef TCG_TARGET_HAS_div_i32
... ... @@ -482,6 +530,7 @@ static inline void tcg_gen_div_i32(TCGv ret, TCGv arg1, TCGv arg2)
482 530 t0 = tcg_temp_new(TCG_TYPE_I32);
483 531 tcg_gen_sari_i32(t0, arg1, 31);
484 532 tcg_gen_op5(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
  533 + tcg_temp_free(t0);
485 534 }
486 535  
487 536 static inline void tcg_gen_rem_i32(TCGv ret, TCGv arg1, TCGv arg2)
... ... @@ -490,6 +539,7 @@ static inline void tcg_gen_rem_i32(TCGv ret, TCGv arg1, TCGv arg2)
490 539 t0 = tcg_temp_new(TCG_TYPE_I32);
491 540 tcg_gen_sari_i32(t0, arg1, 31);
492 541 tcg_gen_op5(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
  542 + tcg_temp_free(t0);
493 543 }
494 544  
495 545 static inline void tcg_gen_divu_i32(TCGv ret, TCGv arg1, TCGv arg2)
... ... @@ -498,6 +548,7 @@ static inline void tcg_gen_divu_i32(TCGv ret, TCGv arg1, TCGv arg2)
498 548 t0 = tcg_temp_new(TCG_TYPE_I32);
499 549 tcg_gen_movi_i32(t0, 0);
500 550 tcg_gen_op5(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2);
  551 + tcg_temp_free(t0);
501 552 }
502 553  
503 554 static inline void tcg_gen_remu_i32(TCGv ret, TCGv arg1, TCGv arg2)
... ... @@ -506,6 +557,7 @@ static inline void tcg_gen_remu_i32(TCGv ret, TCGv arg1, TCGv arg2)
506 557 t0 = tcg_temp_new(TCG_TYPE_I32);
507 558 tcg_gen_movi_i32(t0, 0);
508 559 tcg_gen_op5(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2);
  560 + tcg_temp_free(t0);
509 561 }
510 562 #endif
511 563  
... ... @@ -608,7 +660,9 @@ static inline void tcg_gen_add_i64(TCGv ret, TCGv arg1, TCGv arg2)
608 660  
609 661 static inline void tcg_gen_addi_i64(TCGv ret, TCGv arg1, int64_t arg2)
610 662 {
611   - tcg_gen_add_i64(ret, arg1, tcg_const_i64(arg2));
  663 + TCGv t0 = tcg_const_i64(arg2);
  664 + tcg_gen_add_i64(ret, arg1, t0);
  665 + tcg_temp_free(t0);
612 666 }
613 667  
614 668 static inline void tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2)
... ... @@ -619,7 +673,9 @@ static inline void tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2)
619 673  
620 674 static inline void tcg_gen_subi_i64(TCGv ret, TCGv arg1, int64_t arg2)
621 675 {
622   - tcg_gen_sub_i64(ret, arg1, tcg_const_i64(arg2));
  676 + TCGv t0 = tcg_const_i64(arg2);
  677 + tcg_gen_sub_i64(ret, arg1, t0);
  678 + tcg_temp_free(t0);
623 679 }
624 680  
625 681 static inline void tcg_gen_and_i64(TCGv ret, TCGv arg1, TCGv arg2)
... ... @@ -713,11 +769,15 @@ static inline void tcg_gen_mul_i64(TCGv ret, TCGv arg1, TCGv arg2)
713 769 tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
714 770  
715 771 tcg_gen_mov_i64(ret, t0);
  772 + tcg_temp_free(t0);
  773 + tcg_temp_free(t1);
716 774 }
717 775  
718 776 static inline void tcg_gen_muli_i64(TCGv ret, TCGv arg1, int64_t arg2)
719 777 {
720   - tcg_gen_mul_i64(ret, arg1, tcg_const_i64(arg2));
  778 + TCGv t0 = tcg_const_i64(arg2);
  779 + tcg_gen_mul_i64(ret, arg1, t0);
  780 + tcg_temp_free(t0);
721 781 }
722 782  
723 783 static inline void tcg_gen_div_i64(TCGv ret, TCGv arg1, TCGv arg2)
... ... @@ -824,7 +884,9 @@ static inline void tcg_gen_add_i64(TCGv ret, TCGv arg1, TCGv arg2)
824 884  
825 885 static inline void tcg_gen_addi_i64(TCGv ret, TCGv arg1, int64_t arg2)
826 886 {
827   - tcg_gen_add_i64(ret, arg1, tcg_const_i64(arg2));
  887 + TCGv t0 = tcg_const_i64(arg2);
  888 + tcg_gen_add_i64(ret, arg1, t0);
  889 + tcg_temp_free(t0);
828 890 }
829 891  
830 892 static inline void tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2)
... ... @@ -834,7 +896,9 @@ static inline void tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2)
834 896  
835 897 static inline void tcg_gen_subi_i64(TCGv ret, TCGv arg1, int64_t arg2)
836 898 {
837   - tcg_gen_sub_i64(ret, arg1, tcg_const_i64(arg2));
  899 + TCGv t0 = tcg_const_i64(arg2);
  900 + tcg_gen_sub_i64(ret, arg1, t0);
  901 + tcg_temp_free(t0);
838 902 }
839 903  
840 904 static inline void tcg_gen_and_i64(TCGv ret, TCGv arg1, TCGv arg2)
... ... @@ -844,7 +908,9 @@ static inline void tcg_gen_and_i64(TCGv ret, TCGv arg1, TCGv arg2)
844 908  
845 909 static inline void tcg_gen_andi_i64(TCGv ret, TCGv arg1, int64_t arg2)
846 910 {
847   - tcg_gen_and_i64(ret, arg1, tcg_const_i64(arg2));
  911 + TCGv t0 = tcg_const_i64(arg2);
  912 + tcg_gen_and_i64(ret, arg1, t0);
  913 + tcg_temp_free(t0);
848 914 }
849 915  
850 916 static inline void tcg_gen_or_i64(TCGv ret, TCGv arg1, TCGv arg2)
... ... @@ -854,7 +920,9 @@ static inline void tcg_gen_or_i64(TCGv ret, TCGv arg1, TCGv arg2)
854 920  
855 921 static inline void tcg_gen_ori_i64(TCGv ret, TCGv arg1, int64_t arg2)
856 922 {
857   - tcg_gen_or_i64(ret, arg1, tcg_const_i64(arg2));
  923 + TCGv t0 = tcg_const_i64(arg2);
  924 + tcg_gen_or_i64(ret, arg1, t0);
  925 + tcg_temp_free(t0);
858 926 }
859 927  
860 928 static inline void tcg_gen_xor_i64(TCGv ret, TCGv arg1, TCGv arg2)
... ... @@ -864,7 +932,9 @@ static inline void tcg_gen_xor_i64(TCGv ret, TCGv arg1, TCGv arg2)
864 932  
865 933 static inline void tcg_gen_xori_i64(TCGv ret, TCGv arg1, int64_t arg2)
866 934 {
867   - tcg_gen_xor_i64(ret, arg1, tcg_const_i64(arg2));
  935 + TCGv t0 = tcg_const_i64(arg2);
  936 + tcg_gen_xor_i64(ret, arg1, t0);
  937 + tcg_temp_free(t0);
868 938 }
869 939  
870 940 static inline void tcg_gen_shl_i64(TCGv ret, TCGv arg1, TCGv arg2)
... ... @@ -877,7 +947,9 @@ static inline void tcg_gen_shli_i64(TCGv ret, TCGv arg1, int64_t arg2)
877 947 if (arg2 == 0) {
878 948 tcg_gen_mov_i64(ret, arg1);
879 949 } else {
880   - tcg_gen_shl_i64(ret, arg1, tcg_const_i64(arg2));
  950 + TCGv t0 = tcg_const_i64(arg2);
  951 + tcg_gen_shl_i64(ret, arg1, t0);
  952 + tcg_temp_free(t0);
881 953 }
882 954 }
883 955  
... ... @@ -891,7 +963,9 @@ static inline void tcg_gen_shri_i64(TCGv ret, TCGv arg1, int64_t arg2)
891 963 if (arg2 == 0) {
892 964 tcg_gen_mov_i64(ret, arg1);
893 965 } else {
894   - tcg_gen_shr_i64(ret, arg1, tcg_const_i64(arg2));
  966 + TCGv t0 = tcg_const_i64(arg2);
  967 + tcg_gen_shr_i64(ret, arg1, t0);
  968 + tcg_temp_free(t0);
895 969 }
896 970 }
897 971  
... ... @@ -905,7 +979,9 @@ static inline void tcg_gen_sari_i64(TCGv ret, TCGv arg1, int64_t arg2)
905 979 if (arg2 == 0) {
906 980 tcg_gen_mov_i64(ret, arg1);
907 981 } else {
908   - tcg_gen_sar_i64(ret, arg1, tcg_const_i64(arg2));
  982 + TCGv t0 = tcg_const_i64(arg2);
  983 + tcg_gen_sar_i64(ret, arg1, t0);
  984 + tcg_temp_free(t0);
909 985 }
910 986 }
911 987  
... ... @@ -922,7 +998,9 @@ static inline void tcg_gen_mul_i64(TCGv ret, TCGv arg1, TCGv arg2)
922 998  
923 999 static inline void tcg_gen_muli_i64(TCGv ret, TCGv arg1, int64_t arg2)
924 1000 {
925   - tcg_gen_mul_i64(ret, arg1, tcg_const_i64(arg2));
  1001 + TCGv t0 = tcg_const_i64(arg2);
  1002 + tcg_gen_mul_i64(ret, arg1, t0);
  1003 + tcg_temp_free(t0);
926 1004 }
927 1005  
928 1006 #ifdef TCG_TARGET_HAS_div_i64
... ... @@ -952,6 +1030,7 @@ static inline void tcg_gen_div_i64(TCGv ret, TCGv arg1, TCGv arg2)
952 1030 t0 = tcg_temp_new(TCG_TYPE_I64);
953 1031 tcg_gen_sari_i64(t0, arg1, 63);
954 1032 tcg_gen_op5(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
  1033 + tcg_temp_free(t0);
955 1034 }
956 1035  
957 1036 static inline void tcg_gen_rem_i64(TCGv ret, TCGv arg1, TCGv arg2)
... ... @@ -960,6 +1039,7 @@ static inline void tcg_gen_rem_i64(TCGv ret, TCGv arg1, TCGv arg2)
960 1039 t0 = tcg_temp_new(TCG_TYPE_I64);
961 1040 tcg_gen_sari_i64(t0, arg1, 63);
962 1041 tcg_gen_op5(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
  1042 + tcg_temp_free(t0);
963 1043 }
964 1044  
965 1045 static inline void tcg_gen_divu_i64(TCGv ret, TCGv arg1, TCGv arg2)
... ... @@ -968,6 +1048,7 @@ static inline void tcg_gen_divu_i64(TCGv ret, TCGv arg1, TCGv arg2)
968 1048 t0 = tcg_temp_new(TCG_TYPE_I64);
969 1049 tcg_gen_movi_i64(t0, 0);
970 1050 tcg_gen_op5(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2);
  1051 + tcg_temp_free(t0);
971 1052 }
972 1053  
973 1054 static inline void tcg_gen_remu_i64(TCGv ret, TCGv arg1, TCGv arg2)
... ... @@ -976,6 +1057,7 @@ static inline void tcg_gen_remu_i64(TCGv ret, TCGv arg1, TCGv arg2)
976 1057 t0 = tcg_temp_new(TCG_TYPE_I64);
977 1058 tcg_gen_movi_i64(t0, 0);
978 1059 tcg_gen_op5(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2);
  1060 + tcg_temp_free(t0);
979 1061 }
980 1062 #endif
981 1063  
... ... @@ -1030,6 +1112,8 @@ static inline void tcg_gen_bswap16_i32(TCGv ret, TCGv arg)
1030 1112 tcg_gen_andi_i32(t1, arg, 0x000000ff);
1031 1113 tcg_gen_shli_i32(t1, t1, 8);
1032 1114 tcg_gen_or_i32(ret, t0, t1);
  1115 + tcg_temp_free(t0);
  1116 + tcg_temp_free(t1);
1033 1117 #endif
1034 1118 }
1035 1119  
... ... @@ -1054,6 +1138,8 @@ static inline void tcg_gen_bswap_i32(TCGv ret, TCGv arg)
1054 1138  
1055 1139 tcg_gen_shri_i32(t1, arg, 24);
1056 1140 tcg_gen_or_i32(ret, t0, t1);
  1141 + tcg_temp_free(t0);
  1142 + tcg_temp_free(t1);
1057 1143 #endif
1058 1144 }
1059 1145  
... ... @@ -1121,6 +1207,8 @@ static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg)
1121 1207 tcg_gen_bswap_i32(t1, TCGV_HIGH(arg));
1122 1208 tcg_gen_mov_i32(ret, t1);
1123 1209 tcg_gen_mov_i32(TCGV_HIGH(ret), t0);
  1210 + tcg_temp_free(t0);
  1211 + tcg_temp_free(t1);
1124 1212 }
1125 1213 #else
1126 1214  
... ... @@ -1227,6 +1315,8 @@ static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg)
1227 1315  
1228 1316 tcg_gen_shri_i64(t1, arg, 56);
1229 1317 tcg_gen_or_i64(ret, t0, t1);
  1318 + tcg_temp_free(t0);
  1319 + tcg_temp_free(t1);
1230 1320 #endif
1231 1321 }
1232 1322  
... ... @@ -1237,7 +1327,9 @@ static inline void tcg_gen_neg_i32(TCGv ret, TCGv arg)
1237 1327 #ifdef TCG_TARGET_HAS_neg_i32
1238 1328 tcg_gen_op2(INDEX_op_neg_i32, ret, arg);
1239 1329 #else
1240   - tcg_gen_sub_i32(ret, tcg_const_i32(0), arg);
  1330 + TCGv t0 = tcg_const_i32(0);
  1331 + tcg_gen_sub_i32(ret, t0, arg);
  1332 + tcg_temp_free(t0);
1241 1333 #endif
1242 1334 }
1243 1335  
... ... @@ -1246,18 +1338,20 @@ static inline void tcg_gen_neg_i64(TCGv ret, TCGv arg)
1246 1338 #ifdef TCG_TARGET_HAS_neg_i64
1247 1339 tcg_gen_op2(INDEX_op_neg_i64, ret, arg);
1248 1340 #else
1249   - tcg_gen_sub_i64(ret, tcg_const_i64(0), arg);
  1341 + TCGv t0 = tcg_const_i64(0);
  1342 + tcg_gen_sub_i64(ret, t0, arg);
  1343 + tcg_temp_free(t0);
1250 1344 #endif
1251 1345 }
1252 1346  
1253 1347 static inline void tcg_gen_not_i32(TCGv ret, TCGv arg)
1254 1348 {
1255   - tcg_gen_xor_i32(ret, arg, tcg_const_i32(-1));
  1349 + tcg_gen_xori_i32(ret, arg, -1);
1256 1350 }
1257 1351  
1258 1352 static inline void tcg_gen_not_i64(TCGv ret, TCGv arg)
1259 1353 {
1260   - tcg_gen_xor_i64(ret, arg, tcg_const_i64(-1));
  1354 + tcg_gen_xori_i64(ret, arg, -1);
1261 1355 }
1262 1356  
1263 1357 static inline void tcg_gen_discard_i32(TCGv arg)
... ...
tcg/tcg.c
... ... @@ -266,8 +266,11 @@ void tcg_set_macro_func(TCGContext *s, TCGMacroFunc *func)
266 266  
267 267 void tcg_func_start(TCGContext *s)
268 268 {
  269 + int i;
269 270 tcg_pool_reset(s);
270 271 s->nb_temps = s->nb_globals;
  272 + for(i = 0; i < TCG_TYPE_COUNT; i++)
  273 + s->first_free_temp[i] = -1;
271 274 s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
272 275 s->nb_labels = 0;
273 276 s->current_frame_offset = s->frame_start;
... ... @@ -301,7 +304,6 @@ TCGv tcg_global_reg_new(TCGType type, int reg, const char *name)
301 304 ts->type = type;
302 305 ts->fixed_reg = 1;
303 306 ts->reg = reg;
304   - ts->val_type = TEMP_VAL_REG;
305 307 ts->name = name;
306 308 s->nb_globals++;
307 309 tcg_regset_set_reg(s->reserved_regs, reg);
... ... @@ -327,7 +329,6 @@ TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2,
327 329 ts->type = TCG_TYPE_I32;
328 330 ts->fixed_reg = 1;
329 331 ts->reg = reg1;
330   - ts->val_type = TEMP_VAL_REG;
331 332 pstrcpy(buf, sizeof(buf), name);
332 333 pstrcat(buf, sizeof(buf), "_0");
333 334 ts->name = strdup(buf);
... ... @@ -337,7 +338,6 @@ TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2,
337 338 ts->type = TCG_TYPE_I32;
338 339 ts->fixed_reg = 1;
339 340 ts->reg = reg2;
340   - ts->val_type = TEMP_VAL_REG;
341 341 pstrcpy(buf, sizeof(buf), name);
342 342 pstrcat(buf, sizeof(buf), "_1");
343 343 ts->name = strdup(buf);
... ... @@ -370,7 +370,6 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
370 370 #else
371 371 ts->mem_offset = offset;
372 372 #endif
373   - ts->val_type = TEMP_VAL_MEM;
374 373 pstrcpy(buf, sizeof(buf), name);
375 374 pstrcat(buf, sizeof(buf), "_0");
376 375 ts->name = strdup(buf);
... ... @@ -386,7 +385,6 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
386 385 #else
387 386 ts->mem_offset = offset + 4;
388 387 #endif
389   - ts->val_type = TEMP_VAL_MEM;
390 388 pstrcpy(buf, sizeof(buf), name);
391 389 pstrcat(buf, sizeof(buf), "_1");
392 390 ts->name = strdup(buf);
... ... @@ -403,7 +401,6 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
403 401 ts->mem_allocated = 1;
404 402 ts->mem_reg = reg;
405 403 ts->mem_offset = offset;
406   - ts->val_type = TEMP_VAL_MEM;
407 404 ts->name = name;
408 405 s->nb_globals++;
409 406 }
... ... @@ -416,90 +413,75 @@ TCGv tcg_temp_new(TCGType type)
416 413 TCGTemp *ts;
417 414 int idx;
418 415  
419   - idx = s->nb_temps;
  416 + idx = s->first_free_temp[type];
  417 + if (idx != -1) {
  418 + /* There is already an available temp with the
  419 + right type */
  420 + ts = &s->temps[idx];
  421 + s->first_free_temp[type] = ts->next_free_temp;
  422 + ts->temp_allocated = 1;
  423 + } else {
  424 + idx = s->nb_temps;
420 425 #if TCG_TARGET_REG_BITS == 32
421   - if (type == TCG_TYPE_I64) {
422   - tcg_temp_alloc(s, s->nb_temps + 1);
423   - ts = &s->temps[s->nb_temps];
424   - ts->base_type = type;
425   - ts->type = TCG_TYPE_I32;
426   - ts->fixed_reg = 0;
427   - ts->val_type = TEMP_VAL_DEAD;
428   - ts->mem_allocated = 0;
429   - ts->name = NULL;
430   - ts++;
431   - ts->base_type = TCG_TYPE_I32;
432   - ts->type = TCG_TYPE_I32;
433   - ts->val_type = TEMP_VAL_DEAD;
434   - ts->fixed_reg = 0;
435   - ts->mem_allocated = 0;
436   - ts->name = NULL;
437   - s->nb_temps += 2;
438   - } else
  426 + if (type == TCG_TYPE_I64) {
  427 + tcg_temp_alloc(s, s->nb_temps + 1);
  428 + ts = &s->temps[s->nb_temps];
  429 + ts->base_type = type;
  430 + ts->type = TCG_TYPE_I32;
  431 + ts->temp_allocated = 1;
  432 + ts->name = NULL;
  433 + ts++;
  434 + ts->base_type = TCG_TYPE_I32;
  435 + ts->type = TCG_TYPE_I32;
  436 + ts->temp_allocated = 1;
  437 + ts->name = NULL;
  438 + s->nb_temps += 2;
  439 + } else
439 440 #endif
440   - {
441   - tcg_temp_alloc(s, s->nb_temps + 1);
442   - ts = &s->temps[s->nb_temps];
443   - ts->base_type = type;
444   - ts->type = type;
445   - ts->fixed_reg = 0;
446   - ts->val_type = TEMP_VAL_DEAD;
447   - ts->mem_allocated = 0;
448   - ts->name = NULL;
449   - s->nb_temps++;
  441 + {
  442 + tcg_temp_alloc(s, s->nb_temps + 1);
  443 + ts = &s->temps[s->nb_temps];
  444 + ts->base_type = type;
  445 + ts->type = type;
  446 + ts->temp_allocated = 1;
  447 + ts->name = NULL;
  448 + s->nb_temps++;
  449 + }
450 450 }
451 451 return MAKE_TCGV(idx);
452 452 }
453 453  
454   -TCGv tcg_const_i32(int32_t val)
  454 +void tcg_temp_free(TCGv arg)
455 455 {
456 456 TCGContext *s = &tcg_ctx;
457 457 TCGTemp *ts;
458   - int idx;
  458 + int idx = GET_TCGV(arg);
  459 + TCGType type;
459 460  
460   - idx = s->nb_temps;
461   - tcg_temp_alloc(s, idx + 1);
  461 + assert(idx >= s->nb_globals && idx < s->nb_temps);
462 462 ts = &s->temps[idx];
463   - ts->base_type = ts->type = TCG_TYPE_I32;
464   - ts->val_type = TEMP_VAL_CONST;
465   - ts->name = NULL;
466   - ts->val = val;
467   - s->nb_temps++;
468   - return MAKE_TCGV(idx);
  463 + assert(ts->temp_allocated != 0);
  464 + ts->temp_allocated = 0;
  465 + type = ts->base_type;
  466 + ts->next_free_temp = s->first_free_temp[type];
  467 + s->first_free_temp[type] = idx;
469 468 }
470 469  
471   -TCGv tcg_const_i64(int64_t val)
  470 +
  471 +TCGv tcg_const_i32(int32_t val)
472 472 {
473   - TCGContext *s = &tcg_ctx;
474   - TCGTemp *ts;
475   - int idx;
  473 + TCGv t0;
  474 + t0 = tcg_temp_new(TCG_TYPE_I32);
  475 + tcg_gen_movi_i32(t0, val);
  476 + return t0;
  477 +}
476 478  
477   - idx = s->nb_temps;
478   -#if TCG_TARGET_REG_BITS == 32
479   - tcg_temp_alloc(s, idx + 2);
480   - ts = &s->temps[idx];
481   - ts->base_type = TCG_TYPE_I64;
482   - ts->type = TCG_TYPE_I32;
483   - ts->val_type = TEMP_VAL_CONST;
484   - ts->name = NULL;
485   - ts->val = val;
486   - ts++;
487   - ts->base_type = TCG_TYPE_I32;
488   - ts->type = TCG_TYPE_I32;
489   - ts->val_type = TEMP_VAL_CONST;
490   - ts->name = NULL;
491   - ts->val = val >> 32;
492   - s->nb_temps += 2;
493   -#else
494   - tcg_temp_alloc(s, idx + 1);
495   - ts = &s->temps[idx];
496   - ts->base_type = ts->type = TCG_TYPE_I64;
497   - ts->val_type = TEMP_VAL_CONST;
498   - ts->name = NULL;
499   - ts->val = val;
500   - s->nb_temps++;
501   -#endif
502   - return MAKE_TCGV(idx);
  479 +TCGv tcg_const_i64(int64_t val)
  480 +{
  481 + TCGv t0;
  482 + t0 = tcg_temp_new(TCG_TYPE_I64);
  483 + tcg_gen_movi_i64(t0, val);
  484 + return t0;
503 485 }
504 486  
505 487 void tcg_register_helper(void *func, const char *name)
... ... @@ -663,6 +645,8 @@ void tcg_gen_shifti_i64(TCGv ret, TCGv arg1,
663 645 tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0);
664 646 tcg_gen_mov_i32(ret, t1);
665 647 }
  648 + tcg_temp_free(t0);
  649 + tcg_temp_free(t1);
666 650 }
667 651 }
668 652 #endif
... ... @@ -679,6 +663,12 @@ void tcg_reg_alloc_start(TCGContext *s)
679 663 ts->val_type = TEMP_VAL_MEM;
680 664 }
681 665 }
  666 + for(i = s->nb_globals; i < s->nb_temps; i++) {
  667 + ts = &s->temps[i];
  668 + ts->val_type = TEMP_VAL_DEAD;
  669 + ts->mem_allocated = 0;
  670 + ts->fixed_reg = 0;
  671 + }
682 672 for(i = 0; i < TCG_TARGET_NB_REGS; i++) {
683 673 s->reg_to_temp[i] = -1;
684 674 }
... ... @@ -693,11 +683,7 @@ static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
693 683 if (idx < s->nb_globals) {
694 684 pstrcpy(buf, buf_size, ts->name);
695 685 } else {
696   - if (ts->val_type == TEMP_VAL_CONST) {
697   - snprintf(buf, buf_size, "$0x%" TCG_PRIlx , ts->val);
698   - } else {
699   - snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
700   - }
  686 + snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
701 687 }
702 688 return buf;
703 689 }
... ... @@ -707,37 +693,49 @@ char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg)
707 693 return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV(arg));
708 694 }
709 695  
710   -/* find helper definition (XXX: inefficient) */
711   -static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
  696 +static int helper_cmp(const void *p1, const void *p2)
712 697 {
713   - int i;
714   - for(i = 0; i < s->nb_helpers; i++) {
715   - if (s->helpers[i].func == val)
716   - return &s->helpers[i];
717   - }
718   - return NULL;
  698 + const TCGHelperInfo *th1 = p1;
  699 + const TCGHelperInfo *th2 = p2;
  700 + if (th1->func < th2->func)
  701 + return -1;
  702 + else if (th1->func == th2->func)
  703 + return 0;
  704 + else
  705 + return 1;
719 706 }
720 707  
721   -static const char *tcg_get_helper_str_idx(TCGContext *s, char *buf, int buf_size,
722   - int idx)
  708 +/* find helper definition (Note: A hash table would be better) */
  709 +static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
723 710 {
724   - TCGTemp *ts;
  711 + int m, m_min, m_max;
725 712 TCGHelperInfo *th;
  713 + tcg_target_ulong v;
726 714  
727   - ts = &s->temps[idx];
728   - if (ts->val_type == TEMP_VAL_CONST) {
729   - /* find helper name (XXX: inefficient) */
730   - th = tcg_find_helper(s, ts->val);
731   - if (th) {
732   - pstrcpy(buf, buf_size, "$");
733   - pstrcat(buf, buf_size, th->name);
734   - return buf;
  715 + if (unlikely(!s->helpers_sorted)) {
  716 + qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo),
  717 + helper_cmp);
  718 + s->helpers_sorted = 1;
  719 + }
  720 +
  721 + /* binary search */
  722 + m_min = 0;
  723 + m_max = s->nb_helpers - 1;
  724 + while (m_min <= m_max) {
  725 + m = (m_min + m_max) >> 1;
  726 + th = &s->helpers[m];
  727 + v = th->func;
  728 + if (v == val)
  729 + return th;
  730 + else if (val < v) {
  731 + m_max = m - 1;
  732 + } else {
  733 + m_min = m + 1;
735 734 }
736 735 }
737   - return tcg_get_arg_str_idx(s, buf, buf_size, idx);
  736 + return NULL;
738 737 }
739 738  
740   -
741 739 void tcg_dump_ops(TCGContext *s, FILE *outfile)
742 740 {
743 741 const uint16_t *opc_ptr;
... ... @@ -780,7 +778,7 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
780 778  
781 779 /* function name */
782 780 fprintf(outfile, "%s",
783   - tcg_get_helper_str_idx(s, buf, sizeof(buf), args[nb_oargs + nb_iargs - 1]));
  781 + tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + nb_iargs - 1]));
784 782 /* flags */
785 783 fprintf(outfile, ",$0x%" TCG_PRIlx,
786 784 args[nb_oargs + nb_iargs]);
... ... @@ -800,6 +798,29 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
800 798 tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i]));
801 799 }
802 800 }
  801 + } else if (c == INDEX_op_movi_i32
  802 +#if TCG_TARGET_REG_BITS == 64
  803 + || c == INDEX_op_movi_i64
  804 +#endif
  805 + ) {
  806 + tcg_target_ulong val;
  807 + TCGHelperInfo *th;
  808 +
  809 + nb_oargs = def->nb_oargs;
  810 + nb_iargs = def->nb_iargs;
  811 + nb_cargs = def->nb_cargs;
  812 + fprintf(outfile, " %s %s,$", def->name,
  813 + tcg_get_arg_str_idx(s, buf, sizeof(buf), args[0]));
  814 + val = args[1];
  815 + th = tcg_find_helper(s, val);
  816 + if (th) {
  817 + fprintf(outfile, th->name);
  818 + } else {
  819 + if (c == INDEX_op_movi_i32)
  820 + fprintf(outfile, "0x%x", (uint32_t)val);
  821 + else
  822 + fprintf(outfile, "0x%" PRIx64 , (uint64_t)val);
  823 + }
803 824 } else {
804 825 fprintf(outfile, " %s ", def->name);
805 826 if (c == INDEX_op_nopn) {
... ... @@ -1281,11 +1302,6 @@ static void check_regs(TCGContext *s)
1281 1302 dump_regs(s);
1282 1303 tcg_abort();
1283 1304 }
1284   - if (ts->val_type == TEMP_VAL_CONST && k < s->nb_globals) {
1285   - printf("constant forbidden in global %s\n",
1286   - tcg_get_arg_str_idx(s, buf, sizeof(buf), k));
1287   - goto fail;
1288   - }
1289 1305 }
1290 1306 }
1291 1307 #endif
... ... @@ -1351,47 +1367,80 @@ static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1351 1367 }
1352 1368  
1353 1369 /* save globals to their cannonical location and assume they can be
1354   - modified be the following code. */
1355   -static void save_globals(TCGContext *s)
  1370 + modified be the following code. 'allocated_regs' is used in case a
  1371 + temporary registers needs to be allocated to store a constant. */
  1372 +static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1356 1373 {
1357 1374 TCGTemp *ts;
1358   - int i;
  1375 + int i, reg;
1359 1376  
1360 1377 for(i = 0; i < s->nb_globals; i++) {
1361 1378 ts = &s->temps[i];
1362 1379 if (!ts->fixed_reg) {
1363   - if (ts->val_type == TEMP_VAL_REG) {
  1380 + switch(ts->val_type) {
  1381 + case TEMP_VAL_REG:
1364 1382 tcg_reg_free(s, ts->reg);
1365   - } else if (ts->val_type == TEMP_VAL_DEAD) {
  1383 + break;
  1384 + case TEMP_VAL_DEAD:
1366 1385 ts->val_type = TEMP_VAL_MEM;
  1386 + break;
  1387 + case TEMP_VAL_CONST:
  1388 + reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
  1389 + allocated_regs);
  1390 + tcg_out_movi(s, ts->type, reg, ts->val);
  1391 + tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
  1392 + ts->val_type = TEMP_VAL_MEM;
  1393 + break;
  1394 + case TEMP_VAL_MEM:
  1395 + break;
  1396 + default:
  1397 + tcg_abort();
1367 1398 }
1368 1399 }
1369 1400 }
1370 1401 }
1371 1402  
1372 1403 /* at the end of a basic block, we assume all temporaries are dead and
1373   - all globals are stored at their canonical location */
1374   -/* XXX: optimize by handling constants in another array ? */
1375   -void tcg_reg_alloc_bb_end(TCGContext *s)
  1404 + all globals are stored at their canonical location. */
  1405 +static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1376 1406 {
1377 1407 TCGTemp *ts;
1378 1408 int i;
1379 1409  
1380   - save_globals(s);
1381   -
1382 1410 for(i = s->nb_globals; i < s->nb_temps; i++) {
1383 1411 ts = &s->temps[i];
1384   - if (ts->val_type != TEMP_VAL_CONST) {
1385   - if (ts->val_type == TEMP_VAL_REG) {
1386   - s->reg_to_temp[ts->reg] = -1;
1387   - }
1388   - ts->val_type = TEMP_VAL_DEAD;
  1412 + if (ts->val_type == TEMP_VAL_REG) {
  1413 + s->reg_to_temp[ts->reg] = -1;
1389 1414 }
  1415 + ts->val_type = TEMP_VAL_DEAD;
1390 1416 }
  1417 +
  1418 + save_globals(s, allocated_regs);
1391 1419 }
1392 1420  
1393 1421 #define IS_DEAD_IARG(n) ((dead_iargs >> (n)) & 1)
1394 1422  
  1423 +static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
  1424 +{
  1425 + TCGTemp *ots;
  1426 + tcg_target_ulong val;
  1427 +
  1428 + ots = &s->temps[args[0]];
  1429 + val = args[1];
  1430 +
  1431 + if (ots->fixed_reg) {
  1432 + /* for fixed registers, we do not do any constant
  1433 + propagation */
  1434 + tcg_out_movi(s, ots->type, ots->reg, val);
  1435 + } else {
  1436 + /* The movi is not explicitely generated here */
  1437 + if (ots->val_type == TEMP_VAL_REG)
  1438 + s->reg_to_temp[ots->reg] = -1;
  1439 + ots->val_type = TEMP_VAL_CONST;
  1440 + ots->val = val;
  1441 + }
  1442 +}
  1443 +
1395 1444 static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1396 1445 const TCGArg *args,
1397 1446 unsigned int dead_iargs)
... ... @@ -1404,6 +1453,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1404 1453 ts = &s->temps[args[1]];
1405 1454 arg_ct = &def->args_ct[0];
1406 1455  
  1456 + /* XXX: always mark arg dead if IS_DEAD_IARG(0) */
1407 1457 if (ts->val_type == TEMP_VAL_REG) {
1408 1458 if (IS_DEAD_IARG(0) && !ts->fixed_reg && !ots->fixed_reg) {
1409 1459 /* the mov can be suppressed */
... ... @@ -1430,12 +1480,17 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1430 1480 }
1431 1481 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1432 1482 } else if (ts->val_type == TEMP_VAL_CONST) {
1433   - if (ots->val_type == TEMP_VAL_REG) {
  1483 + if (ots->fixed_reg) {
1434 1484 reg = ots->reg;
  1485 + tcg_out_movi(s, ots->type, reg, ts->val);
1435 1486 } else {
1436   - reg = tcg_reg_alloc(s, arg_ct->u.regs, s->reserved_regs);
  1487 + /* propagate constant */
  1488 + if (ots->val_type == TEMP_VAL_REG)
  1489 + s->reg_to_temp[ots->reg] = -1;
  1490 + ots->val_type = TEMP_VAL_CONST;
  1491 + ots->val = ts->val;
  1492 + return;
1437 1493 }
1438   - tcg_out_movi(s, ots->type, reg, ts->val);
1439 1494 } else {
1440 1495 tcg_abort();
1441 1496 }
... ... @@ -1487,10 +1542,13 @@ static void tcg_reg_alloc_op(TCGContext *s,
1487 1542 new_args[i] = ts->val;
1488 1543 goto iarg_end;
1489 1544 } else {
1490   - /* need to move to a register*/
  1545 + /* need to move to a register */
1491 1546 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1492 1547 tcg_out_movi(s, ts->type, reg, ts->val);
1493   - goto iarg_end1;
  1548 + ts->val_type = TEMP_VAL_REG;
  1549 + ts->reg = reg;
  1550 + ts->mem_coherent = 0;
  1551 + s->reg_to_temp[reg] = arg;
1494 1552 }
1495 1553 }
1496 1554 assert(ts->val_type == TEMP_VAL_REG);
... ... @@ -1518,78 +1576,78 @@ static void tcg_reg_alloc_op(TCGContext *s,
1518 1576 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1519 1577 tcg_out_mov(s, reg, ts->reg);
1520 1578 }
1521   - iarg_end1:
1522 1579 new_args[i] = reg;
1523 1580 const_args[i] = 0;
1524 1581 tcg_regset_set_reg(allocated_regs, reg);
1525 1582 iarg_end: ;
1526 1583 }
1527 1584  
1528   - /* mark dead temporaries and free the associated registers */
1529   - for(i = 0; i < nb_iargs; i++) {
1530   - arg = args[nb_oargs + i];
1531   - if (IS_DEAD_IARG(i)) {
1532   - ts = &s->temps[arg];
1533   - if (ts->val_type != TEMP_VAL_CONST && !ts->fixed_reg) {
1534   - if (ts->val_type == TEMP_VAL_REG)
1535   - s->reg_to_temp[ts->reg] = -1;
1536   - ts->val_type = TEMP_VAL_DEAD;
  1585 + if (def->flags & TCG_OPF_BB_END) {
  1586 + tcg_reg_alloc_bb_end(s, allocated_regs);
  1587 + } else {
  1588 + /* mark dead temporaries and free the associated registers */
  1589 + for(i = 0; i < nb_iargs; i++) {
  1590 + arg = args[nb_oargs + i];
  1591 + if (IS_DEAD_IARG(i)) {
  1592 + ts = &s->temps[arg];
  1593 + if (!ts->fixed_reg) {
  1594 + if (ts->val_type == TEMP_VAL_REG)
  1595 + s->reg_to_temp[ts->reg] = -1;
  1596 + ts->val_type = TEMP_VAL_DEAD;
  1597 + }
1537 1598 }
1538 1599 }
1539   - }
1540   -
1541   - if (def->flags & TCG_OPF_CALL_CLOBBER) {
1542   - /* XXX: permit generic clobber register list ? */
1543   - for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
1544   - if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
1545   - tcg_reg_free(s, reg);
  1600 +
  1601 + if (def->flags & TCG_OPF_CALL_CLOBBER) {
  1602 + /* XXX: permit generic clobber register list ? */
  1603 + for(reg = 0; reg < TCG_TARGET_NB_REGS; reg++) {
  1604 + if (tcg_regset_test_reg(tcg_target_call_clobber_regs, reg)) {
  1605 + tcg_reg_free(s, reg);
  1606 + }
1546 1607 }
  1608 + /* XXX: for load/store we could do that only for the slow path
  1609 + (i.e. when a memory callback is called) */
  1610 +
  1611 + /* store globals and free associated registers (we assume the insn
  1612 + can modify any global. */
  1613 + save_globals(s, allocated_regs);
1547 1614 }
1548   - /* XXX: for load/store we could do that only for the slow path
1549   - (i.e. when a memory callback is called) */
1550   -
1551   - /* store globals and free associated registers (we assume the insn
1552   - can modify any global. */
1553   - save_globals(s);
1554   - }
1555   -
1556   - /* satisfy the output constraints */
1557   - tcg_regset_set(allocated_regs, s->reserved_regs);
1558   - for(k = 0; k < nb_oargs; k++) {
1559   - i = def->sorted_args[k];
1560   - arg = args[i];
1561   - arg_ct = &def->args_ct[i];
1562   - ts = &s->temps[arg];
1563   - if (arg_ct->ct & TCG_CT_ALIAS) {
1564   - reg = new_args[arg_ct->alias_index];
1565   - } else {
1566   - /* if fixed register, we try to use it */
1567   - reg = ts->reg;
1568   - if (ts->fixed_reg &&
1569   - tcg_regset_test_reg(arg_ct->u.regs, reg)) {
1570   - goto oarg_end;
  1615 +
  1616 + /* satisfy the output constraints */
  1617 + tcg_regset_set(allocated_regs, s->reserved_regs);
  1618 + for(k = 0; k < nb_oargs; k++) {
  1619 + i = def->sorted_args[k];
  1620 + arg = args[i];
  1621 + arg_ct = &def->args_ct[i];
  1622 + ts = &s->temps[arg];
  1623 + if (arg_ct->ct & TCG_CT_ALIAS) {
  1624 + reg = new_args[arg_ct->alias_index];
  1625 + } else {
  1626 + /* if fixed register, we try to use it */
  1627 + reg = ts->reg;
  1628 + if (ts->fixed_reg &&
  1629 + tcg_regset_test_reg(arg_ct->u.regs, reg)) {
  1630 + goto oarg_end;
  1631 + }
  1632 + reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1571 1633 }
1572   - reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1573   - }
1574   - tcg_regset_set_reg(allocated_regs, reg);
1575   - /* if a fixed register is used, then a move will be done afterwards */
1576   - if (!ts->fixed_reg) {
1577   - if (ts->val_type == TEMP_VAL_REG)
1578   - s->reg_to_temp[ts->reg] = -1;
1579   - ts->val_type = TEMP_VAL_REG;
1580   - ts->reg = reg;
1581   - /* temp value is modified, so the value kept in memory is
1582   - potentially not the same */
1583   - ts->mem_coherent = 0;
1584   - s->reg_to_temp[reg] = arg;
  1634 + tcg_regset_set_reg(allocated_regs, reg);
  1635 + /* if a fixed register is used, then a move will be done afterwards */
  1636 + if (!ts->fixed_reg) {
  1637 + if (ts->val_type == TEMP_VAL_REG)
  1638 + s->reg_to_temp[ts->reg] = -1;
  1639 + ts->val_type = TEMP_VAL_REG;
  1640 + ts->reg = reg;
  1641 + /* temp value is modified, so the value kept in memory is
  1642 + potentially not the same */
  1643 + ts->mem_coherent = 0;
  1644 + s->reg_to_temp[reg] = arg;
  1645 + }
  1646 + oarg_end:
  1647 + new_args[i] = reg;
1585 1648 }
1586   - oarg_end:
1587   - new_args[i] = reg;
1588 1649 }
1589 1650  
1590   - if (def->flags & TCG_OPF_BB_END)
1591   - tcg_reg_alloc_bb_end(s);
1592   -
1593 1651 /* emit instruction */
1594 1652 tcg_out_op(s, opc, new_args, const_args);
1595 1653  
... ... @@ -1708,6 +1766,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1708 1766 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1709 1767 tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
1710 1768 func_arg = reg;
  1769 + tcg_regset_set_reg(allocated_regs, reg);
1711 1770 } else if (ts->val_type == TEMP_VAL_REG) {
1712 1771 reg = ts->reg;
1713 1772 if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) {
... ... @@ -1715,6 +1774,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1715 1774 tcg_out_mov(s, reg, ts->reg);
1716 1775 }
1717 1776 func_arg = reg;
  1777 + tcg_regset_set_reg(allocated_regs, reg);
1718 1778 } else if (ts->val_type == TEMP_VAL_CONST) {
1719 1779 if (tcg_target_const_match(func_addr, arg_ct)) {
1720 1780 const_func_arg = 1;
... ... @@ -1723,17 +1783,19 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1723 1783 reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs);
1724 1784 tcg_out_movi(s, ts->type, reg, func_addr);
1725 1785 func_arg = reg;
  1786 + tcg_regset_set_reg(allocated_regs, reg);
1726 1787 }
1727 1788 } else {
1728 1789 tcg_abort();
1729 1790 }
  1791 +
1730 1792  
1731 1793 /* mark dead temporaries and free the associated registers */
1732 1794 for(i = 0; i < nb_iargs; i++) {
1733 1795 arg = args[nb_oargs + i];
1734 1796 if (IS_DEAD_IARG(i)) {
1735 1797 ts = &s->temps[arg];
1736   - if (ts->val_type != TEMP_VAL_CONST && !ts->fixed_reg) {
  1798 + if (!ts->fixed_reg) {
1737 1799 if (ts->val_type == TEMP_VAL_REG)
1738 1800 s->reg_to_temp[ts->reg] = -1;
1739 1801 ts->val_type = TEMP_VAL_DEAD;
... ... @@ -1750,7 +1812,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1750 1812  
1751 1813 /* store globals and free associated registers (we assume the call
1752 1814 can modify any global. */
1753   - save_globals(s);
  1815 + save_globals(s, allocated_regs);
1754 1816  
1755 1817 tcg_out_op(s, opc, &func_arg, &const_func_arg);
1756 1818  
... ... @@ -1763,7 +1825,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1763 1825 arg = args[i];
1764 1826 ts = &s->temps[arg];
1765 1827 reg = tcg_target_call_oarg_regs[i];
1766   - tcg_reg_free(s, reg);
  1828 + assert(s->reg_to_temp[reg] == -1);
1767 1829 if (ts->fixed_reg) {
1768 1830 if (ts->reg != reg) {
1769 1831 tcg_out_mov(s, ts->reg, reg);
... ... @@ -1863,6 +1925,12 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
1863 1925 dead_iargs = s->op_dead_iargs[op_index];
1864 1926 tcg_reg_alloc_mov(s, def, args, dead_iargs);
1865 1927 break;
  1928 + case INDEX_op_movi_i32:
  1929 +#if TCG_TARGET_REG_BITS == 64
  1930 + case INDEX_op_movi_i64:
  1931 +#endif
  1932 + tcg_reg_alloc_movi(s, args);
  1933 + break;
1866 1934 case INDEX_op_debug_insn_start:
1867 1935 /* debug instruction */
1868 1936 break;
... ... @@ -1879,7 +1947,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
1879 1947 TCGTemp *ts;
1880 1948 ts = &s->temps[args[0]];
1881 1949 /* mark the temporary as dead */
1882   - if (ts->val_type != TEMP_VAL_CONST && !ts->fixed_reg) {
  1950 + if (!ts->fixed_reg) {
1883 1951 if (ts->val_type == TEMP_VAL_REG)
1884 1952 s->reg_to_temp[ts->reg] = -1;
1885 1953 ts->val_type = TEMP_VAL_DEAD;
... ... @@ -1900,7 +1968,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
1900 1968 /* must never happen here */
1901 1969 tcg_abort();
1902 1970 case INDEX_op_set_label:
1903   - tcg_reg_alloc_bb_end(s);
  1971 + tcg_reg_alloc_bb_end(s, s->reserved_regs);
1904 1972 tcg_out_label(s, args[0], (long)s->code_ptr);
1905 1973 break;
1906 1974 case INDEX_op_call:
... ... @@ -1916,7 +1984,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
1916 1984 #ifdef CONFIG_PROFILER
1917 1985 s->old_op_count++;
1918 1986 #endif
1919   - tcg_reg_alloc_bb_end(s);
  1987 + tcg_reg_alloc_bb_end(s, s->reserved_regs);
1920 1988 if (search_pc >= 0) {
1921 1989 s->code_ptr += def->copy_size;
1922 1990 args += def->nb_args;
... ...
tcg/tcg.h
... ... @@ -98,6 +98,7 @@ typedef int TCGType;
98 98  
99 99 #define TCG_TYPE_I32 0
100 100 #define TCG_TYPE_I64 1
  101 +#define TCG_TYPE_COUNT 2 /* number of different types */
101 102  
102 103 #if TCG_TARGET_REG_BITS == 32
103 104 #define TCG_TYPE_PTR TCG_TYPE_I32
... ... @@ -188,6 +189,9 @@ typedef struct TCGTemp {
188 189 unsigned int fixed_reg:1;
189 190 unsigned int mem_coherent:1;
190 191 unsigned int mem_allocated:1;
  192 + unsigned int temp_allocated:1; /* never used for code gen */
  193 + /* index of next free temp of same base type, -1 if end */
  194 + int next_free_temp;
191 195 const char *name;
192 196 } TCGTemp;
193 197  
... ... @@ -208,6 +212,8 @@ struct TCGContext {
208 212 TCGTemp *temps; /* globals first, temps after */
209 213 int nb_globals;
210 214 int nb_temps;
  215 + int first_free_temp[TCG_TYPE_COUNT]; /* index of free temps, -1 if none */
  216 +
211 217 /* constant indexes (end of temp array) */
212 218 int const_start;
213 219 int const_end;
... ... @@ -236,6 +242,7 @@ struct TCGContext {
236 242 TCGHelperInfo *helpers;
237 243 int nb_helpers;
238 244 int allocated_helpers;
  245 + int helpers_sorted;
239 246  
240 247 #ifdef CONFIG_PROFILER
241 248 /* profiling info */
... ... @@ -299,6 +306,7 @@ TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2,
299 306 TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
300 307 const char *name);
301 308 TCGv tcg_temp_new(TCGType type);
  309 +void tcg_temp_free(TCGv arg);
302 310 char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg);
303 311 void tcg_dump_info(FILE *f,
304 312 int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
... ... @@ -381,9 +389,6 @@ TCGv tcg_const_i64(int64_t val);
381 389  
382 390 void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
383 391 int label_index, long addend);
384   -void tcg_reg_alloc_start(TCGContext *s);
385   -void tcg_reg_alloc_bb_end(TCGContext *s);
386   -void tcg_liveness_analysis(TCGContext *s);
387 392 const TCGArg *tcg_gen_code_op(TCGContext *s, int opc, const TCGArg *args1,
388 393 unsigned int dead_iargs);
389 394  
... ...