[sim] added atomic memory operations
authorAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>
Mon, 6 Sep 2010 23:04:52 +0000 (16:04 -0700)
committerAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>
Mon, 6 Sep 2010 23:04:52 +0000 (16:04 -0700)
17 files changed:
riscv/execute.h
riscv/insns/amo_add.h [new file with mode: 0644]
riscv/insns/amo_and.h [new file with mode: 0644]
riscv/insns/amo_max.h [new file with mode: 0644]
riscv/insns/amo_maxu.h [new file with mode: 0644]
riscv/insns/amo_min.h [new file with mode: 0644]
riscv/insns/amo_minu.h [new file with mode: 0644]
riscv/insns/amo_or.h [new file with mode: 0644]
riscv/insns/amo_swap.h [new file with mode: 0644]
riscv/insns/amow_add.h [new file with mode: 0644]
riscv/insns/amow_and.h [new file with mode: 0644]
riscv/insns/amow_max.h [new file with mode: 0644]
riscv/insns/amow_maxu.h [new file with mode: 0644]
riscv/insns/amow_min.h [new file with mode: 0644]
riscv/insns/amow_minu.h [new file with mode: 0644]
riscv/insns/amow_or.h [new file with mode: 0644]
riscv/insns/amow_swap.h [new file with mode: 0644]

index 823697a76e13928fd04b1585832a23b1ddbc2c78..abfa68e7aeb5a7d062158b6b74a13dad6b39442a 100644 (file)
@@ -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 (file)
index 0000000..0ea6782
--- /dev/null
@@ -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 (file)
index 0000000..c86e537
--- /dev/null
@@ -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 (file)
index 0000000..6e3eeb6
--- /dev/null
@@ -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 (file)
index 0000000..471a119
--- /dev/null
@@ -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 (file)
index 0000000..8235504
--- /dev/null
@@ -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 (file)
index 0000000..0b617a1
--- /dev/null
@@ -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 (file)
index 0000000..790a98c
--- /dev/null
@@ -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 (file)
index 0000000..1995f83
--- /dev/null
@@ -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 (file)
index 0000000..fbf475d
--- /dev/null
@@ -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 (file)
index 0000000..1166e86
--- /dev/null
@@ -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 (file)
index 0000000..c5318e7
--- /dev/null
@@ -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 (file)
index 0000000..9f5bf23
--- /dev/null
@@ -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 (file)
index 0000000..a5abc48
--- /dev/null
@@ -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 (file)
index 0000000..fe55d23
--- /dev/null
@@ -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 (file)
index 0000000..09d105f
--- /dev/null
@@ -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 (file)
index 0000000..6aec206
--- /dev/null
@@ -0,0 +1,3 @@
+reg_t v = mmu.load_int32(RB);
+mmu.store_uint32(RB, RA);
+RC = v;