9 changed files with 108 additions and 0 deletions
@ -0,0 +1,37 @@ |
|||
require_extension(EXT_ZACAS); |
|||
|
|||
if (xlen == 32) { |
|||
// RV32: the spec defines two 32-bit comparisons. Since we're
|
|||
// loading 64-bit for memory we have to adjust for endianness.
|
|||
uint64_t comp, swap, res; |
|||
|
|||
require_align(insn.rd(), 2); |
|||
require_align(insn.rs2(), 2); |
|||
if (insn.rd() == 0) { |
|||
comp = 0; |
|||
} else if (MMU.is_target_big_endian()) { |
|||
comp = (uint32_t)READ_REG(insn.rd() + 1) | (RD << 32); |
|||
} else { |
|||
comp = (uint32_t)RD | (READ_REG(insn.rd() + 1) << 32); |
|||
} |
|||
if (insn.rs2() == 0) { |
|||
swap = 0; |
|||
} else if (MMU.is_target_big_endian()) { |
|||
swap = (uint32_t)READ_REG(insn.rs2() + 1) | (RS2 << 32); |
|||
} else { |
|||
swap = (uint32_t)RS2 | (READ_REG(insn.rs2() + 1) << 32); |
|||
} |
|||
res = MMU.amo_compare_and_swap<uint64_t>(RS1, comp, swap); |
|||
if (insn.rd() != 0) { |
|||
if (MMU.is_target_big_endian()) { |
|||
WRITE_REG(insn.rd() + 1, sext32((uint32_t)res)); |
|||
WRITE_REG(insn.rd(), sext32(res >> 32)); |
|||
} else { |
|||
WRITE_REG(insn.rd(), sext32((uint32_t)res)); |
|||
WRITE_REG(insn.rd() + 1, sext32(res >> 32)); |
|||
} |
|||
} |
|||
} else { |
|||
// RV64
|
|||
WRITE_RD(MMU.amo_compare_and_swap<uint64_t>(RS1, RD, RS2)); |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
require_extension(EXT_ZACAS); |
|||
require_rv64; |
|||
require_align(insn.rd(), 2); |
|||
require_align(insn.rs2(), 2); |
|||
|
|||
// The spec defines two 64-bit comparisons. Since we're loading
|
|||
// 128-bit for memory we have to adjust for endianness.
|
|||
|
|||
uint128_t comp, swap, res; |
|||
|
|||
if (insn.rd() == 0) { |
|||
comp = 0; |
|||
} else if (MMU.is_target_big_endian()) { |
|||
comp = READ_REG(insn.rd() + 1) | ((uint128_t)RD << 64); |
|||
} else { |
|||
comp = RD | ((uint128_t)READ_REG(insn.rd() + 1) << 64); |
|||
} |
|||
if (insn.rs2() == 0) { |
|||
swap = 0; |
|||
} else if (MMU.is_target_big_endian()) { |
|||
swap = READ_REG(insn.rs2() + 1) | ((uint128_t)RS2 << 64); |
|||
} else { |
|||
swap = RS2 | ((uint128_t)READ_REG(insn.rs2() + 1) << 64); |
|||
} |
|||
res = MMU.amo_compare_and_swap<uint128_t>(RS1, comp, swap); |
|||
if (insn.rd() != 0) { |
|||
if (MMU.is_target_big_endian()) { |
|||
WRITE_REG(insn.rd(), res >> 64); |
|||
WRITE_REG(insn.rd() + 1, res); |
|||
} else { |
|||
WRITE_REG(insn.rd(), res); |
|||
WRITE_REG(insn.rd() + 1, res >> 64); |
|||
} |
|||
} |
|||
@ -0,0 +1,2 @@ |
|||
require_extension(EXT_ZACAS); |
|||
WRITE_RD(sext32(MMU.amo_compare_and_swap<uint32_t>(RS1, RD, RS2))); |
|||
Loading…
Reference in new issue