Revision e8996ee0 tcg/tcg.c

b/tcg/tcg.c
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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;

Also available in: Unified diff