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]
|