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,88 +178,115 @@ static inline void tcg_gen_movi_i32(TCGv ret, int32_t arg) | ||
| 178 | 178 | ||
| 179 | static inline void tcg_gen_helper_0_0(void *func) | 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 | tcg_gen_call(&tcg_ctx, | 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 | 0, NULL, 0, NULL); | 185 | 0, NULL, 0, NULL); |
| 186 | + tcg_temp_free(t0); | ||
| 184 | } | 187 | } |
| 185 | 188 | ||
| 186 | static inline void tcg_gen_helper_0_1(void *func, TCGv arg) | 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 | tcg_gen_call(&tcg_ctx, | 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 | 0, NULL, 1, &arg); | 195 | 0, NULL, 1, &arg); |
| 196 | + tcg_temp_free(t0); | ||
| 191 | } | 197 | } |
| 192 | 198 | ||
| 193 | static inline void tcg_gen_helper_0_2(void *func, TCGv arg1, TCGv arg2) | 199 | static inline void tcg_gen_helper_0_2(void *func, TCGv arg1, TCGv arg2) |
| 194 | { | 200 | { |
| 195 | TCGv args[2]; | 201 | TCGv args[2]; |
| 202 | + TCGv t0; | ||
| 196 | args[0] = arg1; | 203 | args[0] = arg1; |
| 197 | args[1] = arg2; | 204 | args[1] = arg2; |
| 205 | + t0 = tcg_const_ptr((tcg_target_long)func); | ||
| 198 | tcg_gen_call(&tcg_ctx, | 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 | 0, NULL, 2, args); | 208 | 0, NULL, 2, args); |
| 209 | + tcg_temp_free(t0); | ||
| 201 | } | 210 | } |
| 202 | 211 | ||
| 203 | static inline void tcg_gen_helper_0_3(void *func, | 212 | static inline void tcg_gen_helper_0_3(void *func, |
| 204 | TCGv arg1, TCGv arg2, TCGv arg3) | 213 | TCGv arg1, TCGv arg2, TCGv arg3) |
| 205 | { | 214 | { |
| 206 | TCGv args[3]; | 215 | TCGv args[3]; |
| 216 | + TCGv t0; | ||
| 207 | args[0] = arg1; | 217 | args[0] = arg1; |
| 208 | args[1] = arg2; | 218 | args[1] = arg2; |
| 209 | args[2] = arg3; | 219 | args[2] = arg3; |
| 220 | + t0 = tcg_const_ptr((tcg_target_long)func); | ||
| 210 | tcg_gen_call(&tcg_ctx, | 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 | 0, NULL, 3, args); | 223 | 0, NULL, 3, args); |
| 224 | + tcg_temp_free(t0); | ||
| 213 | } | 225 | } |
| 214 | 226 | ||
| 215 | static inline void tcg_gen_helper_0_4(void *func, TCGv arg1, TCGv arg2, | 227 | static inline void tcg_gen_helper_0_4(void *func, TCGv arg1, TCGv arg2, |
| 216 | TCGv arg3, TCGv arg4) | 228 | TCGv arg3, TCGv arg4) |
| 217 | { | 229 | { |
| 218 | TCGv args[4]; | 230 | TCGv args[4]; |
| 231 | + TCGv t0; | ||
| 219 | args[0] = arg1; | 232 | args[0] = arg1; |
| 220 | args[1] = arg2; | 233 | args[1] = arg2; |
| 221 | args[2] = arg3; | 234 | args[2] = arg3; |
| 222 | args[3] = arg4; | 235 | args[3] = arg4; |
| 236 | + t0 = tcg_const_ptr((tcg_target_long)func); | ||
| 223 | tcg_gen_call(&tcg_ctx, | 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 | 0, NULL, 4, args); | 239 | 0, NULL, 4, args); |
| 240 | + tcg_temp_free(t0); | ||
| 226 | } | 241 | } |
| 227 | 242 | ||
| 228 | static inline void tcg_gen_helper_1_0(void *func, TCGv ret) | 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 | tcg_gen_call(&tcg_ctx, | 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 | 1, &ret, 0, NULL); | 249 | 1, &ret, 0, NULL); |
| 250 | + tcg_temp_free(t0); | ||
| 233 | } | 251 | } |
| 234 | 252 | ||
| 235 | static inline void tcg_gen_helper_1_1(void *func, TCGv ret, TCGv arg1) | 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 | tcg_gen_call(&tcg_ctx, | 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 | 1, &ret, 1, &arg1); | 259 | 1, &ret, 1, &arg1); |
| 260 | + tcg_temp_free(t0); | ||
| 240 | } | 261 | } |
| 241 | 262 | ||
| 242 | static inline void tcg_gen_helper_1_2(void *func, TCGv ret, | 263 | static inline void tcg_gen_helper_1_2(void *func, TCGv ret, |
| 243 | TCGv arg1, TCGv arg2) | 264 | TCGv arg1, TCGv arg2) |
| 244 | { | 265 | { |
| 245 | TCGv args[2]; | 266 | TCGv args[2]; |
| 267 | + TCGv t0; | ||
| 246 | args[0] = arg1; | 268 | args[0] = arg1; |
| 247 | args[1] = arg2; | 269 | args[1] = arg2; |
| 270 | + t0 = tcg_const_ptr((tcg_target_long)func); | ||
| 248 | tcg_gen_call(&tcg_ctx, | 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 | 1, &ret, 2, args); | 273 | 1, &ret, 2, args); |
| 274 | + tcg_temp_free(t0); | ||
| 251 | } | 275 | } |
| 252 | 276 | ||
| 253 | static inline void tcg_gen_helper_1_3(void *func, TCGv ret, | 277 | static inline void tcg_gen_helper_1_3(void *func, TCGv ret, |
| 254 | TCGv arg1, TCGv arg2, TCGv arg3) | 278 | TCGv arg1, TCGv arg2, TCGv arg3) |
| 255 | { | 279 | { |
| 256 | TCGv args[3]; | 280 | TCGv args[3]; |
| 281 | + TCGv t0; | ||
| 257 | args[0] = arg1; | 282 | args[0] = arg1; |
| 258 | args[1] = arg2; | 283 | args[1] = arg2; |
| 259 | args[2] = arg3; | 284 | args[2] = arg3; |
| 285 | + t0 = tcg_const_ptr((tcg_target_long)func); | ||
| 260 | tcg_gen_call(&tcg_ctx, | 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 | 1, &ret, 3, args); | 288 | 1, &ret, 3, args); |
| 289 | + tcg_temp_free(t0); | ||
| 263 | } | 290 | } |
| 264 | 291 | ||
| 265 | static inline void tcg_gen_helper_1_4(void *func, TCGv ret, | 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,13 +294,16 @@ static inline void tcg_gen_helper_1_4(void *func, TCGv ret, | ||
| 267 | TCGv arg4) | 294 | TCGv arg4) |
| 268 | { | 295 | { |
| 269 | TCGv args[4]; | 296 | TCGv args[4]; |
| 297 | + TCGv t0; | ||
| 270 | args[0] = arg1; | 298 | args[0] = arg1; |
| 271 | args[1] = arg2; | 299 | args[1] = arg2; |
| 272 | args[2] = arg3; | 300 | args[2] = arg3; |
| 273 | args[3] = arg4; | 301 | args[3] = arg4; |
| 302 | + t0 = tcg_const_ptr((tcg_target_long)func); | ||
| 274 | tcg_gen_call(&tcg_ctx, | 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 | 1, &ret, 4, args); | 305 | 1, &ret, 4, args); |
| 306 | + tcg_temp_free(t0); | ||
| 277 | } | 307 | } |
| 278 | 308 | ||
| 279 | /* 32 bit ops */ | 309 | /* 32 bit ops */ |
| @@ -329,7 +359,9 @@ static inline void tcg_gen_addi_i32(TCGv ret, TCGv arg1, int32_t arg2) | @@ -329,7 +359,9 @@ static inline void tcg_gen_addi_i32(TCGv ret, TCGv arg1, int32_t arg2) | ||
| 329 | if (arg2 == 0) { | 359 | if (arg2 == 0) { |
| 330 | tcg_gen_mov_i32(ret, arg1); | 360 | tcg_gen_mov_i32(ret, arg1); |
| 331 | } else { | 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,7 +376,9 @@ static inline void tcg_gen_subi_i32(TCGv ret, TCGv arg1, int32_t arg2) | ||
| 344 | if (arg2 == 0) { | 376 | if (arg2 == 0) { |
| 345 | tcg_gen_mov_i32(ret, arg1); | 377 | tcg_gen_mov_i32(ret, arg1); |
| 346 | } else { | 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,7 +395,9 @@ static inline void tcg_gen_andi_i32(TCGv ret, TCGv arg1, int32_t arg2) | ||
| 361 | } else if (arg2 == 0xffffffff) { | 395 | } else if (arg2 == 0xffffffff) { |
| 362 | tcg_gen_mov_i32(ret, arg1); | 396 | tcg_gen_mov_i32(ret, arg1); |
| 363 | } else { | 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,7 +414,9 @@ static inline void tcg_gen_ori_i32(TCGv ret, TCGv arg1, int32_t arg2) | ||
| 378 | } else if (arg2 == 0) { | 414 | } else if (arg2 == 0) { |
| 379 | tcg_gen_mov_i32(ret, arg1); | 415 | tcg_gen_mov_i32(ret, arg1); |
| 380 | } else { | 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,7 +431,9 @@ static inline void tcg_gen_xori_i32(TCGv ret, TCGv arg1, int32_t arg2) | ||
| 393 | if (arg2 == 0) { | 431 | if (arg2 == 0) { |
| 394 | tcg_gen_mov_i32(ret, arg1); | 432 | tcg_gen_mov_i32(ret, arg1); |
| 395 | } else { | 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,7 +447,9 @@ static inline void tcg_gen_shli_i32(TCGv ret, TCGv arg1, int32_t arg2) | ||
| 407 | if (arg2 == 0) { | 447 | if (arg2 == 0) { |
| 408 | tcg_gen_mov_i32(ret, arg1); | 448 | tcg_gen_mov_i32(ret, arg1); |
| 409 | } else { | 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,7 +463,9 @@ static inline void tcg_gen_shri_i32(TCGv ret, TCGv arg1, int32_t arg2) | ||
| 421 | if (arg2 == 0) { | 463 | if (arg2 == 0) { |
| 422 | tcg_gen_mov_i32(ret, arg1); | 464 | tcg_gen_mov_i32(ret, arg1); |
| 423 | } else { | 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,7 +479,9 @@ static inline void tcg_gen_sari_i32(TCGv ret, TCGv arg1, int32_t arg2) | ||
| 435 | if (arg2 == 0) { | 479 | if (arg2 == 0) { |
| 436 | tcg_gen_mov_i32(ret, arg1); | 480 | tcg_gen_mov_i32(ret, arg1); |
| 437 | } else { | 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,7 +498,9 @@ static inline void tcg_gen_mul_i32(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 452 | 498 | ||
| 453 | static inline void tcg_gen_muli_i32(TCGv ret, TCGv arg1, int32_t arg2) | 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 | #ifdef TCG_TARGET_HAS_div_i32 | 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,6 +530,7 @@ static inline void tcg_gen_div_i32(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 482 | t0 = tcg_temp_new(TCG_TYPE_I32); | 530 | t0 = tcg_temp_new(TCG_TYPE_I32); |
| 483 | tcg_gen_sari_i32(t0, arg1, 31); | 531 | tcg_gen_sari_i32(t0, arg1, 31); |
| 484 | tcg_gen_op5(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2); | 532 | tcg_gen_op5(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2); |
| 533 | + tcg_temp_free(t0); | ||
| 485 | } | 534 | } |
| 486 | 535 | ||
| 487 | static inline void tcg_gen_rem_i32(TCGv ret, TCGv arg1, TCGv arg2) | 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,6 +539,7 @@ static inline void tcg_gen_rem_i32(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 490 | t0 = tcg_temp_new(TCG_TYPE_I32); | 539 | t0 = tcg_temp_new(TCG_TYPE_I32); |
| 491 | tcg_gen_sari_i32(t0, arg1, 31); | 540 | tcg_gen_sari_i32(t0, arg1, 31); |
| 492 | tcg_gen_op5(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2); | 541 | tcg_gen_op5(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2); |
| 542 | + tcg_temp_free(t0); | ||
| 493 | } | 543 | } |
| 494 | 544 | ||
| 495 | static inline void tcg_gen_divu_i32(TCGv ret, TCGv arg1, TCGv arg2) | 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,6 +548,7 @@ static inline void tcg_gen_divu_i32(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 498 | t0 = tcg_temp_new(TCG_TYPE_I32); | 548 | t0 = tcg_temp_new(TCG_TYPE_I32); |
| 499 | tcg_gen_movi_i32(t0, 0); | 549 | tcg_gen_movi_i32(t0, 0); |
| 500 | tcg_gen_op5(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2); | 550 | tcg_gen_op5(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2); |
| 551 | + tcg_temp_free(t0); | ||
| 501 | } | 552 | } |
| 502 | 553 | ||
| 503 | static inline void tcg_gen_remu_i32(TCGv ret, TCGv arg1, TCGv arg2) | 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,6 +557,7 @@ static inline void tcg_gen_remu_i32(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 506 | t0 = tcg_temp_new(TCG_TYPE_I32); | 557 | t0 = tcg_temp_new(TCG_TYPE_I32); |
| 507 | tcg_gen_movi_i32(t0, 0); | 558 | tcg_gen_movi_i32(t0, 0); |
| 508 | tcg_gen_op5(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2); | 559 | tcg_gen_op5(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2); |
| 560 | + tcg_temp_free(t0); | ||
| 509 | } | 561 | } |
| 510 | #endif | 562 | #endif |
| 511 | 563 | ||
| @@ -608,7 +660,9 @@ static inline void tcg_gen_add_i64(TCGv ret, TCGv arg1, TCGv arg2) | @@ -608,7 +660,9 @@ static inline void tcg_gen_add_i64(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 608 | 660 | ||
| 609 | static inline void tcg_gen_addi_i64(TCGv ret, TCGv arg1, int64_t arg2) | 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 | static inline void tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2) | 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,7 +673,9 @@ static inline void tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 619 | 673 | ||
| 620 | static inline void tcg_gen_subi_i64(TCGv ret, TCGv arg1, int64_t arg2) | 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 | static inline void tcg_gen_and_i64(TCGv ret, TCGv arg1, TCGv arg2) | 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,11 +769,15 @@ static inline void tcg_gen_mul_i64(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 713 | tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1); | 769 | tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1); |
| 714 | 770 | ||
| 715 | tcg_gen_mov_i64(ret, t0); | 771 | tcg_gen_mov_i64(ret, t0); |
| 772 | + tcg_temp_free(t0); | ||
| 773 | + tcg_temp_free(t1); | ||
| 716 | } | 774 | } |
| 717 | 775 | ||
| 718 | static inline void tcg_gen_muli_i64(TCGv ret, TCGv arg1, int64_t arg2) | 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 | static inline void tcg_gen_div_i64(TCGv ret, TCGv arg1, TCGv arg2) | 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,7 +884,9 @@ static inline void tcg_gen_add_i64(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 824 | 884 | ||
| 825 | static inline void tcg_gen_addi_i64(TCGv ret, TCGv arg1, int64_t arg2) | 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 | static inline void tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2) | 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,7 +896,9 @@ static inline void tcg_gen_sub_i64(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 834 | 896 | ||
| 835 | static inline void tcg_gen_subi_i64(TCGv ret, TCGv arg1, int64_t arg2) | 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 | static inline void tcg_gen_and_i64(TCGv ret, TCGv arg1, TCGv arg2) | 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,7 +908,9 @@ static inline void tcg_gen_and_i64(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 844 | 908 | ||
| 845 | static inline void tcg_gen_andi_i64(TCGv ret, TCGv arg1, int64_t arg2) | 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 | static inline void tcg_gen_or_i64(TCGv ret, TCGv arg1, TCGv arg2) | 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,7 +920,9 @@ static inline void tcg_gen_or_i64(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 854 | 920 | ||
| 855 | static inline void tcg_gen_ori_i64(TCGv ret, TCGv arg1, int64_t arg2) | 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 | static inline void tcg_gen_xor_i64(TCGv ret, TCGv arg1, TCGv arg2) | 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,7 +932,9 @@ static inline void tcg_gen_xor_i64(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 864 | 932 | ||
| 865 | static inline void tcg_gen_xori_i64(TCGv ret, TCGv arg1, int64_t arg2) | 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 | static inline void tcg_gen_shl_i64(TCGv ret, TCGv arg1, TCGv arg2) | 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,7 +947,9 @@ static inline void tcg_gen_shli_i64(TCGv ret, TCGv arg1, int64_t arg2) | ||
| 877 | if (arg2 == 0) { | 947 | if (arg2 == 0) { |
| 878 | tcg_gen_mov_i64(ret, arg1); | 948 | tcg_gen_mov_i64(ret, arg1); |
| 879 | } else { | 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,7 +963,9 @@ static inline void tcg_gen_shri_i64(TCGv ret, TCGv arg1, int64_t arg2) | ||
| 891 | if (arg2 == 0) { | 963 | if (arg2 == 0) { |
| 892 | tcg_gen_mov_i64(ret, arg1); | 964 | tcg_gen_mov_i64(ret, arg1); |
| 893 | } else { | 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,7 +979,9 @@ static inline void tcg_gen_sari_i64(TCGv ret, TCGv arg1, int64_t arg2) | ||
| 905 | if (arg2 == 0) { | 979 | if (arg2 == 0) { |
| 906 | tcg_gen_mov_i64(ret, arg1); | 980 | tcg_gen_mov_i64(ret, arg1); |
| 907 | } else { | 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,7 +998,9 @@ static inline void tcg_gen_mul_i64(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 922 | 998 | ||
| 923 | static inline void tcg_gen_muli_i64(TCGv ret, TCGv arg1, int64_t arg2) | 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 | #ifdef TCG_TARGET_HAS_div_i64 | 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,6 +1030,7 @@ static inline void tcg_gen_div_i64(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 952 | t0 = tcg_temp_new(TCG_TYPE_I64); | 1030 | t0 = tcg_temp_new(TCG_TYPE_I64); |
| 953 | tcg_gen_sari_i64(t0, arg1, 63); | 1031 | tcg_gen_sari_i64(t0, arg1, 63); |
| 954 | tcg_gen_op5(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2); | 1032 | tcg_gen_op5(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2); |
| 1033 | + tcg_temp_free(t0); | ||
| 955 | } | 1034 | } |
| 956 | 1035 | ||
| 957 | static inline void tcg_gen_rem_i64(TCGv ret, TCGv arg1, TCGv arg2) | 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,6 +1039,7 @@ static inline void tcg_gen_rem_i64(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 960 | t0 = tcg_temp_new(TCG_TYPE_I64); | 1039 | t0 = tcg_temp_new(TCG_TYPE_I64); |
| 961 | tcg_gen_sari_i64(t0, arg1, 63); | 1040 | tcg_gen_sari_i64(t0, arg1, 63); |
| 962 | tcg_gen_op5(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2); | 1041 | tcg_gen_op5(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2); |
| 1042 | + tcg_temp_free(t0); | ||
| 963 | } | 1043 | } |
| 964 | 1044 | ||
| 965 | static inline void tcg_gen_divu_i64(TCGv ret, TCGv arg1, TCGv arg2) | 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,6 +1048,7 @@ static inline void tcg_gen_divu_i64(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 968 | t0 = tcg_temp_new(TCG_TYPE_I64); | 1048 | t0 = tcg_temp_new(TCG_TYPE_I64); |
| 969 | tcg_gen_movi_i64(t0, 0); | 1049 | tcg_gen_movi_i64(t0, 0); |
| 970 | tcg_gen_op5(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2); | 1050 | tcg_gen_op5(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2); |
| 1051 | + tcg_temp_free(t0); | ||
| 971 | } | 1052 | } |
| 972 | 1053 | ||
| 973 | static inline void tcg_gen_remu_i64(TCGv ret, TCGv arg1, TCGv arg2) | 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,6 +1057,7 @@ static inline void tcg_gen_remu_i64(TCGv ret, TCGv arg1, TCGv arg2) | ||
| 976 | t0 = tcg_temp_new(TCG_TYPE_I64); | 1057 | t0 = tcg_temp_new(TCG_TYPE_I64); |
| 977 | tcg_gen_movi_i64(t0, 0); | 1058 | tcg_gen_movi_i64(t0, 0); |
| 978 | tcg_gen_op5(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2); | 1059 | tcg_gen_op5(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2); |
| 1060 | + tcg_temp_free(t0); | ||
| 979 | } | 1061 | } |
| 980 | #endif | 1062 | #endif |
| 981 | 1063 | ||
| @@ -1030,6 +1112,8 @@ static inline void tcg_gen_bswap16_i32(TCGv ret, TCGv arg) | @@ -1030,6 +1112,8 @@ static inline void tcg_gen_bswap16_i32(TCGv ret, TCGv arg) | ||
| 1030 | tcg_gen_andi_i32(t1, arg, 0x000000ff); | 1112 | tcg_gen_andi_i32(t1, arg, 0x000000ff); |
| 1031 | tcg_gen_shli_i32(t1, t1, 8); | 1113 | tcg_gen_shli_i32(t1, t1, 8); |
| 1032 | tcg_gen_or_i32(ret, t0, t1); | 1114 | tcg_gen_or_i32(ret, t0, t1); |
| 1115 | + tcg_temp_free(t0); | ||
| 1116 | + tcg_temp_free(t1); | ||
| 1033 | #endif | 1117 | #endif |
| 1034 | } | 1118 | } |
| 1035 | 1119 | ||
| @@ -1054,6 +1138,8 @@ static inline void tcg_gen_bswap_i32(TCGv ret, TCGv arg) | @@ -1054,6 +1138,8 @@ static inline void tcg_gen_bswap_i32(TCGv ret, TCGv arg) | ||
| 1054 | 1138 | ||
| 1055 | tcg_gen_shri_i32(t1, arg, 24); | 1139 | tcg_gen_shri_i32(t1, arg, 24); |
| 1056 | tcg_gen_or_i32(ret, t0, t1); | 1140 | tcg_gen_or_i32(ret, t0, t1); |
| 1141 | + tcg_temp_free(t0); | ||
| 1142 | + tcg_temp_free(t1); | ||
| 1057 | #endif | 1143 | #endif |
| 1058 | } | 1144 | } |
| 1059 | 1145 | ||
| @@ -1121,6 +1207,8 @@ static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg) | @@ -1121,6 +1207,8 @@ static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg) | ||
| 1121 | tcg_gen_bswap_i32(t1, TCGV_HIGH(arg)); | 1207 | tcg_gen_bswap_i32(t1, TCGV_HIGH(arg)); |
| 1122 | tcg_gen_mov_i32(ret, t1); | 1208 | tcg_gen_mov_i32(ret, t1); |
| 1123 | tcg_gen_mov_i32(TCGV_HIGH(ret), t0); | 1209 | tcg_gen_mov_i32(TCGV_HIGH(ret), t0); |
| 1210 | + tcg_temp_free(t0); | ||
| 1211 | + tcg_temp_free(t1); | ||
| 1124 | } | 1212 | } |
| 1125 | #else | 1213 | #else |
| 1126 | 1214 | ||
| @@ -1227,6 +1315,8 @@ static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg) | @@ -1227,6 +1315,8 @@ static inline void tcg_gen_bswap_i64(TCGv ret, TCGv arg) | ||
| 1227 | 1315 | ||
| 1228 | tcg_gen_shri_i64(t1, arg, 56); | 1316 | tcg_gen_shri_i64(t1, arg, 56); |
| 1229 | tcg_gen_or_i64(ret, t0, t1); | 1317 | tcg_gen_or_i64(ret, t0, t1); |
| 1318 | + tcg_temp_free(t0); | ||
| 1319 | + tcg_temp_free(t1); | ||
| 1230 | #endif | 1320 | #endif |
| 1231 | } | 1321 | } |
| 1232 | 1322 | ||
| @@ -1237,7 +1327,9 @@ static inline void tcg_gen_neg_i32(TCGv ret, TCGv arg) | @@ -1237,7 +1327,9 @@ static inline void tcg_gen_neg_i32(TCGv ret, TCGv arg) | ||
| 1237 | #ifdef TCG_TARGET_HAS_neg_i32 | 1327 | #ifdef TCG_TARGET_HAS_neg_i32 |
| 1238 | tcg_gen_op2(INDEX_op_neg_i32, ret, arg); | 1328 | tcg_gen_op2(INDEX_op_neg_i32, ret, arg); |
| 1239 | #else | 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 | #endif | 1333 | #endif |
| 1242 | } | 1334 | } |
| 1243 | 1335 | ||
| @@ -1246,18 +1338,20 @@ static inline void tcg_gen_neg_i64(TCGv ret, TCGv arg) | @@ -1246,18 +1338,20 @@ static inline void tcg_gen_neg_i64(TCGv ret, TCGv arg) | ||
| 1246 | #ifdef TCG_TARGET_HAS_neg_i64 | 1338 | #ifdef TCG_TARGET_HAS_neg_i64 |
| 1247 | tcg_gen_op2(INDEX_op_neg_i64, ret, arg); | 1339 | tcg_gen_op2(INDEX_op_neg_i64, ret, arg); |
| 1248 | #else | 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 | #endif | 1344 | #endif |
| 1251 | } | 1345 | } |
| 1252 | 1346 | ||
| 1253 | static inline void tcg_gen_not_i32(TCGv ret, TCGv arg) | 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 | static inline void tcg_gen_not_i64(TCGv ret, TCGv arg) | 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 | static inline void tcg_gen_discard_i32(TCGv arg) | 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,8 +266,11 @@ void tcg_set_macro_func(TCGContext *s, TCGMacroFunc *func) | ||
| 266 | 266 | ||
| 267 | void tcg_func_start(TCGContext *s) | 267 | void tcg_func_start(TCGContext *s) |
| 268 | { | 268 | { |
| 269 | + int i; | ||
| 269 | tcg_pool_reset(s); | 270 | tcg_pool_reset(s); |
| 270 | s->nb_temps = s->nb_globals; | 271 | s->nb_temps = s->nb_globals; |
| 272 | + for(i = 0; i < TCG_TYPE_COUNT; i++) | ||
| 273 | + s->first_free_temp[i] = -1; | ||
| 271 | s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS); | 274 | s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS); |
| 272 | s->nb_labels = 0; | 275 | s->nb_labels = 0; |
| 273 | s->current_frame_offset = s->frame_start; | 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,7 +304,6 @@ TCGv tcg_global_reg_new(TCGType type, int reg, const char *name) | ||
| 301 | ts->type = type; | 304 | ts->type = type; |
| 302 | ts->fixed_reg = 1; | 305 | ts->fixed_reg = 1; |
| 303 | ts->reg = reg; | 306 | ts->reg = reg; |
| 304 | - ts->val_type = TEMP_VAL_REG; | ||
| 305 | ts->name = name; | 307 | ts->name = name; |
| 306 | s->nb_globals++; | 308 | s->nb_globals++; |
| 307 | tcg_regset_set_reg(s->reserved_regs, reg); | 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,7 +329,6 @@ TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2, | ||
| 327 | ts->type = TCG_TYPE_I32; | 329 | ts->type = TCG_TYPE_I32; |
| 328 | ts->fixed_reg = 1; | 330 | ts->fixed_reg = 1; |
| 329 | ts->reg = reg1; | 331 | ts->reg = reg1; |
| 330 | - ts->val_type = TEMP_VAL_REG; | ||
| 331 | pstrcpy(buf, sizeof(buf), name); | 332 | pstrcpy(buf, sizeof(buf), name); |
| 332 | pstrcat(buf, sizeof(buf), "_0"); | 333 | pstrcat(buf, sizeof(buf), "_0"); |
| 333 | ts->name = strdup(buf); | 334 | ts->name = strdup(buf); |
| @@ -337,7 +338,6 @@ TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2, | @@ -337,7 +338,6 @@ TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2, | ||
| 337 | ts->type = TCG_TYPE_I32; | 338 | ts->type = TCG_TYPE_I32; |
| 338 | ts->fixed_reg = 1; | 339 | ts->fixed_reg = 1; |
| 339 | ts->reg = reg2; | 340 | ts->reg = reg2; |
| 340 | - ts->val_type = TEMP_VAL_REG; | ||
| 341 | pstrcpy(buf, sizeof(buf), name); | 341 | pstrcpy(buf, sizeof(buf), name); |
| 342 | pstrcat(buf, sizeof(buf), "_1"); | 342 | pstrcat(buf, sizeof(buf), "_1"); |
| 343 | ts->name = strdup(buf); | 343 | ts->name = strdup(buf); |
| @@ -370,7 +370,6 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset, | @@ -370,7 +370,6 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset, | ||
| 370 | #else | 370 | #else |
| 371 | ts->mem_offset = offset; | 371 | ts->mem_offset = offset; |
| 372 | #endif | 372 | #endif |
| 373 | - ts->val_type = TEMP_VAL_MEM; | ||
| 374 | pstrcpy(buf, sizeof(buf), name); | 373 | pstrcpy(buf, sizeof(buf), name); |
| 375 | pstrcat(buf, sizeof(buf), "_0"); | 374 | pstrcat(buf, sizeof(buf), "_0"); |
| 376 | ts->name = strdup(buf); | 375 | ts->name = strdup(buf); |
| @@ -386,7 +385,6 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset, | @@ -386,7 +385,6 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset, | ||
| 386 | #else | 385 | #else |
| 387 | ts->mem_offset = offset + 4; | 386 | ts->mem_offset = offset + 4; |
| 388 | #endif | 387 | #endif |
| 389 | - ts->val_type = TEMP_VAL_MEM; | ||
| 390 | pstrcpy(buf, sizeof(buf), name); | 388 | pstrcpy(buf, sizeof(buf), name); |
| 391 | pstrcat(buf, sizeof(buf), "_1"); | 389 | pstrcat(buf, sizeof(buf), "_1"); |
| 392 | ts->name = strdup(buf); | 390 | ts->name = strdup(buf); |
| @@ -403,7 +401,6 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset, | @@ -403,7 +401,6 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset, | ||
| 403 | ts->mem_allocated = 1; | 401 | ts->mem_allocated = 1; |
| 404 | ts->mem_reg = reg; | 402 | ts->mem_reg = reg; |
| 405 | ts->mem_offset = offset; | 403 | ts->mem_offset = offset; |
| 406 | - ts->val_type = TEMP_VAL_MEM; | ||
| 407 | ts->name = name; | 404 | ts->name = name; |
| 408 | s->nb_globals++; | 405 | s->nb_globals++; |
| 409 | } | 406 | } |
| @@ -416,90 +413,75 @@ TCGv tcg_temp_new(TCGType type) | @@ -416,90 +413,75 @@ TCGv tcg_temp_new(TCGType type) | ||
| 416 | TCGTemp *ts; | 413 | TCGTemp *ts; |
| 417 | int idx; | 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 | #if TCG_TARGET_REG_BITS == 32 | 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 | #endif | 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 | return MAKE_TCGV(idx); | 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 | TCGContext *s = &tcg_ctx; | 456 | TCGContext *s = &tcg_ctx; |
| 457 | TCGTemp *ts; | 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 | ts = &s->temps[idx]; | 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 | void tcg_register_helper(void *func, const char *name) | 487 | void tcg_register_helper(void *func, const char *name) |
| @@ -663,6 +645,8 @@ void tcg_gen_shifti_i64(TCGv ret, TCGv arg1, | @@ -663,6 +645,8 @@ void tcg_gen_shifti_i64(TCGv ret, TCGv arg1, | ||
| 663 | tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0); | 645 | tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t0); |
| 664 | tcg_gen_mov_i32(ret, t1); | 646 | tcg_gen_mov_i32(ret, t1); |
| 665 | } | 647 | } |
| 648 | + tcg_temp_free(t0); | ||
| 649 | + tcg_temp_free(t1); | ||
| 666 | } | 650 | } |
| 667 | } | 651 | } |
| 668 | #endif | 652 | #endif |
| @@ -679,6 +663,12 @@ void tcg_reg_alloc_start(TCGContext *s) | @@ -679,6 +663,12 @@ void tcg_reg_alloc_start(TCGContext *s) | ||
| 679 | ts->val_type = TEMP_VAL_MEM; | 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 | for(i = 0; i < TCG_TARGET_NB_REGS; i++) { | 672 | for(i = 0; i < TCG_TARGET_NB_REGS; i++) { |
| 683 | s->reg_to_temp[i] = -1; | 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,11 +683,7 @@ static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size, | ||
| 693 | if (idx < s->nb_globals) { | 683 | if (idx < s->nb_globals) { |
| 694 | pstrcpy(buf, buf_size, ts->name); | 684 | pstrcpy(buf, buf_size, ts->name); |
| 695 | } else { | 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 | return buf; | 688 | return buf; |
| 703 | } | 689 | } |
| @@ -707,37 +693,49 @@ char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg) | @@ -707,37 +693,49 @@ char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg) | ||
| 707 | return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV(arg)); | 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 | TCGHelperInfo *th; | 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 | void tcg_dump_ops(TCGContext *s, FILE *outfile) | 739 | void tcg_dump_ops(TCGContext *s, FILE *outfile) |
| 742 | { | 740 | { |
| 743 | const uint16_t *opc_ptr; | 741 | const uint16_t *opc_ptr; |
| @@ -780,7 +778,7 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) | @@ -780,7 +778,7 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) | ||
| 780 | 778 | ||
| 781 | /* function name */ | 779 | /* function name */ |
| 782 | fprintf(outfile, "%s", | 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 | /* flags */ | 782 | /* flags */ |
| 785 | fprintf(outfile, ",$0x%" TCG_PRIlx, | 783 | fprintf(outfile, ",$0x%" TCG_PRIlx, |
| 786 | args[nb_oargs + nb_iargs]); | 784 | args[nb_oargs + nb_iargs]); |
| @@ -800,6 +798,29 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) | @@ -800,6 +798,29 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile) | ||
| 800 | tcg_get_arg_str_idx(s, buf, sizeof(buf), args[nb_oargs + i])); | 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 | } else { | 824 | } else { |
| 804 | fprintf(outfile, " %s ", def->name); | 825 | fprintf(outfile, " %s ", def->name); |
| 805 | if (c == INDEX_op_nopn) { | 826 | if (c == INDEX_op_nopn) { |
| @@ -1281,11 +1302,6 @@ static void check_regs(TCGContext *s) | @@ -1281,11 +1302,6 @@ static void check_regs(TCGContext *s) | ||
| 1281 | dump_regs(s); | 1302 | dump_regs(s); |
| 1282 | tcg_abort(); | 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 | #endif | 1307 | #endif |
| @@ -1351,47 +1367,80 @@ static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2) | @@ -1351,47 +1367,80 @@ static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2) | ||
| 1351 | } | 1367 | } |
| 1352 | 1368 | ||
| 1353 | /* save globals to their cannonical location and assume they can be | 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 | TCGTemp *ts; | 1374 | TCGTemp *ts; |
| 1358 | - int i; | 1375 | + int i, reg; |
| 1359 | 1376 | ||
| 1360 | for(i = 0; i < s->nb_globals; i++) { | 1377 | for(i = 0; i < s->nb_globals; i++) { |
| 1361 | ts = &s->temps[i]; | 1378 | ts = &s->temps[i]; |
| 1362 | if (!ts->fixed_reg) { | 1379 | if (!ts->fixed_reg) { |
| 1363 | - if (ts->val_type == TEMP_VAL_REG) { | 1380 | + switch(ts->val_type) { |
| 1381 | + case TEMP_VAL_REG: | ||
| 1364 | tcg_reg_free(s, ts->reg); | 1382 | tcg_reg_free(s, ts->reg); |
| 1365 | - } else if (ts->val_type == TEMP_VAL_DEAD) { | 1383 | + break; |
| 1384 | + case TEMP_VAL_DEAD: | ||
| 1366 | ts->val_type = TEMP_VAL_MEM; | 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 | /* at the end of a basic block, we assume all temporaries are dead and | 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 | TCGTemp *ts; | 1407 | TCGTemp *ts; |
| 1378 | int i; | 1408 | int i; |
| 1379 | 1409 | ||
| 1380 | - save_globals(s); | ||
| 1381 | - | ||
| 1382 | for(i = s->nb_globals; i < s->nb_temps; i++) { | 1410 | for(i = s->nb_globals; i < s->nb_temps; i++) { |
| 1383 | ts = &s->temps[i]; | 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 | #define IS_DEAD_IARG(n) ((dead_iargs >> (n)) & 1) | 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 | static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, | 1444 | static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, |
| 1396 | const TCGArg *args, | 1445 | const TCGArg *args, |
| 1397 | unsigned int dead_iargs) | 1446 | unsigned int dead_iargs) |
| @@ -1404,6 +1453,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, | @@ -1404,6 +1453,7 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, | ||
| 1404 | ts = &s->temps[args[1]]; | 1453 | ts = &s->temps[args[1]]; |
| 1405 | arg_ct = &def->args_ct[0]; | 1454 | arg_ct = &def->args_ct[0]; |
| 1406 | 1455 | ||
| 1456 | + /* XXX: always mark arg dead if IS_DEAD_IARG(0) */ | ||
| 1407 | if (ts->val_type == TEMP_VAL_REG) { | 1457 | if (ts->val_type == TEMP_VAL_REG) { |
| 1408 | if (IS_DEAD_IARG(0) && !ts->fixed_reg && !ots->fixed_reg) { | 1458 | if (IS_DEAD_IARG(0) && !ts->fixed_reg && !ots->fixed_reg) { |
| 1409 | /* the mov can be suppressed */ | 1459 | /* the mov can be suppressed */ |
| @@ -1430,12 +1480,17 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, | @@ -1430,12 +1480,17 @@ static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def, | ||
| 1430 | } | 1480 | } |
| 1431 | tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset); | 1481 | tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset); |
| 1432 | } else if (ts->val_type == TEMP_VAL_CONST) { | 1482 | } else if (ts->val_type == TEMP_VAL_CONST) { |
| 1433 | - if (ots->val_type == TEMP_VAL_REG) { | 1483 | + if (ots->fixed_reg) { |
| 1434 | reg = ots->reg; | 1484 | reg = ots->reg; |
| 1485 | + tcg_out_movi(s, ots->type, reg, ts->val); | ||
| 1435 | } else { | 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 | } else { | 1494 | } else { |
| 1440 | tcg_abort(); | 1495 | tcg_abort(); |
| 1441 | } | 1496 | } |
| @@ -1487,10 +1542,13 @@ static void tcg_reg_alloc_op(TCGContext *s, | @@ -1487,10 +1542,13 @@ static void tcg_reg_alloc_op(TCGContext *s, | ||
| 1487 | new_args[i] = ts->val; | 1542 | new_args[i] = ts->val; |
| 1488 | goto iarg_end; | 1543 | goto iarg_end; |
| 1489 | } else { | 1544 | } else { |
| 1490 | - /* need to move to a register*/ | 1545 | + /* need to move to a register */ |
| 1491 | reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); | 1546 | reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); |
| 1492 | tcg_out_movi(s, ts->type, reg, ts->val); | 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 | assert(ts->val_type == TEMP_VAL_REG); | 1554 | assert(ts->val_type == TEMP_VAL_REG); |
| @@ -1518,78 +1576,78 @@ static void tcg_reg_alloc_op(TCGContext *s, | @@ -1518,78 +1576,78 @@ static void tcg_reg_alloc_op(TCGContext *s, | ||
| 1518 | reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); | 1576 | reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); |
| 1519 | tcg_out_mov(s, reg, ts->reg); | 1577 | tcg_out_mov(s, reg, ts->reg); |
| 1520 | } | 1578 | } |
| 1521 | - iarg_end1: | ||
| 1522 | new_args[i] = reg; | 1579 | new_args[i] = reg; |
| 1523 | const_args[i] = 0; | 1580 | const_args[i] = 0; |
| 1524 | tcg_regset_set_reg(allocated_regs, reg); | 1581 | tcg_regset_set_reg(allocated_regs, reg); |
| 1525 | iarg_end: ; | 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 | /* emit instruction */ | 1651 | /* emit instruction */ |
| 1594 | tcg_out_op(s, opc, new_args, const_args); | 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,6 +1766,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, | ||
| 1708 | reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); | 1766 | reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); |
| 1709 | tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset); | 1767 | tcg_out_ld(s, ts->type, reg, ts->mem_reg, ts->mem_offset); |
| 1710 | func_arg = reg; | 1768 | func_arg = reg; |
| 1769 | + tcg_regset_set_reg(allocated_regs, reg); | ||
| 1711 | } else if (ts->val_type == TEMP_VAL_REG) { | 1770 | } else if (ts->val_type == TEMP_VAL_REG) { |
| 1712 | reg = ts->reg; | 1771 | reg = ts->reg; |
| 1713 | if (!tcg_regset_test_reg(arg_ct->u.regs, reg)) { | 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,6 +1774,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, | ||
| 1715 | tcg_out_mov(s, reg, ts->reg); | 1774 | tcg_out_mov(s, reg, ts->reg); |
| 1716 | } | 1775 | } |
| 1717 | func_arg = reg; | 1776 | func_arg = reg; |
| 1777 | + tcg_regset_set_reg(allocated_regs, reg); | ||
| 1718 | } else if (ts->val_type == TEMP_VAL_CONST) { | 1778 | } else if (ts->val_type == TEMP_VAL_CONST) { |
| 1719 | if (tcg_target_const_match(func_addr, arg_ct)) { | 1779 | if (tcg_target_const_match(func_addr, arg_ct)) { |
| 1720 | const_func_arg = 1; | 1780 | const_func_arg = 1; |
| @@ -1723,17 +1783,19 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, | @@ -1723,17 +1783,19 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, | ||
| 1723 | reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); | 1783 | reg = tcg_reg_alloc(s, arg_ct->u.regs, allocated_regs); |
| 1724 | tcg_out_movi(s, ts->type, reg, func_addr); | 1784 | tcg_out_movi(s, ts->type, reg, func_addr); |
| 1725 | func_arg = reg; | 1785 | func_arg = reg; |
| 1786 | + tcg_regset_set_reg(allocated_regs, reg); | ||
| 1726 | } | 1787 | } |
| 1727 | } else { | 1788 | } else { |
| 1728 | tcg_abort(); | 1789 | tcg_abort(); |
| 1729 | } | 1790 | } |
| 1791 | + | ||
| 1730 | 1792 | ||
| 1731 | /* mark dead temporaries and free the associated registers */ | 1793 | /* mark dead temporaries and free the associated registers */ |
| 1732 | for(i = 0; i < nb_iargs; i++) { | 1794 | for(i = 0; i < nb_iargs; i++) { |
| 1733 | arg = args[nb_oargs + i]; | 1795 | arg = args[nb_oargs + i]; |
| 1734 | if (IS_DEAD_IARG(i)) { | 1796 | if (IS_DEAD_IARG(i)) { |
| 1735 | ts = &s->temps[arg]; | 1797 | ts = &s->temps[arg]; |
| 1736 | - if (ts->val_type != TEMP_VAL_CONST && !ts->fixed_reg) { | 1798 | + if (!ts->fixed_reg) { |
| 1737 | if (ts->val_type == TEMP_VAL_REG) | 1799 | if (ts->val_type == TEMP_VAL_REG) |
| 1738 | s->reg_to_temp[ts->reg] = -1; | 1800 | s->reg_to_temp[ts->reg] = -1; |
| 1739 | ts->val_type = TEMP_VAL_DEAD; | 1801 | ts->val_type = TEMP_VAL_DEAD; |
| @@ -1750,7 +1812,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, | @@ -1750,7 +1812,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, | ||
| 1750 | 1812 | ||
| 1751 | /* store globals and free associated registers (we assume the call | 1813 | /* store globals and free associated registers (we assume the call |
| 1752 | can modify any global. */ | 1814 | can modify any global. */ |
| 1753 | - save_globals(s); | 1815 | + save_globals(s, allocated_regs); |
| 1754 | 1816 | ||
| 1755 | tcg_out_op(s, opc, &func_arg, &const_func_arg); | 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,7 +1825,7 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, | ||
| 1763 | arg = args[i]; | 1825 | arg = args[i]; |
| 1764 | ts = &s->temps[arg]; | 1826 | ts = &s->temps[arg]; |
| 1765 | reg = tcg_target_call_oarg_regs[i]; | 1827 | reg = tcg_target_call_oarg_regs[i]; |
| 1766 | - tcg_reg_free(s, reg); | 1828 | + assert(s->reg_to_temp[reg] == -1); |
| 1767 | if (ts->fixed_reg) { | 1829 | if (ts->fixed_reg) { |
| 1768 | if (ts->reg != reg) { | 1830 | if (ts->reg != reg) { |
| 1769 | tcg_out_mov(s, ts->reg, reg); | 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,6 +1925,12 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, | ||
| 1863 | dead_iargs = s->op_dead_iargs[op_index]; | 1925 | dead_iargs = s->op_dead_iargs[op_index]; |
| 1864 | tcg_reg_alloc_mov(s, def, args, dead_iargs); | 1926 | tcg_reg_alloc_mov(s, def, args, dead_iargs); |
| 1865 | break; | 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 | case INDEX_op_debug_insn_start: | 1934 | case INDEX_op_debug_insn_start: |
| 1867 | /* debug instruction */ | 1935 | /* debug instruction */ |
| 1868 | break; | 1936 | break; |
| @@ -1879,7 +1947,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, | @@ -1879,7 +1947,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, | ||
| 1879 | TCGTemp *ts; | 1947 | TCGTemp *ts; |
| 1880 | ts = &s->temps[args[0]]; | 1948 | ts = &s->temps[args[0]]; |
| 1881 | /* mark the temporary as dead */ | 1949 | /* mark the temporary as dead */ |
| 1882 | - if (ts->val_type != TEMP_VAL_CONST && !ts->fixed_reg) { | 1950 | + if (!ts->fixed_reg) { |
| 1883 | if (ts->val_type == TEMP_VAL_REG) | 1951 | if (ts->val_type == TEMP_VAL_REG) |
| 1884 | s->reg_to_temp[ts->reg] = -1; | 1952 | s->reg_to_temp[ts->reg] = -1; |
| 1885 | ts->val_type = TEMP_VAL_DEAD; | 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,7 +1968,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, | ||
| 1900 | /* must never happen here */ | 1968 | /* must never happen here */ |
| 1901 | tcg_abort(); | 1969 | tcg_abort(); |
| 1902 | case INDEX_op_set_label: | 1970 | case INDEX_op_set_label: |
| 1903 | - tcg_reg_alloc_bb_end(s); | 1971 | + tcg_reg_alloc_bb_end(s, s->reserved_regs); |
| 1904 | tcg_out_label(s, args[0], (long)s->code_ptr); | 1972 | tcg_out_label(s, args[0], (long)s->code_ptr); |
| 1905 | break; | 1973 | break; |
| 1906 | case INDEX_op_call: | 1974 | case INDEX_op_call: |
| @@ -1916,7 +1984,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, | @@ -1916,7 +1984,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, | ||
| 1916 | #ifdef CONFIG_PROFILER | 1984 | #ifdef CONFIG_PROFILER |
| 1917 | s->old_op_count++; | 1985 | s->old_op_count++; |
| 1918 | #endif | 1986 | #endif |
| 1919 | - tcg_reg_alloc_bb_end(s); | 1987 | + tcg_reg_alloc_bb_end(s, s->reserved_regs); |
| 1920 | if (search_pc >= 0) { | 1988 | if (search_pc >= 0) { |
| 1921 | s->code_ptr += def->copy_size; | 1989 | s->code_ptr += def->copy_size; |
| 1922 | args += def->nb_args; | 1990 | args += def->nb_args; |
tcg/tcg.h
| @@ -98,6 +98,7 @@ typedef int TCGType; | @@ -98,6 +98,7 @@ typedef int TCGType; | ||
| 98 | 98 | ||
| 99 | #define TCG_TYPE_I32 0 | 99 | #define TCG_TYPE_I32 0 |
| 100 | #define TCG_TYPE_I64 1 | 100 | #define TCG_TYPE_I64 1 |
| 101 | +#define TCG_TYPE_COUNT 2 /* number of different types */ | ||
| 101 | 102 | ||
| 102 | #if TCG_TARGET_REG_BITS == 32 | 103 | #if TCG_TARGET_REG_BITS == 32 |
| 103 | #define TCG_TYPE_PTR TCG_TYPE_I32 | 104 | #define TCG_TYPE_PTR TCG_TYPE_I32 |
| @@ -188,6 +189,9 @@ typedef struct TCGTemp { | @@ -188,6 +189,9 @@ typedef struct TCGTemp { | ||
| 188 | unsigned int fixed_reg:1; | 189 | unsigned int fixed_reg:1; |
| 189 | unsigned int mem_coherent:1; | 190 | unsigned int mem_coherent:1; |
| 190 | unsigned int mem_allocated:1; | 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 | const char *name; | 195 | const char *name; |
| 192 | } TCGTemp; | 196 | } TCGTemp; |
| 193 | 197 | ||
| @@ -208,6 +212,8 @@ struct TCGContext { | @@ -208,6 +212,8 @@ struct TCGContext { | ||
| 208 | TCGTemp *temps; /* globals first, temps after */ | 212 | TCGTemp *temps; /* globals first, temps after */ |
| 209 | int nb_globals; | 213 | int nb_globals; |
| 210 | int nb_temps; | 214 | int nb_temps; |
| 215 | + int first_free_temp[TCG_TYPE_COUNT]; /* index of free temps, -1 if none */ | ||
| 216 | + | ||
| 211 | /* constant indexes (end of temp array) */ | 217 | /* constant indexes (end of temp array) */ |
| 212 | int const_start; | 218 | int const_start; |
| 213 | int const_end; | 219 | int const_end; |
| @@ -236,6 +242,7 @@ struct TCGContext { | @@ -236,6 +242,7 @@ struct TCGContext { | ||
| 236 | TCGHelperInfo *helpers; | 242 | TCGHelperInfo *helpers; |
| 237 | int nb_helpers; | 243 | int nb_helpers; |
| 238 | int allocated_helpers; | 244 | int allocated_helpers; |
| 245 | + int helpers_sorted; | ||
| 239 | 246 | ||
| 240 | #ifdef CONFIG_PROFILER | 247 | #ifdef CONFIG_PROFILER |
| 241 | /* profiling info */ | 248 | /* profiling info */ |
| @@ -299,6 +306,7 @@ TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2, | @@ -299,6 +306,7 @@ TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2, | ||
| 299 | TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset, | 306 | TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset, |
| 300 | const char *name); | 307 | const char *name); |
| 301 | TCGv tcg_temp_new(TCGType type); | 308 | TCGv tcg_temp_new(TCGType type); |
| 309 | +void tcg_temp_free(TCGv arg); | ||
| 302 | char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg); | 310 | char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg); |
| 303 | void tcg_dump_info(FILE *f, | 311 | void tcg_dump_info(FILE *f, |
| 304 | int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); | 312 | int (*cpu_fprintf)(FILE *f, const char *fmt, ...)); |
| @@ -381,9 +389,6 @@ TCGv tcg_const_i64(int64_t val); | @@ -381,9 +389,6 @@ TCGv tcg_const_i64(int64_t val); | ||
| 381 | 389 | ||
| 382 | void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type, | 390 | void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type, |
| 383 | int label_index, long addend); | 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 | const TCGArg *tcg_gen_code_op(TCGContext *s, int opc, const TCGArg *args1, | 392 | const TCGArg *tcg_gen_code_op(TCGContext *s, int opc, const TCGArg *args1, |
| 388 | unsigned int dead_iargs); | 393 | unsigned int dead_iargs); |
| 389 | 394 |