aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td
blob: 5e013b496c6b1e5e00efd55a1e5841fc6b0c61e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//===-- RISCVInstrInfoZalasr.td  ---------------------------*- tablegen -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file describes the RISC-V instructions from the Zalasr (Load-Acquire
// and Store-Release) extension
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Instruction class templates
//===----------------------------------------------------------------------===//

let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
class LAQ_r<bit aq, bit rl, bits<3> funct3, string opcodestr>
    : RVInstRAtomic<0b00110, aq, rl, funct3, OPC_AMO,
                    (outs GPR:$rd), (ins GPRMemZeroOffset:$rs1),
                    opcodestr, "$rd, $rs1"> {
  let rs2 = 0;
}

let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
class SRL_r<bit aq, bit rl, bits<3> funct3, string opcodestr>
    : RVInstRAtomic<0b00111, aq, rl, funct3, OPC_AMO,
                    (outs ), (ins GPRMemZeroOffset:$rs1, GPR:$rs2),
                    opcodestr, "$rs2, $rs1"> {
  let rd = 0;
}
multiclass LAQ_r_aq_rl<bits<3> funct3, string opcodestr> {
  def _AQ    : LAQ_r<1, 0, funct3, opcodestr # ".aq">;
  def _AQ_RL : LAQ_r<1, 1, funct3, opcodestr # ".aqrl">;
}

multiclass SRL_r_aq_rl<bits<3> funct3, string opcodestr> {
  def _RL    : SRL_r<0, 1, funct3, opcodestr # ".rl">;
  def _AQ_RL : SRL_r<1, 1, funct3, opcodestr # ".aqrl">;
}

//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//

let Predicates = [HasStdExtZalasr] in {
defm LB : LAQ_r_aq_rl<0b000, "lb">;
defm LH : LAQ_r_aq_rl<0b001, "lh">;
defm LW : LAQ_r_aq_rl<0b010, "lw">;
defm SB : SRL_r_aq_rl<0b000, "sb">;
defm SH : SRL_r_aq_rl<0b001, "sh">;
defm SW : SRL_r_aq_rl<0b010, "sw">;
} // Predicates = [HasStdExtZalasr]

let Predicates = [HasStdExtZalasr, IsRV64] in {
defm LD : LAQ_r_aq_rl<0b011, "ld">;
defm SD : SRL_r_aq_rl<0b011, "sd">;
} // Predicates = [HasStdExtZalasr, IsRV64]

//===----------------------------------------------------------------------===//
// Pseudo-instructions and codegen patterns
//===----------------------------------------------------------------------===//

class PatLAQ<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT>
    : Pat<(vt (OpNode (vt GPRMemZeroOffset:$rs1))), (Inst GPRMemZeroOffset:$rs1)>;

// n.b. this switches order of arguments
//  to deal with the fact that SRL has addr, data
//  while atomic_store has data, addr
class PatSRL<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT>
    : Pat<(OpNode (vt GPR:$rs2), (vt GPRMemZeroOffset:$rs1)),
          (Inst GPRMemZeroOffset:$rs1, GPR:$rs2)>;


let Predicates = [HasStdExtZalasr] in {
  // the sequentially consistent loads use
  //  .aq instead of .aqrl to match the psABI/A.7
  def : PatLAQ<acquiring_load<atomic_load_asext_8>, LB_AQ>;
  def : PatLAQ<seq_cst_load<atomic_load_asext_8>, LB_AQ>;

  def : PatLAQ<acquiring_load<atomic_load_asext_16>, LH_AQ>;
  def : PatLAQ<seq_cst_load<atomic_load_asext_16>, LH_AQ>;

  // the sequentially consistent stores use
  //  .rl instead of .aqrl to match the psABI/A.7
  def : PatSRL<releasing_store<atomic_store_8>, SB_RL>;
  def : PatSRL<seq_cst_store<atomic_store_8>, SB_RL>;

  def : PatSRL<releasing_store<atomic_store_16>, SH_RL>;
  def : PatSRL<seq_cst_store<atomic_store_16>, SH_RL>;

  def : PatSRL<releasing_store<atomic_store_32>, SW_RL>;
  def : PatSRL<seq_cst_store<atomic_store_32>, SW_RL>;
} // Predicates = [HasStdExtZalasr]

let Predicates = [HasStdExtZalasr, IsRV32] in {
  def : PatLAQ<acquiring_load<atomic_load_nonext_32>, LW_AQ>;
  def : PatLAQ<seq_cst_load<atomic_load_nonext_32>, LW_AQ>;

} // Predicates = [HasStdExtZalasr, IsRV64]

let Predicates = [HasStdExtZalasr, IsRV64] in {
  def : PatLAQ<acquiring_load<atomic_load_asext_32>, LW_AQ>;
  def : PatLAQ<seq_cst_load<atomic_load_asext_32>, LW_AQ>;

  def : PatLAQ<acquiring_load<atomic_load_nonext_64>, LD_AQ>;
  def : PatLAQ<seq_cst_load<atomic_load_nonext_64>, LD_AQ>;

  def : PatSRL<releasing_store<atomic_store_64>, SD_RL>;
  def : PatSRL<seq_cst_store<atomic_store_64>, SD_RL>;
} // Predicates = [HasStdExtZalasr, IsRV64]