fsh
Half-precision floating-point store
This instruction is defined by:
-
anyOf:
-
Zfh, version >= 0
-
Zfhmin, version >= 0
-
This instruction is included in the following profiles:
-
RVA22S64 (Mandatory)
-
RVA22U64 (Mandatory)
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"),
};
}
}
}
}
}
}