-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathRISCVInstrInfoXCheri.td
1579 lines (1291 loc) · 65.6 KB
/
RISCVInstrInfoXCheri.td
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//===-- RISCVInstrInfoXCheri.td - XCheri RISCV instructions -*- tblgen-*---===//
//
// 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
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// RISC-V specific DAG Nodes.
//===----------------------------------------------------------------------===//
// Target-dependent type requirements.
def SDT_RISCVCapCall : SDTypeProfile<0, -1, [SDTCisVT<0, CLenVT>]>;
def SDT_RISCVCheriBoolUnary : SDTypeProfile<1, 1, [
SDTCisInt<0>, SDTCisVT<1, CLenVT>
]>;
def SDT_RISCVCheriBoolBinary : SDTypeProfile<1, 2, [
SDTCisInt<0>, SDTCisVT<1, CLenVT>, SDTCisVT<2, CLenVT>
]>;
// Target-dependent nodes.
def riscv_cap_call : SDNode<"RISCVISD::CAP_CALL", SDT_RISCVCapCall,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
SDNPVariadic]>;
def riscv_cap_tail : SDNode<"RISCVISD::CAP_TAIL", SDT_RISCVCapCall,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
SDNPVariadic]>;
def riscv_cap_tag_get : SDNode<"RISCVISD::CAP_TAG_GET",
SDT_RISCVCheriBoolUnary>;
def riscv_cap_sealed_get : SDNode<"RISCVISD::CAP_SEALED_GET",
SDT_RISCVCheriBoolUnary>;
def riscv_cap_subset_test : SDNode<"RISCVISD::CAP_SUBSET_TEST",
SDT_RISCVCheriBoolBinary>;
def riscv_cap_equal_exact : SDNode<"RISCVISD::CAP_EQUAL_EXACT",
SDT_RISCVCheriBoolBinary>;
//===----------------------------------------------------------------------===//
// Operand and SDNode transformation definitions.
//===----------------------------------------------------------------------===//
def TPRelCIncOffsetSymbol : AsmOperandClass {
let Name = "TPRelCIncOffsetSymbol";
let RenderMethod = "addImmOperands";
let DiagnosticType = "InvalidTPRelCIncOffsetSymbol";
let ParserMethod = "parseOperandWithModifier";
}
// A bare symbol with the %tprel_add variant.
def tprel_cincoffset_symbol : Operand<XLenVT> {
let ParserMatchClass = TPRelCIncOffsetSymbol;
}
def CheriAtomicMemOpOperand : AsmOperandClass {
let Name = "CheriAtomicMemOpOperand";
let RenderMethod = "addRegOperands";
let PredicateMethod = "isGPCR";
let ParserMethod = "parseAtomicMemOp";
}
def GPCRMemAtomic : RegisterOperand<GPCR> {
let ParserMatchClass = CheriAtomicMemOpOperand;
let PrintMethod = "printAtomicMemOp";
}
def CapFI64 : ComplexPattern<iFATPTR64, 1, "SelectCapFI", [frameindex], []>;
def CapFI128 : ComplexPattern<iFATPTR128, 1, "SelectCapFI", [frameindex], []>;
//===----------------------------------------------------------------------===//
// Instruction Formats
//===----------------------------------------------------------------------===//
include "RISCVInstrFormatsXCheri.td"
//===----------------------------------------------------------------------===//
// Instruction Class Templates
//===----------------------------------------------------------------------===//
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class Cheri_r<bits<5> funct5, string opcodestr, RegisterClass rdClass=GPR,
RegisterClass rs1Class=GPCR>
: RVInstCheriSrcDst<0x7f, funct5, 0, OPC_CHERI, (outs rdClass:$rd),
(ins rs1Class:$rs1), opcodestr, "$rd, $rs1">;
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class Cheri_rr<bits<7> funct7, string opcodestr, RegisterClass rdClass=GPCR,
RegisterClass rs2Class=GPR, RegisterClass rs1Class=GPCR>
: RVInstR<funct7, 0, OPC_CHERI, (outs rdClass:$rd),
(ins rs1Class:$rs1, rs2Class:$rs2),
opcodestr, "$rd, $rs1, $rs2">;
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class Cheri_ri<bits<3> funct3, string opcodestr, bit simm>
: RVInstI<funct3, OPC_CHERI, (outs GPCR:$rd),
(ins GPCR:$rs1, !if(simm,simm12,uimm12):$imm12),
opcodestr, "$rd, $rs1, $imm12">;
let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
class Cheri_clear<bits<5> funct5, string opcodestr>
: RVInstCheriClear<0x7f, funct5, 0, OPC_CHERI, (outs),
(ins uimm2:$quarter, uimm8:$mask),
opcodestr, "$quarter, $mask">;
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
class CheriLoad_r<bits<5> op, string opcodestr, RegisterClass rdClass,
RegisterOperand rs1Operand>
: RVInstCheriSrcDst<0x7d, op, 0, OPC_CHERI, (outs rdClass:$rd),
(ins rs1Operand:$rs1), opcodestr, "$rd, $rs1">;
let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
class CheriStore_r<bits<5> op, string opcodestr, RegisterClass rs2Class,
RegisterOperand rs1Operand>
: RVInstCheriTwoSrc<0x7c, op, 0, OPC_CHERI, (outs),
(ins rs2Class:$rs2, rs1Operand:$rs1),
opcodestr, "$rs2, $rs1">;
let hasSideEffects = 0, mayLoad = 0, mayStore = 1, Constraints = "$rd = $rs2" in
class CheriStoreCond_r<bits<5> op, string opcodestr, RegisterClass rs2Class,
RegisterOperand rs1Operand>
: RVInstCheriTwoSrc<0x7c, op, 0, OPC_CHERI, (outs rs2Class:$rd),
(ins rs2Class:$rs2, rs1Operand:$rs1),
opcodestr, "$rs2, $rs1">;
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
class LR_C_r<bit aq, bit rl, bits<3> funct3, string opcodestr>
: RVInstRAtomic<0b00010, aq, rl, funct3, OPC_AMO,
(outs GPCR:$rd), (ins GPRMemAtomic:$rs1),
opcodestr, "$rd, $rs1"> {
let rs2 = 0;
}
multiclass LR_C_r_aq_rl<string clenstr, bits<3> funct3, string opcodestr> {
def _ # clenstr : LR_C_r<0, 0, funct3, opcodestr>;
def _AQ_ # clenstr : LR_C_r<1, 0, funct3, opcodestr # ".aq">;
def _RL_ # clenstr : LR_C_r<0, 1, funct3, opcodestr # ".rl">;
def _AQ_RL_ # clenstr : LR_C_r<1, 1, funct3, opcodestr # ".aqrl">;
}
let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in
class AMO_C_rr<bits<5> funct5, bit aq, bit rl, bits<3> funct3, string opcodestr,
RegisterClass rdClass>
: RVInstRAtomic<funct5, aq, rl, funct3, OPC_AMO,
(outs rdClass:$rd), (ins GPRMemAtomic:$rs1, GPCR:$rs2),
opcodestr, "$rd, $rs2, $rs1">;
multiclass AMO_C_rr_aq_rl<string clenstr, bits<5> funct5, bits<3> funct3,
string opcodestr, RegisterClass rdClass> {
def _ # clenstr : AMO_C_rr<funct5, 0, 0, funct3, opcodestr, rdClass>;
def _AQ_ # clenstr : AMO_C_rr<funct5, 1, 0, funct3, opcodestr # ".aq",
rdClass>;
def _RL_ # clenstr : AMO_C_rr<funct5, 0, 1, funct3, opcodestr # ".rl",
rdClass>;
def _AQ_RL_ # clenstr : AMO_C_rr<funct5, 1, 1, funct3, opcodestr # ".aqrl",
rdClass>;
}
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
class CheriLoad_ri<bits<3> funct3, string opcodestr>
: RVInstI<funct3, OPC_LOAD, (outs GPR:$rd), (ins GPCR:$rs1, simm12:$imm12),
opcodestr, "$rd, ${imm12}(${rs1})">;
let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
class CheriStore_ri<bits<3> funct3, string opcodestr>
: RVInstS<funct3, OPC_STORE, (outs),
(ins GPR:$rs2, GPCR:$rs1, simm12:$imm12),
opcodestr, "$rs2, ${imm12}(${rs1})">;
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
class CLR_r<bit aq, bit rl, bits<3> funct3, string opcodestr>
: RVInstRAtomic<0b00010, aq, rl, funct3, OPC_AMO,
(outs GPR:$rd), (ins GPCRMemAtomic:$rs1),
opcodestr, "$rd, $rs1"> {
let rs2 = 0;
}
multiclass CLR_r_aq_rl<bits<3> funct3, string opcodestr> {
def "" : CLR_r<0, 0, funct3, opcodestr>;
def _AQ : CLR_r<1, 0, funct3, opcodestr # ".aq">;
def _RL : CLR_r<0, 1, funct3, opcodestr # ".rl">;
def _AQ_RL : CLR_r<1, 1, funct3, opcodestr # ".aqrl">;
}
let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in
class CAMO_rr<bits<5> funct5, bit aq, bit rl, bits<3> funct3, string opcodestr>
: RVInstRAtomic<funct5, aq, rl, funct3, OPC_AMO,
(outs GPR:$rd), (ins GPCRMemAtomic:$rs1, GPR:$rs2),
opcodestr, "$rd, $rs2, $rs1">;
multiclass CAMO_rr_aq_rl<bits<5> funct5, bits<3> funct3, string opcodestr> {
def "" : CAMO_rr<funct5, 0, 0, funct3, opcodestr>;
def _AQ : CAMO_rr<funct5, 1, 0, funct3, opcodestr # ".aq">;
def _RL : CAMO_rr<funct5, 0, 1, funct3, opcodestr # ".rl">;
def _AQ_RL : CAMO_rr<funct5, 1, 1, funct3, opcodestr # ".aqrl">;
}
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
class CLR_C_r<bit aq, bit rl, bits<3> funct3, string opcodestr>
: RVInstRAtomic<0b00010, aq, rl, funct3, OPC_AMO,
(outs GPCR:$rd), (ins GPCRMemAtomic:$rs1),
opcodestr, "$rd, $rs1"> {
let rs2 = 0;
}
multiclass CLR_C_r_aq_rl<string clenstr, bits<3> funct3, string opcodestr> {
def _ # clenstr : CLR_C_r<0, 0, funct3, opcodestr>;
def _AQ_ # clenstr : CLR_C_r<1, 0, funct3, opcodestr # ".aq">;
def _RL_ # clenstr : CLR_C_r<0, 1, funct3, opcodestr # ".rl">;
def _AQ_RL_ # clenstr : CLR_C_r<1, 1, funct3, opcodestr # ".aqrl">;
}
let hasSideEffects = 0, mayLoad = 1, mayStore = 1 in
class CAMO_C_rr<bits<5> funct5, bit aq, bit rl, bits<3> funct3,
string opcodestr, RegisterClass rdClass>
: RVInstRAtomic<funct5, aq, rl, funct3, OPC_AMO,
(outs rdClass:$rd), (ins GPCRMemAtomic:$rs1, GPCR:$rs2),
opcodestr, "$rd, $rs2, $rs1">;
multiclass CAMO_C_rr_aq_rl<string clenstr, bits<5> funct5, bits<3> funct3,
string opcodestr, RegisterClass rdClass> {
def _ # clenstr : CAMO_C_rr<funct5, 0, 0, funct3, opcodestr, rdClass>;
def _AQ_ # clenstr : CAMO_C_rr<funct5, 1, 0, funct3, opcodestr # ".aq",
rdClass>;
def _RL_ # clenstr : CAMO_C_rr<funct5, 0, 1, funct3, opcodestr # ".rl",
rdClass>;
def _AQ_RL_ # clenstr : CAMO_C_rr<funct5, 1, 1, funct3, opcodestr # ".aqrl",
rdClass>;
}
//===----------------------------------------------------------------------===//
// Capability-Inspection Instructions
//===----------------------------------------------------------------------===//
let Predicates = [HasCheri] in {
def CGetPerm : Cheri_r<0x0, "cgetperm">;
def CGetType : Cheri_r<0x1, "cgettype">;
def CGetBase : Cheri_r<0x2, "cgetbase">;
def CGetLen : Cheri_r<0x3, "cgetlen">;
def CGetTag : Cheri_r<0x4, "cgettag">;
def CGetSealed : Cheri_r<0x5, "cgetsealed">;
def CGetOffset : Cheri_r<0x6, "cgetoffset">;
def CGetFlags : Cheri_r<0x7, "cgetflags">;
def CGetAddr : Cheri_r<0xf, "cgetaddr">;
}
//===----------------------------------------------------------------------===//
// Capability-Modification Instructions
//===----------------------------------------------------------------------===//
let Predicates = [HasCheri] in {
let Constraints = "@traps_if_sealed $rs1" in {
let mayTrap = 1 in {
let defsCanBeSealed = 1 in
def CSeal : Cheri_rr<0xb, "cseal", GPCR, GPCR>;
def CUnseal : Cheri_rr<0xc, "cunseal", GPCR, GPCR>;
def CAndPerm : Cheri_rr<0xd, "candperm">;
} // let mayTrap = 1
def CSetFlags : Cheri_rr<0xe, "csetflags">;
def CSetOffset : Cheri_rr<0xf, "csetoffset">;
def CSetAddr : Cheri_rr<0x10, "csetaddr">;
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
def CIncOffset : Cheri_rr<0x11, "cincoffset">;
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
def CIncOffsetImm : Cheri_ri<0x1, "cincoffset", 1>;
// Note: mayTrap is optimized in RISCVInstrInfo::isGuaranteedNotToTrap()
let mayTrap = 1 in {
def CSetBounds : Cheri_rr<0x8, "csetbounds">;
def CSetBoundsExact : Cheri_rr<0x9, "csetboundsexact">;
def CSetBoundsImm : Cheri_ri<0x2, "csetbounds", 0>;
} // mayTrap = 1
} // let Constraints = "@traps_if_sealed $rs1"
def CClearTag : Cheri_r<0xb, "ccleartag", GPCR>;
let mayTrap = 1 in {
let defsCanBeSealed = 1 in
def CBuildCap : Cheri_rr<0x1d, "cbuildcap", GPCR, GPCR, GPCRC0IsDDC>;
def CCopyType : Cheri_rr<0x1e, "ccopytype", GPCR, GPCR>;
let defsCanBeSealed = 1 in
def CCSeal : Cheri_rr<0x1f, "ccseal", GPCR, GPCR>;
let defsCanBeSealed = 1 in
def CSealEntry : Cheri_r<0x11, "csealentry", GPCR>;
} // let mayTrap = 1
def : InstAlias<"cincoffsetimm $cd, $cs1, $imm",
(CIncOffsetImm GPCR:$cd, GPCR:$cs1, simm12:$imm), 0>;
def : InstAlias<"csetboundsimm $cd, $cs1, $imm",
(CSetBoundsImm GPCR:$cd, GPCR:$cs1, uimm12:$imm), 0>;
}
//===----------------------------------------------------------------------===//
// Pointer-Arithmetic Instructions
//===----------------------------------------------------------------------===//
let Predicates = [HasCheri] in {
let mayTrap = 1 in {
def CToPtr : Cheri_rr<0x12, "ctoptr", GPR, GPCRC0IsDDC>;
def CFromPtr : Cheri_rr<0x13, "cfromptr", GPCR, GPR, GPCRC0IsDDC>;
}
def CSub : Cheri_rr<0x14, "csub", GPR, GPCR>;
let isMoveReg = 1, isReMaterializable = 1, isAsCheapAsAMove = 1,
defsCanBeSealed = 1 in
def CMove : Cheri_r<0xa, "cmove", GPCR>;
}
//===----------------------------------------------------------------------===//
// Control-Flow Instructions
//===----------------------------------------------------------------------===//
let Predicates = [HasCheri] in {
let isCall = 1, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
def CJALR : RVInstCheriSrcDst<0x7f, 0xc, 0, OPC_CHERI, (outs GPCR:$rd),
(ins GPCR:$rs1), "cjalr", "$rd, $rs1">;
let isCall = 1, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
def CInvoke : RVInstCheriTwoSrc<0x7e, 0x1, 0, OPC_CHERI, (outs),
(ins GPCR:$rs1, GPCR:$rs2),
"cinvoke", "$rs1, $rs2">;
def : InstAlias<"cjalr $cs1", (CJALR C1, GPCR:$cs1), 1>;
def : InstAlias<"cjr $cs1", (CJALR C0, GPCR:$cs1), 1>;
def : InstAlias<"cret", (CJALR C0, C1), 2>;
}
let Predicates = [HasCheri, IsPureCapABI],
isCall = 1, Defs = [C1] in
def PseudoCapCALLIndirect : Pseudo<(outs), (ins GPCR:$rs1),
[(riscv_cap_call GPCR:$rs1)]>,
PseudoInstExpansion<(CJALR C1, GPCR:$rs1)>;
let Predicates = [HasCheri, IsPureCapABI],
isBarrier = 1, isReturn = 1, isTerminator = 1 in
def PseudoCapRET : Pseudo<(outs), (ins), [(riscv_ret_flag)]>,
PseudoInstExpansion<(CJALR C0, C1)>;
let Predicates = [HasCheri, IsPureCapABI],
isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [C2] in
def PseudoCapTAILIndirect : Pseudo<(outs), (ins GPCRTC:$rs1),
[(riscv_cap_tail GPCRTC:$rs1)]>,
PseudoInstExpansion<(CJALR C0, GPCR:$rs1)>;
//===----------------------------------------------------------------------===//
// Assertion Instructions
//===----------------------------------------------------------------------===//
let Predicates = [HasCheri] in {
def CTestSubset : Cheri_rr<0x20, "ctestsubset", GPR, GPCR, GPCRC0IsDDC>;
def CSEQX : Cheri_rr<0x21, "csetequalexact", GPR, GPCR, GPCR>;
def : InstAlias<"cseqx $rd, $cs1, $cs2", (CSEQX GPR:$rd, GPCR:$cs1, GPCR:$cs2)>;
}
//===----------------------------------------------------------------------===//
// Special Capabilty Register Access Instructions
//===----------------------------------------------------------------------===//
let Predicates = [HasCheri] in {
let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
def CSpecialRW : RVInstCheriSCR<0x1, 0, OPC_CHERI, (outs GPCR:$rd),
(ins special_capreg:$imm5, GPCR:$rs1),
"cspecialrw", "$rd, $imm5, $rs1">;
def : InstAlias<"cspecialr $cd, $scr",
(CSpecialRW GPCR:$cd, special_capreg:$scr, C0)>;
def : InstAlias<"cspecialw $scr, $cs",
(CSpecialRW C0, special_capreg:$scr, GPCRNoC0:$cs)>;
}
//===----------------------------------------------------------------------===//
// Fast Register-Clearing Instructions
//===----------------------------------------------------------------------===//
let Predicates = [HasCheri], hasSideEffects = 1 in {
def Clear : Cheri_clear<0xd, "clear">;
def FPClear : Cheri_clear<0x10, "fpclear">;
}
//===----------------------------------------------------------------------===//
// Adjusting to Compressed Capability Precision Instructions
//===----------------------------------------------------------------------===//
let Predicates = [HasCheri] in {
def CRRL : Cheri_r<0x8, "croundrepresentablelength", GPR, GPR>;
def CRAM : Cheri_r<0x9, "crepresentablealignmentmask", GPR, GPR>;
def : InstAlias<"crrl $rd, $rs1", (CRRL GPR:$rd, GPR:$rs1)>;
def : InstAlias<"cram $rd, $rs1", (CRAM GPR:$rd, GPR:$rs1)>;
}
//===----------------------------------------------------------------------===//
// Memory-Access with Explicit Address Type Instructions
//===----------------------------------------------------------------------===//
let Predicates = [HasCheri] in {
def LB_DDC : CheriLoad_r<0b00000, "lb.ddc", GPR, GPRMemAtomic>;
def LH_DDC : CheriLoad_r<0b00001, "lh.ddc", GPR, GPRMemAtomic>;
def LW_DDC : CheriLoad_r<0b00010, "lw.ddc", GPR, GPRMemAtomic>;
def LBU_DDC : CheriLoad_r<0b00100, "lbu.ddc", GPR, GPRMemAtomic>;
def LHU_DDC : CheriLoad_r<0b00101, "lhu.ddc", GPR, GPRMemAtomic>;
}
let Predicates = [HasCheri, IsRV64] in {
def LWU_DDC : CheriLoad_r<0b00110, "lwu.ddc", GPR, GPRMemAtomic>;
def LD_DDC : CheriLoad_r<0b00011, "ld.ddc", GPR, GPRMemAtomic>;
}
let DecoderNamespace = "RISCV32Only_",
Predicates = [HasCheri, IsRV32] in
def LC_DDC_64 : CheriLoad_r<0b00011, "lc.ddc", GPCR, GPRMemAtomic>;
let Predicates = [HasCheri, IsRV64] in
def LC_DDC_128 : CheriLoad_r<0b10111, "lc.ddc", GPCR, GPRMemAtomic>;
let Predicates = [HasCheri] in {
def SB_DDC : CheriStore_r<0b00000, "sb.ddc", GPR, GPRMemAtomic>;
def SH_DDC : CheriStore_r<0b00001, "sh.ddc", GPR, GPRMemAtomic>;
def SW_DDC : CheriStore_r<0b00010, "sw.ddc", GPR, GPRMemAtomic>;
}
let Predicates = [HasCheri, IsRV64] in {
def SD_DDC : CheriStore_r<0b00011, "sd.ddc", GPR, GPRMemAtomic>;
}
let DecoderNamespace = "RISCV32Only_",
Predicates = [HasCheri, IsRV32] in
def SC_DDC_64 : CheriStore_r<0b00011, "sc.ddc", GPCR, GPRMemAtomic>;
let Predicates = [HasCheri, IsRV64] in
def SC_DDC_128 : CheriStore_r<0b00100, "sc.ddc", GPCR, GPRMemAtomic>;
let Predicates = [HasCheri] in {
def LB_CAP : CheriLoad_r<0b01000, "lb.cap", GPR, GPCRMemAtomic>;
def LH_CAP : CheriLoad_r<0b01001, "lh.cap", GPR, GPCRMemAtomic>;
def LW_CAP : CheriLoad_r<0b01010, "lw.cap", GPR, GPCRMemAtomic>;
def LBU_CAP : CheriLoad_r<0b01100, "lbu.cap", GPR, GPCRMemAtomic>;
def LHU_CAP : CheriLoad_r<0b01101, "lhu.cap", GPR, GPCRMemAtomic>;
}
let Predicates = [HasCheri, IsRV64] in {
def LWU_CAP : CheriLoad_r<0b01110, "lwu.cap", GPR, GPCRMemAtomic>;
def LD_CAP : CheriLoad_r<0b01011, "ld.cap", GPR, GPCRMemAtomic>;
}
let DecoderNamespace = "RISCV32Only_",
Predicates = [HasCheri, IsRV32] in
def LC_CAP_64 : CheriLoad_r<0b01011, "lc.cap", GPCR, GPCRMemAtomic>;
let Predicates = [HasCheri, IsRV64] in
def LC_CAP_128 : CheriLoad_r<0b11111, "lc.cap", GPCR, GPCRMemAtomic>;
let Predicates = [HasCheri] in {
def SB_CAP : CheriStore_r<0b01000, "sb.cap", GPR, GPCRMemAtomic>;
def SH_CAP : CheriStore_r<0b01001, "sh.cap", GPR, GPCRMemAtomic>;
def SW_CAP : CheriStore_r<0b01010, "sw.cap", GPR, GPCRMemAtomic>;
}
let Predicates = [HasCheri, IsRV64] in {
def SD_CAP : CheriStore_r<0b01011, "sd.cap", GPR, GPCRMemAtomic>;
}
let DecoderNamespace = "RISCV32Only_",
Predicates = [HasCheri, IsRV32] in
def SC_CAP_64 : CheriStore_r<0b01011, "sc.cap", GPCR, GPCRMemAtomic>;
let Predicates = [HasCheri, IsRV64] in
def SC_CAP_128 : CheriStore_r<0b01100, "sc.cap", GPCR, GPCRMemAtomic>;
let Predicates = [HasCheri, HasStdExtA] in {
def LR_B_DDC : CheriLoad_r<0b10000, "lr.b.ddc", GPR, GPRMemAtomic>;
def LR_H_DDC : CheriLoad_r<0b10001, "lr.h.ddc", GPR, GPRMemAtomic>;
def LR_W_DDC : CheriLoad_r<0b10010, "lr.w.ddc", GPR, GPRMemAtomic>;
}
let Predicates = [HasCheri, HasStdExtA, IsRV64] in
def LR_D_DDC : CheriLoad_r<0b10011, "lr.d.ddc", GPR, GPRMemAtomic>;
let DecoderNamespace = "RISCV32Only_",
Predicates = [HasCheri, HasStdExtA, IsRV32] in
def LR_C_DDC_64 : CheriLoad_r<0b10011, "lr.c.ddc", GPCR, GPRMemAtomic>;
let Predicates = [HasCheri, HasStdExtA, IsRV64] in
def LR_C_DDC_128 : CheriLoad_r<0b10100, "lr.c.ddc", GPCR, GPRMemAtomic>;
let Predicates = [HasCheri, HasStdExtA] in {
def LR_B_CAP : CheriLoad_r<0b11000, "lr.b.cap", GPR, GPCRMemAtomic>;
def LR_H_CAP : CheriLoad_r<0b11001, "lr.h.cap", GPR, GPCRMemAtomic>;
def LR_W_CAP : CheriLoad_r<0b11010, "lr.w.cap", GPR, GPCRMemAtomic>;
}
let Predicates = [HasCheri, HasStdExtA, IsRV64] in
def LR_D_CAP : CheriLoad_r<0b11011, "lr.d.cap", GPR, GPCRMemAtomic>;
let DecoderNamespace = "RISCV32Only_",
Predicates = [HasCheri, HasStdExtA, IsRV32] in
def LR_C_CAP_64 : CheriLoad_r<0b11011, "lr.c.cap", GPCR, GPCRMemAtomic>;
let Predicates = [HasCheri, HasStdExtA, IsRV64] in
def LR_C_CAP_128 : CheriLoad_r<0b11100, "lr.c.cap", GPCR, GPCRMemAtomic>;
let Predicates = [HasCheri, HasStdExtA] in {
def SC_B_DDC : CheriStoreCond_r<0b10000, "sc.b.ddc", GPR, GPRMemAtomic>;
def SC_H_DDC : CheriStoreCond_r<0b10001, "sc.h.ddc", GPR, GPRMemAtomic>;
def SC_W_DDC : CheriStoreCond_r<0b10010, "sc.w.ddc", GPR, GPRMemAtomic>;
}
let Predicates = [HasCheri, HasStdExtA, IsRV64] in
def SC_D_DDC : CheriStoreCond_r<0b10011, "sc.d.ddc", GPR, GPRMemAtomic>;
let DecoderNamespace = "RISCV32Only_",
Predicates = [HasCheri, HasStdExtA, IsRV32] in
def SC_C_DDC_64 : CheriStoreCond_r<0b10011, "sc.c.ddc", GPCR, GPRMemAtomic>;
let Predicates = [HasCheri, HasStdExtA, IsRV64] in
def SC_C_DDC_128 : CheriStoreCond_r<0b10100, "sc.c.ddc", GPCR, GPRMemAtomic>;
let Predicates = [HasCheri, HasStdExtA] in {
def SC_B_CAP : CheriStoreCond_r<0b11000, "sc.b.cap", GPR, GPCRMemAtomic>;
def SC_H_CAP : CheriStoreCond_r<0b11001, "sc.h.cap", GPR, GPCRMemAtomic>;
def SC_W_CAP : CheriStoreCond_r<0b11010, "sc.w.cap", GPR, GPCRMemAtomic>;
}
let Predicates = [HasCheri, HasStdExtA, IsRV64] in
def SC_D_CAP : CheriStoreCond_r<0b11011, "sc.d.cap", GPR, GPCRMemAtomic>;
let DecoderNamespace = "RISCV32Only_",
Predicates = [HasCheri, HasStdExtA, IsRV32] in
def SC_C_CAP_64 : CheriStoreCond_r<0b11011, "sc.c.cap", GPCR, GPCRMemAtomic>;
let Predicates = [HasCheri, HasStdExtA, IsRV64] in
def SC_C_CAP_128 : CheriStoreCond_r<0b11100, "sc.c.cap", GPCR, GPCRMemAtomic>;
//===----------------------------------------------------------------------===//
// Memory-Access Instructions
//===----------------------------------------------------------------------===//
let Predicates = [HasCheri, IsRV32, NotCapMode] in {
let DecoderNamespace = "RISCV32Only_",
hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
def LC_64 : RVInstI<0x3, OPC_LOAD, (outs GPCR:$rd),
(ins GPR:$rs1, simm12:$imm12),
"lc", "$rd, ${imm12}(${rs1})">;
let DecoderNamespace = "RISCV32Only_",
hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
def SC_64 : RVInstS<0x3, OPC_STORE, (outs),
(ins GPCR:$rs2, GPR:$rs1, simm12:$imm12),
"sc", "$rs2, ${imm12}(${rs1})">;
let EmitPriority = 0 in {
def : InstAlias<"lc $rd, (${rs1})",
(LC_64 GPCR:$rd, GPR:$rs1, 0)>;
def : InstAlias<"sc $rs2, (${rs1})",
(SC_64 GPCR:$rs2, GPR:$rs1, 0)>;
}
}
let Predicates = [HasCheri, IsRV64, NotCapMode] in {
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
def LC_128 : RVInstI<0x2, OPC_MISC_MEM, (outs GPCR:$rd),
(ins GPR:$rs1, simm12:$imm12),
"lc", "$rd, ${imm12}(${rs1})">;
let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
def SC_128 : RVInstS<0x4, OPC_STORE, (outs),
(ins GPCR:$rs2, GPR:$rs1, simm12:$imm12),
"sc", "$rs2, ${imm12}(${rs1})">;
let EmitPriority = 0 in {
def : InstAlias<"lc $rd, (${rs1})",
(LC_128 GPCR:$rd, GPR:$rs1, 0)>;
def : InstAlias<"sc $rs2, (${rs1})",
(SC_128 GPCR:$rs2, GPR:$rs1, 0)>;
}
}
let DecoderNamespace = "RISCV32Only_",
Predicates = [HasCheri, HasStdExtA, IsRV32, NotCapMode] in {
defm LR_C : LR_C_r_aq_rl<"64", 0b011, "lr.c">;
defm SC_C : AMO_C_rr_aq_rl<"64", 0b00011, 0b011, "sc.c", GPR>;
defm AMOSWAP_C : AMO_C_rr_aq_rl<"64", 0b00001, 0b011, "amoswap.c", GPCR>;
}
let Predicates = [HasCheri, HasStdExtA, IsRV64, NotCapMode] in {
defm LR_C : LR_C_r_aq_rl<"128", 0b100, "lr.c">;
defm SC_C : AMO_C_rr_aq_rl<"128", 0b00011, 0b100, "sc.c", GPR>;
defm AMOSWAP_C : AMO_C_rr_aq_rl<"128", 0b00001, 0b100, "amoswap.c", GPCR>;
}
//===----------------------------------------------------------------------===//
// Capability Mode Instructions
//===----------------------------------------------------------------------===//
/// 'I' (Integer) base
let DecoderNamespace = "CapModeOnly_" in {
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
let Predicates = [HasCheri, IsCapMode] in
def AUIPCC : RVInstU<OPC_AUIPC, (outs GPCR:$rd), (ins uimm20_auipc:$imm20),
"auipcc", "$rd, $imm20">;
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
let Predicates = [HasCheri, IsCapMode] in {
def CLB : CheriLoad_ri<0b000, "clb">;
def CLH : CheriLoad_ri<0b001, "clh">;
def CLW : CheriLoad_ri<0b010, "clw">;
def CLBU : CheriLoad_ri<0b100, "clbu">;
def CLHU : CheriLoad_ri<0b101, "clhu">;
def CSB : CheriStore_ri<0b000, "csb">;
def CSH : CheriStore_ri<0b001, "csh">;
def CSW : CheriStore_ri<0b010, "csw">;
} // Predicates = [HasCheri, IsCapMode]
let Predicates = [HasCheri, IsRV64, IsCapMode] in {
def CLWU : CheriLoad_ri<0b110, "clwu">;
def CLD : CheriLoad_ri<0b011, "cld">;
def CSD : CheriStore_ri<0b011, "csd">;
} // Predicates = [HasCheri, IsRV64, IsCapMode]
} // DecoderNameSpace = "CapModeOnly_"
let Predicates = [HasCheri, IsRV32, IsCapMode] in {
let DecoderNamespace = "RISCV32CapModeOnly_",
hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
def CLC_64 : RVInstI<0x3, OPC_LOAD, (outs GPCR:$rd),
(ins GPCR:$rs1, simm12:$imm12),
"clc", "$rd, ${imm12}(${rs1})">;
let DecoderNamespace = "RISCV32CapModeOnly_",
hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
def CSC_64 : RVInstS<0x3, OPC_STORE, (outs),
(ins GPCR:$rs2, GPCR:$rs1, simm12:$imm12),
"csc", "$rs2, ${imm12}(${rs1})">;
let EmitPriority = 0 in {
def : InstAlias<"clc $rd, (${rs1})",
(CLC_64 GPCR:$rd, GPCR:$rs1, 0)>;
def : InstAlias<"csc $rs2, (${rs1})",
(CSC_64 GPCR:$rs2, GPCR:$rs1, 0)>;
}
}
let Predicates = [HasCheri, IsRV64, IsCapMode] in {
let DecoderNamespace = "CapModeOnly_",
hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
def CLC_128 : RVInstI<0x2, OPC_MISC_MEM, (outs GPCR:$rd),
(ins GPCR:$rs1, simm12:$imm12),
"clc", "$rd, ${imm12}(${rs1})">;
let DecoderNamespace = "CapModeOnly_",
hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
def CSC_128 : RVInstS<0x4, OPC_STORE, (outs),
(ins GPCR:$rs2, GPCR:$rs1, simm12:$imm12),
"csc", "$rs2, ${imm12}(${rs1})">;
let EmitPriority = 0 in {
def : InstAlias<"clc $rd, (${rs1})",
(CLC_128 GPCR:$rd, GPCR:$rs1, 0)>;
def : InstAlias<"csc $rs2, (${rs1})",
(CSC_128 GPCR:$rs2, GPCR:$rs1, 0)>;
}
}
let EmitPriority = 0 in {
let Predicates = [HasCheri, IsCapMode] in {
def : InstAlias<"clb $rd, (${rs1})",
(CLB GPR:$rd, GPCR:$rs1, 0)>;
def : InstAlias<"clh $rd, (${rs1})",
(CLH GPR:$rd, GPCR:$rs1, 0)>;
def : InstAlias<"clw $rd, (${rs1})",
(CLW GPR:$rd, GPCR:$rs1, 0)>;
def : InstAlias<"clbu $rd, (${rs1})",
(CLBU GPR:$rd, GPCR:$rs1, 0)>;
def : InstAlias<"clhu $rd, (${rs1})",
(CLHU GPR:$rd, GPCR:$rs1, 0)>;
def : InstAlias<"csb $rs2, (${rs1})",
(CSB GPR:$rs2, GPCR:$rs1, 0)>;
def : InstAlias<"csh $rs2, (${rs1})",
(CSH GPR:$rs2, GPCR:$rs1, 0)>;
def : InstAlias<"csw $rs2, (${rs1})",
(CSW GPR:$rs2, GPCR:$rs1, 0)>;
} // Predicates = [HasCheri, IsCapMode]
let Predicates = [HasCheri, IsRV64, IsCapMode] in {
def : InstAlias<"clwu $rd, (${rs1})",
(CLWU GPR:$rd, GPCR:$rs1, 0)>;
def : InstAlias<"cld $rd, (${rs1})",
(CLD GPR:$rd, GPCR:$rs1, 0)>;
def : InstAlias<"csd $rs2, (${rs1})",
(CSD GPR:$rs2, GPCR:$rs1, 0)>;
} // Predicates = [HasCheri, IsRV64, IsCapMode]
}
/// 'A' (Atomic Instructions) extension
let DecoderNamespace = "CapModeOnly_" in {
let Predicates = [HasCheri, HasStdExtA, IsCapMode] in {
defm CLR_B : CLR_r_aq_rl<0b000, "clr.b">;
defm CSC_B : CAMO_rr_aq_rl<0b00011, 0b000, "csc.b">;
defm CLR_H : CLR_r_aq_rl<0b001, "clr.h">;
defm CSC_H : CAMO_rr_aq_rl<0b00011, 0b001, "csc.h">;
defm CLR_W : CLR_r_aq_rl<0b010, "clr.w">;
defm CSC_W : CAMO_rr_aq_rl<0b00011, 0b010, "csc.w">;
defm CAMOSWAP_W : CAMO_rr_aq_rl<0b00001, 0b010, "camoswap.w">;
defm CAMOADD_W : CAMO_rr_aq_rl<0b00000, 0b010, "camoadd.w">;
defm CAMOXOR_W : CAMO_rr_aq_rl<0b00100, 0b010, "camoxor.w">;
defm CAMOAND_W : CAMO_rr_aq_rl<0b01100, 0b010, "camoand.w">;
defm CAMOOR_W : CAMO_rr_aq_rl<0b01000, 0b010, "camoor.w">;
defm CAMOMIN_W : CAMO_rr_aq_rl<0b10000, 0b010, "camomin.w">;
defm CAMOMAX_W : CAMO_rr_aq_rl<0b10100, 0b010, "camomax.w">;
defm CAMOMINU_W : CAMO_rr_aq_rl<0b11000, 0b010, "camominu.w">;
defm CAMOMAXU_W : CAMO_rr_aq_rl<0b11100, 0b010, "camomaxu.w">;
} // Predicates = [HasCheri, HasStdExtA, IsCapMode]
let Predicates = [HasCheri, HasStdExtA, IsRV64, IsCapMode] in {
defm CLR_D : CLR_r_aq_rl<0b011, "clr.d">;
defm CSC_D : CAMO_rr_aq_rl<0b00011, 0b011, "csc.d">;
defm CAMOSWAP_D : CAMO_rr_aq_rl<0b00001, 0b011, "camoswap.d">;
defm CAMOADD_D : CAMO_rr_aq_rl<0b00000, 0b011, "camoadd.d">;
defm CAMOXOR_D : CAMO_rr_aq_rl<0b00100, 0b011, "camoxor.d">;
defm CAMOAND_D : CAMO_rr_aq_rl<0b01100, 0b011, "camoand.d">;
defm CAMOOR_D : CAMO_rr_aq_rl<0b01000, 0b011, "camoor.d">;
defm CAMOMIN_D : CAMO_rr_aq_rl<0b10000, 0b011, "camomin.d">;
defm CAMOMAX_D : CAMO_rr_aq_rl<0b10100, 0b011, "camomax.d">;
defm CAMOMINU_D : CAMO_rr_aq_rl<0b11000, 0b011, "camominu.d">;
defm CAMOMAXU_D : CAMO_rr_aq_rl<0b11100, 0b011, "camomaxu.d">;
} // Predicates = [HasCheri, HasStdExtA, IsRV64, IsCapMode]
} // DecoderNamespace = "CapModeOnly_"
let DecoderNamespace = "RISCV32CapModeOnly_",
Predicates = [HasCheri, HasStdExtA, IsRV32, IsCapMode] in {
defm CLR_C : CLR_C_r_aq_rl<"64", 0b011, "clr.c">;
defm CSC_C : CAMO_C_rr_aq_rl<"64", 0b00011, 0b011, "csc.c", GPR>;
defm CAMOSWAP_C : CAMO_C_rr_aq_rl<"64", 0b00001, 0b011, "camoswap.c", GPCR>;
}
let DecoderNamespace = "CapModeOnly_",
Predicates = [HasCheri, HasStdExtA, IsRV64, IsCapMode] in {
defm CLR_C : CLR_C_r_aq_rl<"128", 0b100, "clr.c">;
defm CSC_C : CAMO_C_rr_aq_rl<"128", 0b00011, 0b100, "csc.c", GPR>;
defm CAMOSWAP_C : CAMO_C_rr_aq_rl<"128", 0b00001, 0b100, "camoswap.c", GPCR>;
}
/// 'F' (Single-Precision Floating-Point) extension
let Predicates = [HasCheri, HasStdExtF, IsCapMode] in {
let DecoderNamespace = "CapModeOnly_",
hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
def CFLW : RVInstI<0b010, OPC_LOAD_FP, (outs FPR32:$rd),
(ins GPCR:$rs1, simm12:$imm12),
"cflw", "$rd, ${imm12}(${rs1})">;
let DecoderNamespace = "CapModeOnly_",
hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
def CFSW : RVInstS<0b010, OPC_STORE_FP, (outs),
(ins FPR32:$rs2, GPCR:$rs1, simm12:$imm12),
"cfsw", "$rs2, ${imm12}(${rs1})">;
def : InstAlias<"cflw $rd, (${rs1})", (CFLW FPR32:$rd, GPCR:$rs1, 0), 0>;
def : InstAlias<"cfsw $rs2, (${rs1})", (CFSW FPR32:$rs2, GPCR:$rs1, 0), 0>;
} // Predicates = [HasCheri, HasStdExtF, IsCapMode]
/// 'D' (Single-Precision Floating-Point) extension
let Predicates = [HasCheri, HasStdExtD, IsCapMode] in {
let DecoderNamespace = "CapModeOnly_",
hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
def CFLD : RVInstI<0b011, OPC_LOAD_FP, (outs FPR64:$rd),
(ins GPCR:$rs1, simm12:$imm12),
"cfld", "$rd, ${imm12}(${rs1})">;
let DecoderNamespace = "CapModeOnly_",
hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
def CFSD : RVInstS<0b011, OPC_STORE_FP, (outs),
(ins FPR64:$rs2, GPCR:$rs1, simm12:$imm12),
"cfsd", "$rs2, ${imm12}(${rs1})">;
def : InstAlias<"cfld $rd, (${rs1})", (CFLD FPR64:$rd, GPCR:$rs1, 0), 0>;
def : InstAlias<"cfsd $rs2, (${rs1})", (CFSD FPR64:$rs2, GPCR:$rs1, 0), 0>;
} // Predicates = [HasCheri, HasStdExtD, IsCapMode]
/// 'C' (Compressed Instructions) extension
// TODO
//===----------------------------------------------------------------------===//
// Pseudo-instructions and codegen patterns
//===----------------------------------------------------------------------===//
let Predicates = [HasCheri, IsCapMode] in {
let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0,
isAsmParserOnly = 1 in
def PseudoCLLC : Pseudo<(outs GPCR:$dst), (ins bare_symbol:$src), [],
"cllc", "$dst, $src">;
let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0,
isAsmParserOnly = 1 in
def PseudoCLGC : Pseudo<(outs GPCR:$dst), (ins bare_symbol:$src), [],
"clgc", "$dst, $src">;
let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0,
isAsmParserOnly = 1 in
def PseudoCLA_TLS_IE : Pseudo<(outs GPR:$dst, GPCR:$tmp),
(ins bare_symbol:$src), [],
"cla.tls.ie", "$dst, $src, $tmp">;
let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0,
isAsmParserOnly = 1 in
def PseudoCLC_TLS_GD : Pseudo<(outs GPCR:$dst), (ins bare_symbol:$src), [],
"clc.tls.gd", "$dst, $src">;
let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0 in
def PseudoCIncOffsetTPRel : Pseudo<(outs GPCR:$rd),
(ins GPCR:$rs1, GPR:$rs2,
tprel_cincoffset_symbol:$src), [],
"cincoffset", "$rd, $rs1, $rs2, $src">;
}
class PatGpcr<SDPatternOperator OpNode, RVInstCheriSrcDst Inst>
: Pat<(OpNode GPCR:$rs1), (Inst GPCR:$rs1)>;
class PatGpr<SDPatternOperator OpNode, RVInstCheriSrcDst Inst>
: Pat<(OpNode GPR:$rs1), (Inst GPR:$rs1)>;
class PatGpcrGpcr<SDPatternOperator OpNode, RVInst Inst>
: Pat<(OpNode GPCR:$rs1, GPCR:$rs2), (Inst GPCR:$rs1, GPCR:$rs2)>;
class PatGpcrGpr<SDPatternOperator OpNode, RVInst Inst>
: Pat<(OpNode GPCR:$rs1, GPR:$rs2), (Inst GPCR:$rs1, GPR:$rs2)>;
class PatGpcrSimm12<SDPatternOperator OpNode, RVInstI Inst>
: Pat<(OpNode GPCR:$rs1, simm12:$imm12), (Inst GPCR:$rs1, simm12:$imm12)>;
class PatGpcrUimm12<SDPatternOperator OpNode, RVInstI Inst>
: Pat<(OpNode GPCR:$rs1, uimm12:$imm12), (Inst GPCR:$rs1, uimm12:$imm12)>;
class PatGprGpcr<SDPatternOperator OpNode, RVInst Inst>
: Pat<(OpNode GPR:$rs1, GPCR:$rs2), (Inst GPR:$rs1, GPCR:$rs2)>;
/// Capability-Inspection Instructions
def : PatGpcr<int_cheri_cap_perms_get, CGetPerm>;
def : PatGpcr<int_cheri_cap_type_get, CGetType>;
def : PatGpcr<int_cheri_cap_base_get, CGetBase>;
def : PatGpcr<int_cheri_cap_length_get, CGetLen>;
def : PatGpcr<riscv_cap_tag_get, CGetTag>;
def : PatGpcr<riscv_cap_sealed_get, CGetSealed>;
def : PatGpcr<int_cheri_cap_offset_get, CGetOffset>;
def : PatGpcr<int_cheri_cap_flags_get, CGetFlags>;
def : PatGpcr<int_cheri_cap_address_get, CGetAddr>;
/// Capability-Modification Instructions
def : PatGpcrGpcr<int_cheri_cap_seal, CSeal>;
def : PatGpcrGpcr<int_cheri_cap_unseal, CUnseal>;
def : PatGpcrGpr<int_cheri_cap_perms_and, CAndPerm>;
def : PatGpcrGpr<int_cheri_cap_flags_set, CSetFlags>;
def : PatGpcrGpr<int_cheri_cap_offset_set, CSetOffset>;
def : PatGpcrGpr<int_cheri_cap_address_set, CSetAddr>;
def : PatGpcrGpr<ptradd, CIncOffset>;
def : PatGpcrSimm12<ptradd, CIncOffsetImm>;
def : PatGpcrGpr<int_cheri_cap_bounds_set, CSetBounds>;
def : PatGpcrGpr<int_cheri_cap_bounds_set_exact, CSetBoundsExact>;
def : PatGpcrUimm12<int_cheri_cap_bounds_set, CSetBoundsImm>;
def : PatGpcr<int_cheri_cap_tag_clear, CClearTag>;
def : PatGpcrGpcr<int_cheri_cap_build, CBuildCap>;
def : PatGpcrGpcr<int_cheri_cap_type_copy, CCopyType>;
def : PatGpcrGpcr<int_cheri_cap_conditional_seal, CCSeal>;
def : PatGpcr<int_cheri_cap_seal_entry, CSealEntry>;
// TODO: Make this rematerialisable like MIPS
def : PatGpcrGpr<int_cheri_bounded_stack_cap, CSetBounds>;
/// Pointer-Arithmetic Instructions
def : Pat<(int_cheri_cap_to_pointer GPCR:$rs1, GPCRC0IsDDC:$rs2),
(CToPtr GPCR:$rs1, GPCRC0IsDDC:$rs2)>;
def : Pat<(int_cheri_cap_from_pointer GPCRC0IsDDC:$rs1, GPR:$rs2),
(CFromPtr GPCRC0IsDDC:$rs1, GPR:$rs2)>;
def : PatGpcrGpcr<int_cheri_cap_diff, CSub>;
let Predicates = [IsPureCapABI] in {
def : Pat<(inttoptr GPR:$rs2), (CIncOffset C0, GPR:$rs2)>;
def : Pat<(inttoptr simm12:$imm12), (CIncOffsetImm C0, simm12:$imm12)>;
def : Pat<(ptrtoint GPCR:$rs1), (CGetAddr GPCR:$rs1)>;
}
let Predicates = [NotPureCapABI] in {
def : Pat<(inttoptr GPR:$rs2), (CFromPtr DDC, GPR:$rs2)>;
def : Pat<(ptrtoint GPCR:$rs1), (CToPtr GPCR:$rs1, DDC)>;
}
def : Pat<(int_cheri_cap_to_pointer (CLenVT (int_cheri_ddc_get)), GPCR:$rs1),
(CToPtr $rs1, DDC)>;
def : Pat<(int_cheri_cap_from_pointer (CLenVT (int_cheri_ddc_get)), GPR:$rs2),
(CFromPtr DDC, $rs2)>;
/// Null Capability Patterns
def : Pat<(int_cheri_cap_from_pointer DDC, (XLenVT 0)), (CLenVT (COPY C0))>;
def : Pat<(inttoptr (XLenVT 0)), (CLenVT (COPY C0))>;
def : Pat<(ptrtoint C0), (XLenVT (COPY X0))>;
/// Pointer-Comparison Instructions
// Currently no dedicated instructions, so we:
// * Rely on a merged register file
// * Break untagged < tagged semantics
// * Can't implement exact equality
class CheriSetCCPatGpcrGpcr<PatFrag CondOp, dag GprGprDag>
: Pat<(CondOp GPCR:$cs1, GPCR:$cs2),
(OutPatFrag<(ops node:$rs1, node:$rs2), GprGprDag>
(EXTRACT_SUBREG GPCR:$cs1, sub_cap_addr),
(EXTRACT_SUBREG GPCR:$cs2, sub_cap_addr))>;
multiclass CheriSetCCPatGpcrSimm12<PatFrag CondOp, dag GprSimm12Dag> {
def : Pat<(CondOp GPCR:$cs1, (inttoptr simm12:$imm12)),
(OutPatFrag<(ops node:$rs1, node:$imm12), GprSimm12Dag>
(EXTRACT_SUBREG GPCR:$cs1, sub_cap_addr), simm12:$imm12)>;
def : Pat<(CondOp GPCR:$cs1,
(ptradd (inttoptr (XLenVT 0)), simm12:$imm12)),
(OutPatFrag<(ops node:$rs1, node:$imm12), GprSimm12Dag>
(EXTRACT_SUBREG GPCR:$cs1, sub_cap_addr), simm12:$imm12)>;
def : Pat<(CondOp GPCR:$cs1,
(int_cheri_cap_offset_set
(iFATPTR64 (inttoptr (XLenVT 0))), simm12:$imm12)),
(OutPatFrag<(ops node:$rs1, node:$imm12), GprSimm12Dag>
(EXTRACT_SUBREG GPCR:$cs1, sub_cap_addr), simm12:$imm12)>;
def : Pat<(CondOp GPCR:$cs1,
(int_cheri_cap_offset_set
(iFATPTR64 (inttoptr (XLenVT 0))), simm12:$imm12)),
(OutPatFrag<(ops node:$rs1, node:$imm12), GprSimm12Dag>
(EXTRACT_SUBREG GPCR:$cs1, sub_cap_addr), simm12:$imm12)>;
def : Pat<(CondOp GPCR:$cs1,
(int_cheri_cap_address_set
(iFATPTR64 (inttoptr (XLenVT 0))), simm12:$imm12)),
(OutPatFrag<(ops node:$rs1, node:$imm12), GprSimm12Dag>
(EXTRACT_SUBREG GPCR:$cs1, sub_cap_addr), simm12:$imm12)>;
def : Pat<(CondOp GPCR:$cs1,
(int_cheri_cap_address_set
(iFATPTR128 (inttoptr (XLenVT 0))), simm12:$imm12)),
(OutPatFrag<(ops node:$rs1, node:$imm12), GprSimm12Dag>
(EXTRACT_SUBREG GPCR:$cs1, sub_cap_addr), simm12:$imm12)>;
}
class CheriSetCCPatGpcrNull<PatFrag CondOp, dag GprDag>
: Pat<(CondOp GPCR:$cs1, (inttoptr (XLenVT 0))),
(OutPatFrag<(ops node:$rs1), GprDag>
(EXTRACT_SUBREG GPCR:$cs1, sub_cap_addr))>;
class Swap<PatFrag BinFrag>
: PatFrag<(ops node:$a, node:$b), (BinFrag $b, $a)>;
def : CheriSetCCPatGpcrNull<seteq, (SLTIU node:$rs1, 1)>;
def : CheriSetCCPatGpcrGpcr<seteq, (SLTIU (XOR node:$rs1, node:$rs2), 1)>;
defm : CheriSetCCPatGpcrSimm12<seteq, (SLTIU (XORI node:$rs1, node:$imm12), 1)>;
defm : CheriSetCCPatGpcrSimm12<Swap<seteq>, (SLTIU (XORI node:$rs1, node:$imm12), 1)>;
def : CheriSetCCPatGpcrNull<setne, (SLTU X0, node:$rs1)>;
def : CheriSetCCPatGpcrGpcr<setne, (SLTU X0, (XOR node:$rs1, node:$rs2))>;
defm : CheriSetCCPatGpcrSimm12<setne, (SLTU X0, (XORI node:$rs1, node:$imm12))>;
defm : CheriSetCCPatGpcrSimm12<Swap<setne>, (SLTU X0, (XORI node:$rs1, node:$imm12))>;
def : CheriSetCCPatGpcrGpcr<setugt, (SLTU node:$rs2, node:$rs1)>;
defm : CheriSetCCPatGpcrSimm12<Swap<setugt>, (SLTIU node:$rs1, node:$imm12)>;
def : CheriSetCCPatGpcrGpcr<setuge, (XORI (SLTU node:$rs1, node:$rs2), 1)>;
def : CheriSetCCPatGpcrGpcr<setule, (XORI (SLTU node:$rs2, node:$rs1), 1)>;
def : CheriSetCCPatGpcrGpcr<setult, (SLTU node:$rs1, node:$rs2)>;
defm : CheriSetCCPatGpcrSimm12<setult, (SLTIU node:$rs1, node:$imm12)>;
def : CheriSetCCPatGpcrGpcr<setgt, (SLT node:$rs2, node:$rs1)>;
defm : CheriSetCCPatGpcrSimm12<Swap<setgt>, (SLTI node:$rs1, node:$imm12)>;
def : CheriSetCCPatGpcrGpcr<setge, (XORI (SLT node:$rs1, node:$rs2), 1)>;
def : CheriSetCCPatGpcrGpcr<setle, (XORI (SLT node:$rs2, node:$rs1), 1)>;
def : CheriSetCCPatGpcrGpcr<setlt, (SLT node:$rs1, node:$rs2)>;
defm : CheriSetCCPatGpcrSimm12<setlt, (SLTI node:$rs1, node:$imm12)>;
def Select_GPCR_Using_CC_GPR : SelectCC_rrirr<GPCR, GPR>;
/// Control-Flow Instructions
// No dedicated instructions; see above
class CheriBccPat<PatFrag CondOp, RVInstB Inst>
: Pat<(brcond (XLenVT (CondOp GPCR:$rs1, GPCR:$rs2)), bb:$imm12),
(Inst
(EXTRACT_SUBREG GPCR:$rs1, sub_cap_addr),
(EXTRACT_SUBREG GPCR:$rs2, sub_cap_addr),
simm13_lsb0:$imm12)>;
def : CheriBccPat<seteq, BEQ>;
def : CheriBccPat<setne, BNE>;
def : CheriBccPat<setlt, BLT>;
def : CheriBccPat<setge, BGE>;
def : CheriBccPat<setult, BLTU>;
def : CheriBccPat<setuge, BGEU>;
class CheriBccSwapPat<PatFrag CondOp, RVInst InstBcc>
: Pat<(brcond (XLenVT (CondOp GPCR:$rs1, GPCR:$rs2)), bb:$imm12),
(InstBcc
(EXTRACT_SUBREG GPCR:$rs2, sub_cap_addr),