Encode full memory fences
b58290fa22eb1d572362802faa9bdf3ab0c9763e897e38cd94fe65fc328b0458
1 parent
c50805e1
lib/std/arch/rv64/asm.rad
+2 -1
| 260 | 260 | export constant SHIFT_LIMIT: i32 = 64; |
|
| 261 | 261 | /// Largest `lui` or `auipc` immediate. |
|
| 262 | 262 | export constant UPPER_IMM_MAX_VALUE: i64 = 0xFFFFF; |
|
| 263 | 263 | ||
| 264 | 264 | /// Sorted instruction descriptor table used by the assembler parser. |
|
| 265 | - | export constant INSTRUCTIONS: [InstructionEntry; 87] = [ |
|
| 265 | + | export constant INSTRUCTIONS: [InstructionEntry; 88] = [ |
|
| 266 | 266 | { name: "add", encoder: InstructionEncoder::RRR { enc: encode::add } }, |
|
| 267 | 267 | { name: "addi", encoder: InstructionEncoder::RRI { enc: encode::addi } }, |
|
| 268 | 268 | { name: "addiw", encoder: InstructionEncoder::RRI { enc: encode::addiw } }, |
|
| 269 | 269 | { name: "addw", encoder: InstructionEncoder::RRR { enc: encode::addw } }, |
|
| 270 | 270 | { name: "and", encoder: InstructionEncoder::RRR { enc: encode::and_ } }, |
| 290 | 290 | { name: "divu", encoder: InstructionEncoder::RRR { enc: encode::divu } }, |
|
| 291 | 291 | { name: "divuw", encoder: InstructionEncoder::RRR { enc: encode::divuw } }, |
|
| 292 | 292 | { name: "divw", encoder: InstructionEncoder::RRR { enc: encode::divw } }, |
|
| 293 | 293 | { name: "ebreak", encoder: InstructionEncoder::NoOperand { enc: encode::ebreak } }, |
|
| 294 | 294 | { name: "ecall", encoder: InstructionEncoder::NoOperand { enc: encode::ecall } }, |
|
| 295 | + | { name: "fence", encoder: InstructionEncoder::NoOperand { enc: encode::fence } }, |
|
| 295 | 296 | { name: "j", encoder: InstructionEncoder::Jump { rd: rv64::ZERO } }, |
|
| 296 | 297 | { name: "jal", encoder: InstructionEncoder::Jal }, |
|
| 297 | 298 | { name: "jalr", encoder: InstructionEncoder::RRI { enc: encode::jalr } }, |
|
| 298 | 299 | { name: "la", encoder: InstructionEncoder::La }, |
|
| 299 | 300 | { name: "lb", encoder: InstructionEncoder::Load { enc: encode::lb } }, |
lib/std/arch/rv64/encode.rad
+5 -0
| 544 | 544 | /// Environment break (debugger breakpoint). |
|
| 545 | 545 | export fn ebreak() -> u32 { |
|
| 546 | 546 | return encodeI(OP_SYSTEM, super::ZERO, super::ZERO, 0, 1); |
|
| 547 | 547 | } |
|
| 548 | 548 | ||
| 549 | + | /// Full predecessor/successor memory fence (`fence rw, rw`). |
|
| 550 | + | export fn fence() -> u32 { |
|
| 551 | + | return 0x0330000F; |
|
| 552 | + | } |
|
| 553 | + | ||
| 549 | 554 | /// Encode a CSR instruction with a register source. |
|
| 550 | 555 | fn encodeCsr(op: u32, rd: gen::Reg, csr: u32, funct3: u32, rs1: gen::Reg) -> u32 { |
|
| 551 | 556 | return (op & 0x7F) |
|
| 552 | 557 | | ((*rd as u32 & 0x1F) << 7) |
|
| 553 | 558 | | ((funct3 & 0x07) << 12) |
test/tests/asm.fence.ras
added
+7 -0
| 1 | + | //! returns: 0 |
|
| 2 | + | ||
| 3 | + | .text; |
|
| 4 | + | fence; |
|
| 5 | + | li %a0 0; |
|
| 6 | + | li %a7 93; |
|
| 7 | + | ecall; |