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 | ... | ... |