Problem
We currently define the main memory address space as:
|
extern char MEM[1<<XLEN]; |
Then, a single index expression like in here:
|
LW { |
|
encoding: imm[11:0] :: rs1[4:0] :: 3'b010 :: rd[4:0] :: 7'b0000011; |
|
assembly: "{name(rd)}, {imm}({name(rs1)})"; |
|
behavior: { |
|
unsigned<XLEN> load_address = X[rs1%RFS] + (signed<12>)imm; |
|
signed<32> res = (signed<32>)MEM[load_address]; |
|
if((rd%RFS)!=0) X[rd%RFS]=(unsigned<32>)res; |
|
} |
|
} |
... would only yield a
char result (as declared), which is then wrongly sign-extended to 32-bits.
Possible solutions
- Make multiple loads and concatenation explicit.
X[rd] = MEM[base + 3] :: MEM[base + 2] :: MEM[base + 1] :: MEM[base + 0];
- Introduce a ranged index operator for CoreDSL (currently, this is only supported for bit ranges, and with constant indices!)
X[rd] = MEM[base+3:base];
- Make loads as wide as the assignment target, and stores as wide as the value to be written. This would be the first context-sensitive type rule in the language, and hence doesn't fit well into the overall semantics.
Problem
We currently define the main memory address space as:
RISCV_ISA_CoreDSL/RISCVBase.core_desc
Line 48 in 28abf7c
Then, a single index expression like in here:
RISCV_ISA_CoreDSL/RV32I.core_desc
Lines 129 to 137 in 28abf7c
... would only yield a
charresult (as declared), which is then wrongly sign-extended to 32-bits.Possible solutions