fcvt.s.h

Convert single-precision float to a half-precision float

This instruction is defined by:

  • anyOf:

    • Zfh, version >= 0

    • Zfhmin, version >= 0

This instruction is included in the following profiles:

  • RVA22S64 (Mandatory)

  • RVA22U64 (Mandatory)

Encoding

svg

Assembly format

fcvt.s.h fd, rs1

Synopsis

Converts a single-precision number in floating-point register fs1 into a half-precision floating-point number in floating-point register fd.

fcvt.s.h will never round, and so the 'rm' field is effectively ignored.

Access

M HS U VS VU

Always

Always

Always

Always

Always

Decode Variables

Bits<5> fs1 = $encoding[19:15];
Bits<3> rm = $encoding[14:12];
Bits<5> fd = $encoding[11:7];

Execution

  • IDL

  • Sail

check_f_ok($encoding);
Bits<32> sp_value = f[fs1][31:0];
Bits<1> sign = sp_value[31];
Bits<8> exp = sp_value[30:23];
Bits<23> frac = sp_value[22:0];
if (exp == 0xFF) {
  if (frac != 0) {
    if ((sp_value & 0x00400000) != 0) {
      set_fp_flag(FpFlag::NV);
    }
    f[fd] = nan_box<16, FLEN>(HP_CANONICAL_NAN);
  } else {
    f[fd] = nan_box<16, FLEN>(packToF16UI(sign, 0x1F, 0));
  }
} else {
  Bits<16> frac16 = (frac >> 9) | frac & 0x1ff) != 0 ? 1 : 0);   if ((exp | frac16) == 0) {     f[fd] = nan_box<16, FLEN>(packToF16UI(sign, 0, 0;
  } else {
    assert(false, "TODO: implement roundPackToF16");
  }
}
mark_f_state_dirty();
{
  assert(sizeof(xlen) >= 64);
  let rs1_val_LU = X(rs1)[63..0];
  match (select_instr_or_fcsr_rm (rm)) {
    None() => { handle_illegal(); RETIRE_FAIL },
    Some(rm') => {
      let rm_3b = encdec_rounding_mode(rm');
      let (fflags, rd_val_H) = riscv_ui64ToF16 (rm_3b, rs1_val_LU);

      accrue_fflags(fflags);
      F_or_X_H(rd) = rd_val_H;
      RETIRE_SUCCESS
    }
  }
}

Exceptions

This instruction may result in the following synchronous exceptions:

  • IllegalInstruction