[PATCH] D98936: [RISCV] DAG nodes and pseudo instructions for CSR access

Serge Pavlov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 19 03:14:10 PDT 2021


sepavloff created this revision.
sepavloff added reviewers: asb, craig.topper, luismarques, jrtc27.
Herald added subscribers: vkmr, frasercrmck, evandro, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, shiva0217, kito-cheng, niosHD, sabuasal, simoncook, johnrusso, rbar, hiraditya.
sepavloff requested review of this revision.
Herald added a subscriber: MaskRay.
Herald added a project: LLVM.

New custom DAG nodes were added. They represent operations on CSR. These
nodes are lowered to corresponding pseudo instruction. Using the pseudo
instructions allows to spefify different scheduling information for
operations on different system registers. It also make possible to
specify dependencies of instructions on specific system registers.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D98936

Files:
  llvm/lib/Target/RISCV/RISCVISelLowering.cpp
  llvm/lib/Target/RISCV/RISCVISelLowering.h
  llvm/lib/Target/RISCV/RISCVInstrInfo.td


Index: llvm/lib/Target/RISCV/RISCVInstrInfo.td
===================================================================
--- llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -28,6 +28,9 @@
 def SDT_RISCVBrCC : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>,
                                          SDTCisVT<2, OtherVT>,
                                          SDTCisVT<3, OtherVT>]>;
+def SDT_ReadCSR   : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisInt<1>]>;
+def SDT_WriteCSR  : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisInt<1>]>;
+def SDT_ModifyCSR : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>, SDTCisInt<2>]>;
 def SDT_RISCVReadCycleWide : SDTypeProfile<2, 0, [SDTCisVT<0, i32>,
                                                   SDTCisVT<1, i32>]>;
 def SDT_RISCVIntBinOpW : SDTypeProfile<1, 2, [
@@ -61,6 +64,12 @@
 def riscv_sllw      : SDNode<"RISCVISD::SLLW", SDT_RISCVIntBinOpW>;
 def riscv_sraw      : SDNode<"RISCVISD::SRAW", SDT_RISCVIntBinOpW>;
 def riscv_srlw      : SDNode<"RISCVISD::SRLW", SDT_RISCVIntBinOpW>;
+def riscv_read_csr  : SDNode<"RISCVISD::READ_CSR", SDT_ReadCSR,
+                             [SDNPHasChain]>;
+def riscv_write_csr : SDNode<"RISCVISD::WRITE_CSR", SDT_WriteCSR,
+                             [SDNPHasChain]>;
+def riscv_modify_csr: SDNode<"RISCVISD::MODIFY_CSR", SDT_ModifyCSR,
+                             [SDNPHasChain]>;
 
 def riscv_read_cycle_wide : SDNode<"RISCVISD::READ_CYCLE_WIDE",
                                    SDT_RISCVReadCycleWide,
@@ -1146,6 +1155,26 @@
 // present. This is necessary as it isn't valid to mix __atomic_* libcalls
 // with inline atomic operations for the same object.
 
+/// Access to system registers
+
+let hasSideEffects = 0, isCodeGenOnly = 1 in
+def PseudoReadCSR : Pseudo<(outs GPR:$rd), (ins csr_sysreg:$reg),
+                            [(set GPR:$rd, (riscv_read_csr (XLenVT imm:$reg)))],
+                            "csrr", "$rd, $reg">,
+                    PseudoInstExpansion<(CSRRC GPR:$rd, csr_sysreg:$reg, X0)>;
+
+let hasSideEffects = 1, isCodeGenOnly = 1 in
+def PseudoWriteCSR : Pseudo<(outs), (ins csr_sysreg:$reg, GPR:$val),
+                            [(riscv_write_csr (XLenVT imm:$reg), GPR:$val)],
+                            "csrw", "$reg, $val">,
+                     PseudoInstExpansion<(CSRRW X0, csr_sysreg:$reg, GPR:$val)>;
+
+let hasSideEffects = 1, isCodeGenOnly = 1 in
+def PseudoModifyCSR : Pseudo<(outs GPR:$rd), (ins csr_sysreg:$reg, GPR:$val),
+                             [(set GPR:$rd, (riscv_modify_csr (XLenVT imm:$reg), GPR:$val))],
+                             "csrrw", "$rd, $reg, $val">,
+                      PseudoInstExpansion<(CSRRW GPR:$rd, csr_sysreg:$reg, GPR:$val)>;
+
 /// Other pseudo-instructions
 
 // Pessimistically assume the stack pointer will be clobbered
Index: llvm/lib/Target/RISCV/RISCVISelLowering.h
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -219,6 +219,22 @@
   VSEXT_VL,
   VZEXT_VL,
 
+  // Reads value of CSR.
+  // The first operand is a chain pointer. The second specifies address of the
+  // required CSR. Two results are produced, the read value and the new chain
+  // pointer.
+  READ_CSR,
+  // Write value to CSR.
+  // The first operand is a chain pointer, the second specifies address of the
+  // required CSR and the third is the value to write. The result is the new
+  // chain pointer.
+  WRITE_CSR,
+  // Read-Modify-Write value of CSR.
+  // The first operand is a chain pointer, the second specifies address of the
+  // required CSR and the third is the value to write. Two results are produced,
+  // the value read before the modification and the new chain pointer.
+  MODIFY_CSR,
+
   // Memory opcodes start here.
   VLE_VL = ISD::FIRST_TARGET_MEMORY_OPCODE,
   VSE_VL,
Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -6590,6 +6590,9 @@
   NODE_NAME_CASE(VZEXT_VL)
   NODE_NAME_CASE(VLE_VL)
   NODE_NAME_CASE(VSE_VL)
+  NODE_NAME_CASE(READ_CSR)
+  NODE_NAME_CASE(WRITE_CSR)
+  NODE_NAME_CASE(MODIFY_CSR)
   }
   // clang-format on
   return nullptr;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D98936.331812.patch
Type: text/x-patch
Size: 4357 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210319/bb6c7526/attachment.bin>


More information about the llvm-commits mailing list