Commit e8996ee012e957cf8456d41ee6a7bbaf1f9b888b
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
Showing
3 changed files
with
396 additions
and
229 deletions
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 | |
... | ... |