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