From 4ef2c87da8e6ada5f2210acd0f47d4d602f48d4f Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 6 Sep 2010 16:04:52 -0700 Subject: [PATCH] [sim] added atomic memory operations --- riscv/execute.h | 146 +++++++++++++++++++++++++++++++++++----- riscv/insns/amo_add.h | 4 ++ riscv/insns/amo_and.h | 4 ++ riscv/insns/amo_max.h | 4 ++ riscv/insns/amo_maxu.h | 4 ++ riscv/insns/amo_min.h | 4 ++ riscv/insns/amo_minu.h | 4 ++ riscv/insns/amo_or.h | 4 ++ riscv/insns/amo_swap.h | 4 ++ riscv/insns/amow_add.h | 3 + riscv/insns/amow_and.h | 3 + riscv/insns/amow_max.h | 3 + riscv/insns/amow_maxu.h | 3 + riscv/insns/amow_min.h | 3 + riscv/insns/amow_minu.h | 3 + riscv/insns/amow_or.h | 3 + riscv/insns/amow_swap.h | 3 + 17 files changed, 184 insertions(+), 18 deletions(-) create mode 100644 riscv/insns/amo_add.h create mode 100644 riscv/insns/amo_and.h create mode 100644 riscv/insns/amo_max.h create mode 100644 riscv/insns/amo_maxu.h create mode 100644 riscv/insns/amo_min.h create mode 100644 riscv/insns/amo_minu.h create mode 100644 riscv/insns/amo_or.h create mode 100644 riscv/insns/amo_swap.h create mode 100644 riscv/insns/amow_add.h create mode 100644 riscv/insns/amow_and.h create mode 100644 riscv/insns/amow_max.h create mode 100644 riscv/insns/amow_maxu.h create mode 100644 riscv/insns/amow_min.h create mode 100644 riscv/insns/amow_minu.h create mode 100644 riscv/insns/amow_or.h create mode 100644 riscv/insns/amow_swap.h diff --git a/riscv/execute.h b/riscv/execute.h index 823697a..abfa68e 100644 --- a/riscv/execute.h +++ b/riscv/execute.h @@ -245,14 +245,14 @@ switch((insn.bits >> 0x19) & 0x7f) } case 0x2: { - if((insn.bits & 0xfe007fe0) == 0xd0002c20) + if((insn.bits & 0xfe007fe0) == 0xd0002020) { - #include "insns/c_eq_d.h" + #include "insns/c_eq_s.h" break; } - if((insn.bits & 0xfe007fe0) == 0xd0002020) + if((insn.bits & 0xfe007fe0) == 0xd0002c20) { - #include "insns/c_eq_s.h" + #include "insns/c_eq_d.h" break; } if((insn.bits & 0xfe007fe0) == 0xd0002c60) @@ -340,6 +340,37 @@ switch((insn.bits >> 0x19) & 0x7f) } break; } + case 0x69: + { + switch((insn.bits >> 0xc) & 0x7) + { + case 0x2: + { + #include "insns/l_s.h" + break; + } + case 0x3: + { + #include "insns/l_d.h" + break; + } + case 0x6: + { + #include "insns/s_s.h" + break; + } + case 0x7: + { + #include "insns/s_d.h" + break; + } + default: + { + #include "insns/unimp.h" + } + } + break; + } case 0x6a: { switch((insn.bits >> 0xc) & 0x7) @@ -808,25 +839,104 @@ switch((insn.bits >> 0x19) & 0x7f) #include "insns/sd.h" break; } - case 0x4: - { - #include "insns/l_s.h" - break; - } - case 0x5: + default: { - #include "insns/l_d.h" - break; + #include "insns/unimp.h" } - case 0x6: + } + break; + } + case 0x7a: + { + switch((insn.bits >> 0xc) & 0x7) + { + case 0x2: { - #include "insns/s_s.h" - break; + if((insn.bits & 0xfe007fe0) == 0xf4002040) + { + #include "insns/amow_and.h" + break; + } + if((insn.bits & 0xfe007fe0) == 0xf4002080) + { + #include "insns/amow_min.h" + break; + } + if((insn.bits & 0xfe007fe0) == 0xf4002060) + { + #include "insns/amow_or.h" + break; + } + if((insn.bits & 0xfe007fe0) == 0xf40020a0) + { + #include "insns/amow_max.h" + break; + } + if((insn.bits & 0xfe007fe0) == 0xf40020c0) + { + #include "insns/amow_minu.h" + break; + } + if((insn.bits & 0xfe007fe0) == 0xf4002000) + { + #include "insns/amow_add.h" + break; + } + if((insn.bits & 0xfe007fe0) == 0xf4002020) + { + #include "insns/amow_swap.h" + break; + } + if((insn.bits & 0xfe007fe0) == 0xf40020e0) + { + #include "insns/amow_maxu.h" + break; + } + #include "insns/unimp.h" } - case 0x7: + case 0x3: { - #include "insns/s_d.h" - break; + if((insn.bits & 0xfe007fe0) == 0xf4003000) + { + #include "insns/amo_add.h" + break; + } + if((insn.bits & 0xfe007fe0) == 0xf4003020) + { + #include "insns/amo_swap.h" + break; + } + if((insn.bits & 0xfe007fe0) == 0xf4003060) + { + #include "insns/amo_or.h" + break; + } + if((insn.bits & 0xfe007fe0) == 0xf40030a0) + { + #include "insns/amo_max.h" + break; + } + if((insn.bits & 0xfe007fe0) == 0xf4003080) + { + #include "insns/amo_min.h" + break; + } + if((insn.bits & 0xfe007fe0) == 0xf40030c0) + { + #include "insns/amo_minu.h" + break; + } + if((insn.bits & 0xfe007fe0) == 0xf4003040) + { + #include "insns/amo_and.h" + break; + } + if((insn.bits & 0xfe007fe0) == 0xf40030e0) + { + #include "insns/amo_maxu.h" + break; + } + #include "insns/unimp.h" } default: { diff --git a/riscv/insns/amo_add.h b/riscv/insns/amo_add.h new file mode 100644 index 0000000..0ea6782 --- /dev/null +++ b/riscv/insns/amo_add.h @@ -0,0 +1,4 @@ +require64; +reg_t v = mmu.load_uint64(RB); +mmu.store_uint64(RB, RA + v); +RC = v; diff --git a/riscv/insns/amo_and.h b/riscv/insns/amo_and.h new file mode 100644 index 0000000..c86e537 --- /dev/null +++ b/riscv/insns/amo_and.h @@ -0,0 +1,4 @@ +require64; +reg_t v = mmu.load_uint64(RB); +mmu.store_uint64(RB, RA & v); +RC = v; diff --git a/riscv/insns/amo_max.h b/riscv/insns/amo_max.h new file mode 100644 index 0000000..6e3eeb6 --- /dev/null +++ b/riscv/insns/amo_max.h @@ -0,0 +1,4 @@ +require64; +sreg_t v = mmu.load_int64(RB); +mmu.store_uint64(RB, std::max(sreg_t(RA),v)); +RC = v; diff --git a/riscv/insns/amo_maxu.h b/riscv/insns/amo_maxu.h new file mode 100644 index 0000000..471a119 --- /dev/null +++ b/riscv/insns/amo_maxu.h @@ -0,0 +1,4 @@ +require64; +reg_t v = mmu.load_uint64(RB); +mmu.store_uint64(RB, std::max(RA,v)); +RC = v; diff --git a/riscv/insns/amo_min.h b/riscv/insns/amo_min.h new file mode 100644 index 0000000..8235504 --- /dev/null +++ b/riscv/insns/amo_min.h @@ -0,0 +1,4 @@ +require64; +sreg_t v = mmu.load_int64(RB); +mmu.store_uint64(RB, std::min(sreg_t(RA),v)); +RC = v; diff --git a/riscv/insns/amo_minu.h b/riscv/insns/amo_minu.h new file mode 100644 index 0000000..0b617a1 --- /dev/null +++ b/riscv/insns/amo_minu.h @@ -0,0 +1,4 @@ +require64; +reg_t v = mmu.load_uint64(RB); +mmu.store_uint64(RB, std::min(RA,v)); +RC = v; diff --git a/riscv/insns/amo_or.h b/riscv/insns/amo_or.h new file mode 100644 index 0000000..790a98c --- /dev/null +++ b/riscv/insns/amo_or.h @@ -0,0 +1,4 @@ +require64; +reg_t v = mmu.load_uint64(RB); +mmu.store_uint64(RB, RA | v); +RC = v; diff --git a/riscv/insns/amo_swap.h b/riscv/insns/amo_swap.h new file mode 100644 index 0000000..1995f83 --- /dev/null +++ b/riscv/insns/amo_swap.h @@ -0,0 +1,4 @@ +require64; +reg_t v = mmu.load_uint64(RB); +mmu.store_uint64(RB, RA); +RC = v; diff --git a/riscv/insns/amow_add.h b/riscv/insns/amow_add.h new file mode 100644 index 0000000..fbf475d --- /dev/null +++ b/riscv/insns/amow_add.h @@ -0,0 +1,3 @@ +reg_t v = mmu.load_int32(RB); +mmu.store_uint32(RB, RA + v); +RC = v; diff --git a/riscv/insns/amow_and.h b/riscv/insns/amow_and.h new file mode 100644 index 0000000..1166e86 --- /dev/null +++ b/riscv/insns/amow_and.h @@ -0,0 +1,3 @@ +reg_t v = mmu.load_int32(RB); +mmu.store_uint32(RB, RA & v); +RC = v; diff --git a/riscv/insns/amow_max.h b/riscv/insns/amow_max.h new file mode 100644 index 0000000..c5318e7 --- /dev/null +++ b/riscv/insns/amow_max.h @@ -0,0 +1,3 @@ +int32_t v = mmu.load_int32(RB); +mmu.store_uint32(RB, std::max(int32_t(RA),v)); +RC = v; diff --git a/riscv/insns/amow_maxu.h b/riscv/insns/amow_maxu.h new file mode 100644 index 0000000..9f5bf23 --- /dev/null +++ b/riscv/insns/amow_maxu.h @@ -0,0 +1,3 @@ +uint32_t v = mmu.load_int32(RB); +mmu.store_uint32(RB, std::max(uint32_t(RA),v)); +RC = v; diff --git a/riscv/insns/amow_min.h b/riscv/insns/amow_min.h new file mode 100644 index 0000000..a5abc48 --- /dev/null +++ b/riscv/insns/amow_min.h @@ -0,0 +1,3 @@ +int32_t v = mmu.load_int32(RB); +mmu.store_uint32(RB, std::min(int32_t(RA),v)); +RC = v; diff --git a/riscv/insns/amow_minu.h b/riscv/insns/amow_minu.h new file mode 100644 index 0000000..fe55d23 --- /dev/null +++ b/riscv/insns/amow_minu.h @@ -0,0 +1,3 @@ +uint32_t v = mmu.load_int32(RB); +mmu.store_uint32(RB, std::min(uint32_t(RA),v)); +RC = v; diff --git a/riscv/insns/amow_or.h b/riscv/insns/amow_or.h new file mode 100644 index 0000000..09d105f --- /dev/null +++ b/riscv/insns/amow_or.h @@ -0,0 +1,3 @@ +reg_t v = mmu.load_int32(RB); +mmu.store_uint32(RB, RA | v); +RC = v; diff --git a/riscv/insns/amow_swap.h b/riscv/insns/amow_swap.h new file mode 100644 index 0000000..6aec206 --- /dev/null +++ b/riscv/insns/amow_swap.h @@ -0,0 +1,3 @@ +reg_t v = mmu.load_int32(RB); +mmu.store_uint32(RB, RA); +RC = v; -- 2.30.2