Encode full memory fences

b58290fa22eb1d572362802faa9bdf3ab0c9763e897e38cd94fe65fc328b0458
Alexis Sellier committed ago 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;