sd
Store doubleword
For RV64, store 64 bits of data from register xs2
to an
address formed by adding xs1
to a signed offset.
<% if ext?(:Zilsd) %>
For RV32, store doubleword from even/odd register pair.
<% end %>
Decode Variables
-
RV32
-
RV64
Bits<12> imm = {$encoding[31:25], $encoding[11:7]};
Bits<5> xs2 = $encoding[24:20];
Bits<5> xs1 = $encoding[19:15];
signed Bits<12> imm = sext({$encoding[31:25], $encoding[11:7]});
Bits<5> xs2 = $encoding[24:20];
Bits<5> xs1 = $encoding[19:15];
Execution
-
IDL
-
Sail
Bits<64> data;
XReg virtual_address = X[xs1] + $signed(imm);
if (xlen() == 32) {
if (implemented?(ExtensionName::Zclsd)) {
data = {X[xs2 + 1], X[xs2]};
} else {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}
} else {
data = X[xs2];
}
write_memory<64>(virtual_address, data, $encoding);
{
let offset : xlenbits = sign_extend(imm);
/* Get the address, X(xs1) + offset.
Some extensions perform additional checks on address validity. */
match ext_data_get_addr(xs1, 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(paddr, _) => {
let eares : MemoryOpResult(unit) = match width {
BYTE => mem_write_ea(paddr, 1, aq, rl, false),
HALF => mem_write_ea(paddr, 2, aq, rl, false),
WORD => mem_write_ea(paddr, 4, aq, rl, false),
DOUBLE => mem_write_ea(paddr, 8, aq, rl, false)
};
match (eares) {
MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
MemValue(_) => {
let xs2_val = X(xs2);
let res : MemoryOpResult(bool) = match (width) {
BYTE => mem_write_value(paddr, 1, xs2_val[7..0], aq, rl, false),
HALF => mem_write_value(paddr, 2, xs2_val[15..0], aq, rl, false),
WORD => mem_write_value(paddr, 4, xs2_val[31..0], aq, rl, false),
DOUBLE if sizeof(xlen) >= 64
=> mem_write_value(paddr, 8, xs2_val, aq, rl, false),
_ => report_invalid_width(__FILE__, __LINE__, width, "store"),
};
match (res) {
MemValue(true) => RETIRE_SUCCESS,
MemValue(false) => internal_error(__FILE__, __LINE__, "store got false from mem_write_value"),
MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }
}
}
}
}
}
}
}