fsh

Half-precision floating-point store

Assembly format

fsh rs2, imm12($rs1)

Synopsis

The fsh instruction stores a half-precision floating-point value from register rd to memory at address rs1 + imm.

fsh does not modify the bits being transferred; in particular, the payloads of non-canonical NaNs are preserved.

fsh ignores all but the lower 16 bits in rs2.

fsh is only guaranteed to execute atomically if the effective address is naturally aligned.

Decode Variables

Bits<12> imm = {$encoding[31:25], $encoding[11:7]};
Bits<5> rs1 = $encoding[19:15];
Bits<5> fs2 = $encoding[24:20];

Execution

  • IDL

  • Sail

check_f_ok($encoding);
XReg virtual_address = X[rs1] + $signed(imm);
Bits<16> hp_value = f[fs2][15:0];
write_memory<16>(virtual_address, hp_value, $encoding);
{
  let offset : xlenbits = sign_extend(imm);
  let (aq, rl, con) = (false, false, false);
  /* Get the address, X(rs1) + offset.
     Some extensions perform additional checks on address validity. */
  match ext_data_get_addr(rs1, offset, Write(Data), width) {
    Ext_DataAddr_Error(e)  => { ext_handle_data_check_error(e); RETIRE_FAIL },
    Ext_DataAddr_OK(vaddr) =>
      if   check_misaligned(vaddr, width)
      then { handle_mem_exception(vaddr, E_SAMO_Addr_Align()); RETIRE_FAIL }
      else match translateAddr(vaddr, Write(Data)) {
        TR_Failure(e, _)    => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
        TR_Address(addr, _) => {
          let eares : MemoryOpResult(unit) = match width {
            BYTE   => MemValue () /* bogus placeholder for illegal size */,
            HALF   => mem_write_ea(addr, 2, aq, rl, false),
            WORD   => mem_write_ea(addr, 4, aq, rl, false),
            DOUBLE => mem_write_ea(addr, 8, aq, rl, false)
          };
          match (eares) {
            MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
            MemValue(_) => {
              let rs2_val = F(rs2);
              match (width) {
                BYTE => { handle_illegal(); RETIRE_FAIL },
                HALF => process_fstore (vaddr, mem_write_value(addr, 2, rs2_val[15..0], aq, rl, con)),
                WORD => process_fstore (vaddr, mem_write_value(addr, 4, rs2_val[31..0], aq, rl, con)),
                DOUBLE if sizeof(flen) >= 64 =>
                  process_fstore (vaddr, mem_write_value(addr, 8, rs2_val, aq, rl, con)),
                _ => report_invalid_width(__FILE__, __LINE__, width, "floating point store"),
              };
            }
          }
        }
      }
  }
}

Exceptions

This instruction may result in the following synchronous exceptions:

  • IllegalInstruction

  • LoadAccessFault

  • StoreAmoAccessFault

  • StoreAmoAddressMisaligned

  • StoreAmoPageFault

Encoding

svg

Defining extension

  • anyOf:

    • Zfh, version >= Zfh@1.0.0

    • Zfhmin, version >= Zfhmin@1.0.0

    • Zhinx, version >= Zhinx@1.0.0

Access

M HS U VS VU

Always

Always

Always

Always

Always

Containing profiles

  • Mandatory: RVA22S64, RVA22U64, RVA23M64, RVA23S64, RVA23U64

  • Optional: RVB23M64, RVB23S64, RVB23U64