flw
Single-precision floating-point load
This instruction is defined by:
-
F, version >= 0
This instruction is included in the following profiles:
-
RVA20U64 (Mandatory)
-
RVA22U64 (Mandatory)
-
RVI20U32 (Optional)
-
RVI20U64 (Optional)
Synopsis
This instruction must have data-independent timing when extension Zkt is enabled. |
The flw instruction loads a single-precision floating-point value from memory at address rs1 + imm into floating-point register fd.
flw does not modify the bits being transferred; in particular, the payloads of non-canonical NaNs are preserved.
Decode Variables
Bits<12> imm = $encoding[31:20];
Bits<5> rs1 = $encoding[19:15];
Bits<5> fd = $encoding[11:7];
Execution
-
IDL
-
Sail
check_f_ok($encoding);
XReg virtual_address = X[rs1] + $signed(imm);
Bits<32> sp_value = read_memory<32>(virtual_address, $encoding);
if (implemented?(ExtensionName::D)) {
f[fd] = nan_box<32, 64>(sp_value);
} else {
f[fd] = sp_value;
}
mark_f_state_dirty();
{
let offset : xlenbits = sign_extend(imm);
/* Get the address, X(rs1) + offset.
Some extensions perform additional checks on address validity. */
match ext_data_get_addr(rs1, offset, Read(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_Load_Addr_Align()); RETIRE_FAIL }
else match translateAddr(vaddr, Read(Data)) {
TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
TR_Address(addr, _) => {
let (aq, rl, res) = (false, false, false);
match (width) {
BYTE => { handle_illegal(); RETIRE_FAIL },
HALF =>
process_fload16(rd, vaddr, mem_read(Read(Data), addr, 2, aq, rl, res)),
WORD =>
process_fload32(rd, vaddr, mem_read(Read(Data), addr, 4, aq, rl, res)),
DOUBLE if sizeof(flen) >= 64 =>
process_fload64(rd, vaddr, mem_read(Read(Data), addr, 8, aq, rl, res)),
_ => report_invalid_width(__FILE__, __LINE__, width, "floating point load"),
}
}
}
}
}