Skip to content

Commit aebf16f

Browse files
Merge pull request #145 from riscv-software-src/sail
Add Sail snippets to instructions
2 parents d4597d6 + 1494df1 commit aebf16f

File tree

183 files changed

+5645
-19
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

183 files changed

+5645
-19
lines changed

arch/inst/A/amoadd.d.yaml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,98 @@ amoadd.d:
4141
XReg virtual_address = X[rs1];
4242
4343
X[rd] = amo<64>(virtual_address, X[rs2], AmoOperation::Add, aq, rl, $encoding);
44+
45+
46+
47+
sail(): |
48+
{
49+
if extension("A") then {
50+
/* Get the address, X(rs1) (no offset).
51+
* Some extensions perform additional checks on address validity.
52+
*/
53+
match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {
54+
Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },
55+
Ext_DataAddr_OK(vaddr) => {
56+
match translateAddr(vaddr, ReadWrite(Data, Data)) {
57+
TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
58+
TR_Address(addr, _) => {
59+
let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {
60+
(BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),
61+
(HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),
62+
(WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),
63+
(DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),
64+
_ => internal_error(__FILE__, __LINE__, "Unexpected AMO width")
65+
};
66+
let is_unsigned : bool = match op {
67+
AMOMINU => true,
68+
AMOMAXU => true,
69+
_ => false
70+
};
71+
let rs2_val : xlenbits = match width {
72+
BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),
73+
HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),
74+
WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),
75+
DOUBLE => X(rs2)
76+
};
77+
match (eares) {
78+
MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
79+
MemValue(_) => {
80+
let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {
81+
(BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),
82+
(HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),
83+
(WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),
84+
(DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),
85+
_ => internal_error(__FILE__, __LINE__, "Unexpected AMO width")
86+
};
87+
match (mval) {
88+
MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
89+
MemValue(loaded) => {
90+
let result : xlenbits =
91+
match op {
92+
AMOSWAP => rs2_val,
93+
AMOADD => rs2_val + loaded,
94+
AMOXOR => rs2_val ^ loaded,
95+
AMOAND => rs2_val & loaded,
96+
AMOOR => rs2_val | loaded,
97+
98+
/* These operations convert bitvectors to integer values using [un]signed,
99+
* and back using to_bits().
100+
*/
101+
AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),
102+
AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),
103+
AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),
104+
AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))
105+
};
106+
let rval : xlenbits = match width {
107+
BYTE => sign_extend(loaded[7..0]),
108+
HALF => sign_extend(loaded[15..0]),
109+
WORD => sign_extend(loaded[31..0]),
110+
DOUBLE => loaded
111+
};
112+
let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {
113+
(BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),
114+
(HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),
115+
(WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),
116+
(DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),
117+
_ => internal_error(__FILE__, __LINE__, "Unexpected AMO width")
118+
};
119+
match (wval) {
120+
MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },
121+
MemValue(false) => { internal_error(__FILE__, __LINE__, "AMO got false from mem_write_value") },
122+
MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }
123+
}
124+
}
125+
}
126+
}
127+
}
128+
}
129+
}
130+
}
131+
}
132+
} else {
133+
handle_illegal();
134+
RETIRE_FAIL
135+
}
136+
}
137+
138+

arch/inst/A/amoadd.w.yaml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,98 @@ amoadd.w:
4040
XReg virtual_address = X[rs1];
4141
4242
X[rd] = amo<32>(virtual_address, X[rs2][31:0], AmoOperation::Add, aq, rl, $encoding);
43+
44+
45+
46+
sail(): |
47+
{
48+
if extension("A") then {
49+
/* Get the address, X(rs1) (no offset).
50+
* Some extensions perform additional checks on address validity.
51+
*/
52+
match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {
53+
Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },
54+
Ext_DataAddr_OK(vaddr) => {
55+
match translateAddr(vaddr, ReadWrite(Data, Data)) {
56+
TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
57+
TR_Address(addr, _) => {
58+
let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {
59+
(BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),
60+
(HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),
61+
(WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),
62+
(DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),
63+
_ => internal_error(__FILE__, __LINE__, "Unexpected AMO width")
64+
};
65+
let is_unsigned : bool = match op {
66+
AMOMINU => true,
67+
AMOMAXU => true,
68+
_ => false
69+
};
70+
let rs2_val : xlenbits = match width {
71+
BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),
72+
HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),
73+
WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),
74+
DOUBLE => X(rs2)
75+
};
76+
match (eares) {
77+
MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
78+
MemValue(_) => {
79+
let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {
80+
(BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),
81+
(HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),
82+
(WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),
83+
(DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),
84+
_ => internal_error(__FILE__, __LINE__, "Unexpected AMO width")
85+
};
86+
match (mval) {
87+
MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
88+
MemValue(loaded) => {
89+
let result : xlenbits =
90+
match op {
91+
AMOSWAP => rs2_val,
92+
AMOADD => rs2_val + loaded,
93+
AMOXOR => rs2_val ^ loaded,
94+
AMOAND => rs2_val & loaded,
95+
AMOOR => rs2_val | loaded,
96+
97+
/* These operations convert bitvectors to integer values using [un]signed,
98+
* and back using to_bits().
99+
*/
100+
AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),
101+
AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),
102+
AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),
103+
AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))
104+
};
105+
let rval : xlenbits = match width {
106+
BYTE => sign_extend(loaded[7..0]),
107+
HALF => sign_extend(loaded[15..0]),
108+
WORD => sign_extend(loaded[31..0]),
109+
DOUBLE => loaded
110+
};
111+
let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {
112+
(BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),
113+
(HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),
114+
(WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),
115+
(DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),
116+
_ => internal_error(__FILE__, __LINE__, "Unexpected AMO width")
117+
};
118+
match (wval) {
119+
MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },
120+
MemValue(false) => { internal_error(__FILE__, __LINE__, "AMO got false from mem_write_value") },
121+
MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }
122+
}
123+
}
124+
}
125+
}
126+
}
127+
}
128+
}
129+
}
130+
}
131+
} else {
132+
handle_illegal();
133+
RETIRE_FAIL
134+
}
135+
}
136+
137+

