Revision cd54be5f target-arm/translate-a64.c

b/target-arm/translate-a64.c
3367 3367
    }
3368 3368
}
3369 3369

  
3370
/* C3.6.27 Floating-point data-processing (3 source) - single precision */
3371
static void handle_fp_3src_single(DisasContext *s, bool o0, bool o1,
3372
                                  int rd, int rn, int rm, int ra)
3373
{
3374
    TCGv_i32 tcg_op1, tcg_op2, tcg_op3;
3375
    TCGv_i32 tcg_res = tcg_temp_new_i32();
3376
    TCGv_ptr fpst = get_fpstatus_ptr();
3377

  
3378
    tcg_op1 = read_fp_sreg(s, rn);
3379
    tcg_op2 = read_fp_sreg(s, rm);
3380
    tcg_op3 = read_fp_sreg(s, ra);
3381

  
3382
    /* These are fused multiply-add, and must be done as one
3383
     * floating point operation with no rounding between the
3384
     * multiplication and addition steps.
3385
     * NB that doing the negations here as separate steps is
3386
     * correct : an input NaN should come out with its sign bit
3387
     * flipped if it is a negated-input.
3388
     */
3389
    if (o1 == true) {
3390
        gen_helper_vfp_negs(tcg_op3, tcg_op3);
3391
    }
3392

  
3393
    if (o0 != o1) {
3394
        gen_helper_vfp_negs(tcg_op1, tcg_op1);
3395
    }
3396

  
3397
    gen_helper_vfp_muladds(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst);
3398

  
3399
    write_fp_sreg(s, rd, tcg_res);
3400

  
3401
    tcg_temp_free_ptr(fpst);
3402
    tcg_temp_free_i32(tcg_op1);
3403
    tcg_temp_free_i32(tcg_op2);
3404
    tcg_temp_free_i32(tcg_op3);
3405
    tcg_temp_free_i32(tcg_res);
3406
}
3407

  
3408
/* C3.6.27 Floating-point data-processing (3 source) - double precision */
3409
static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1,
3410
                                  int rd, int rn, int rm, int ra)
3411
{
3412
    TCGv_i64 tcg_op1, tcg_op2, tcg_op3;
3413
    TCGv_i64 tcg_res = tcg_temp_new_i64();
3414
    TCGv_ptr fpst = get_fpstatus_ptr();
3415

  
3416
    tcg_op1 = read_fp_dreg(s, rn);
3417
    tcg_op2 = read_fp_dreg(s, rm);
3418
    tcg_op3 = read_fp_dreg(s, ra);
3419

  
3420
    /* These are fused multiply-add, and must be done as one
3421
     * floating point operation with no rounding between the
3422
     * multiplication and addition steps.
3423
     * NB that doing the negations here as separate steps is
3424
     * correct : an input NaN should come out with its sign bit
3425
     * flipped if it is a negated-input.
3426
     */
3427
    if (o1 == true) {
3428
        gen_helper_vfp_negd(tcg_op3, tcg_op3);
3429
    }
3430

  
3431
    if (o0 != o1) {
3432
        gen_helper_vfp_negd(tcg_op1, tcg_op1);
3433
    }
3434

  
3435
    gen_helper_vfp_muladdd(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst);
3436

  
3437
    write_fp_dreg(s, rd, tcg_res);
3438

  
3439
    tcg_temp_free_ptr(fpst);
3440
    tcg_temp_free_i64(tcg_op1);
3441
    tcg_temp_free_i64(tcg_op2);
3442
    tcg_temp_free_i64(tcg_op3);
3443
    tcg_temp_free_i64(tcg_res);
3444
}
3445

  
3370 3446
/* C3.6.27 Floating point data-processing (3 source)
3371 3447
 *   31  30  29 28       24 23  22  21  20  16  15  14  10 9    5 4    0
3372 3448
 * +---+---+---+-----------+------+----+------+----+------+------+------+
......
3375 3451
 */
3376 3452
static void disas_fp_3src(DisasContext *s, uint32_t insn)
3377 3453
{
3378
    unsupported_encoding(s, insn);
3454
    int type = extract32(insn, 22, 2);
3455
    int rd = extract32(insn, 0, 5);
3456
    int rn = extract32(insn, 5, 5);
3457
    int ra = extract32(insn, 10, 5);
3458
    int rm = extract32(insn, 16, 5);
3459
    bool o0 = extract32(insn, 15, 1);
3460
    bool o1 = extract32(insn, 21, 1);
3461

  
3462
    switch (type) {
3463
    case 0:
3464
        handle_fp_3src_single(s, o0, o1, rd, rn, rm, ra);
3465
        break;
3466
    case 1:
3467
        handle_fp_3src_double(s, o0, o1, rd, rn, rm, ra);
3468
        break;
3469
    default:
3470
        unallocated_encoding(s);
3471
    }
3379 3472
}
3380 3473

  
3381 3474
/* C3.6.28 Floating point immediate

Also available in: Unified diff