arch/inst/A/amoand.d.yaml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,98 @@ amoand.d:
4141
XReg virtual_address = X[rs1];
4242
4343
X[rd] = amo<64>(virtual_address, X[rs2], AmoOperation::And, aq, rl, $encoding);
44+
45+
46+
47+
sail(): |
48+
{
49+
if extension("A") then {
50+
/* Get the address, X(rs1) (no offset).
51+
* Some extensions perform additional checks on address validity.
52+
*/
53+
match ext_data_get_addr(rs1, zeros(), ReadWrite(Data, Data), width) {
54+
Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); RETIRE_FAIL },
55+
Ext_DataAddr_OK(vaddr) => {
56+
match translateAddr(vaddr, ReadWrite(Data, Data)) {
57+
TR_Failure(e, _) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
58+
TR_Address(addr, _) => {
59+
let eares : MemoryOpResult(unit) = match (width, sizeof(xlen)) {
60+
(BYTE, _) => mem_write_ea(addr, 1, aq & rl, rl, true),
61+
(HALF, _) => mem_write_ea(addr, 2, aq & rl, rl, true),
62+
(WORD, _) => mem_write_ea(addr, 4, aq & rl, rl, true),
63+
(DOUBLE, 64) => mem_write_ea(addr, 8, aq & rl, rl, true),
64+
_ => internal_error(__FILE__, __LINE__, "Unexpected AMO width")
65+
};
66+
let is_unsigned : bool = match op {
67+
AMOMINU => true,
68+
AMOMAXU => true,
69+
_ => false
70+
};
71+
let rs2_val : xlenbits = match width {
72+
BYTE => if is_unsigned then zero_extend(X(rs2)[7..0]) else sign_extend(X(rs2)[7..0]),
73+
HALF => if is_unsigned then zero_extend(X(rs2)[15..0]) else sign_extend(X(rs2)[15..0]),
74+
WORD => if is_unsigned then zero_extend(X(rs2)[31..0]) else sign_extend(X(rs2)[31..0]),
75+
DOUBLE => X(rs2)
76+
};
77+
match (eares) {
78+
MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
79+
MemValue(_) => {
80+
let mval : MemoryOpResult(xlenbits) = match (width, sizeof(xlen)) {
81+
(BYTE, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 1, aq, aq & rl, true)),
82+
(HALF, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 2, aq, aq & rl, true)),
83+
(WORD, _) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 4, aq, aq & rl, true)),
84+
(DOUBLE, 64) => extend_value(is_unsigned, mem_read(ReadWrite(Data, Data), addr, 8, aq, aq & rl, true)),
85+
_ => internal_error(__FILE__, __LINE__, "Unexpected AMO width")
86+
};
87+
match (mval) {
88+
MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL },
89+
MemValue(loaded) => {
90+
let result : xlenbits =
91+
match op {
92+
AMOSWAP => rs2_val,
93+
AMOADD => rs2_val + loaded,
94+
AMOXOR => rs2_val ^ loaded,
95+
AMOAND => rs2_val & loaded,
96+
AMOOR => rs2_val | loaded,
97+
98+
/* These operations convert bitvectors to integer values using [un]signed,
99+
* and back using to_bits().
100+
*/
101+
AMOMIN => to_bits(sizeof(xlen), min(signed(rs2_val), signed(loaded))),
102+
AMOMAX => to_bits(sizeof(xlen), max(signed(rs2_val), signed(loaded))),
103+
AMOMINU => to_bits(sizeof(xlen), min(unsigned(rs2_val), unsigned(loaded))),
104+
AMOMAXU => to_bits(sizeof(xlen), max(unsigned(rs2_val), unsigned(loaded)))
105+
};
106+
let rval : xlenbits = match width {
107+
BYTE => sign_extend(loaded[7..0]),
108+
HALF => sign_extend(loaded[15..0]),
109+
WORD => sign_extend(loaded[31..0]),
110+
DOUBLE => loaded
111+
};
112+
let wval : MemoryOpResult(bool) = match (width, sizeof(xlen)) {
113+
(BYTE, _) => mem_write_value(addr, 1, result[7..0], aq & rl, rl, true),
114+
(HALF, _) => mem_write_value(addr, 2, result[15..0], aq & rl, rl, true),
115+
(WORD, _) => mem_write_value(addr, 4, result[31..0], aq & rl, rl, true),
116+
(DOUBLE, 64) => mem_write_value(addr, 8, result, aq & rl, rl, true),
117+
_ => internal_error(__FILE__, __LINE__, "Unexpected AMO width")
118+
};
119+
match (wval) {
120+
MemValue(true) => { X(rd) = rval; RETIRE_SUCCESS },
121+
MemValue(false) => { internal_error(__FILE__, __LINE__, "AMO got false from mem_write_value") },
122+
MemException(e) => { handle_mem_exception(vaddr, e); RETIRE_FAIL }
123+
}
124+
}
125+
}
126+
}
127+
}
128+
}
129+
}
130+
}
131+
}
132+
} else {
133+
handle_illegal();
134+
RETIRE_FAIL
135+
}
136+
}
137+
138+

0 commit comments

Comments
 (0)