llvm.org GIT mirror llvm / 631bc69
[RISCV] Add basic RV32E definitions and MC layer support The RISC-V ISA defines RV32E as an alternative "base" instruction set encoding, that differs from RV32I by having only 16 rather than 32 registers. This patch adds basic definitions for RV32E as well as MC layer support (assembling, disassembling) and tests. The only supported ABI on RV32E is ILP32E. Add a new RISCVFeatures::validate() helper to RISCVUtils which can be called from codegen or MC layer libraries to validate the combination of TargetTriple and FeatureBitSet. Other targets have similar checks (e.g. erroring if SPE is enabled on PPC64 or oddspreg + o32 ABI on Mips), but they either duplicate the checks (Mips), or fail to check for both codegen and MC codepaths (PPC). Codegen for the ILP32E ABI support and RV32E codegen are left for a future patch/patches. Differential Revision: https://reviews.llvm.org/D59470 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356744 91177308-0d34-0410-b5e6-96231b3b80d8 Alex Bradbury 1 year, 8 months ago
16 changed file(s) with 333 addition(s) and 15 deletion(s). Raw diff Collapse all Expand all
4646
4747 SMLoc getLoc() const { return getParser().getTok().getLoc(); }
4848 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
49 bool isRV32E() const { return getSTI().hasFeature(RISCV::FeatureRV32E); }
4950
5051 RISCVTargetStreamer &getTargetStreamer() {
5152 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
909910
910911 // Attempts to match Name as a register (either using the default name or
911912 // alternative ABI names), setting RegNo to the matching register. Upon
912 // failure, returns true and sets RegNo to 0.
913 static bool matchRegisterNameHelper(unsigned &RegNo, StringRef Name) {
913 // failure, returns true and sets RegNo to 0. If IsRV32E then registers
914 // x16-x31 will be rejected.
915 static bool matchRegisterNameHelper(bool IsRV32E, unsigned &RegNo,
916 StringRef Name) {
914917 RegNo = MatchRegisterName(Name);
915918 if (RegNo == 0)
916919 RegNo = MatchRegisterAltName(Name);
920 if (IsRV32E && RegNo >= RISCV::X16 && RegNo <= RISCV::X31)
921 RegNo = 0;
917922 return RegNo == 0;
918923 }
919924
925930 RegNo = 0;
926931 StringRef Name = getLexer().getTok().getIdentifier();
927932
928 if (matchRegisterNameHelper(RegNo, Name))
933 if (matchRegisterNameHelper(isRV32E(), RegNo, Name))
929934 return Error(StartLoc, "invalid register name");
930935
931936 getParser().Lex(); // Eat identifier token.
953958 case AsmToken::Identifier:
954959 StringRef Name = getLexer().getTok().getIdentifier();
955960 unsigned RegNo;
956 matchRegisterNameHelper(RegNo, Name);
961 matchRegisterNameHelper(isRV32E(), RegNo, Name);
957962
958963 if (RegNo == 0) {
959964 if (HadParens)
6868 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
6969 uint64_t Address,
7070 const void *Decoder) {
71 if (RegNo > array_lengthof(GPRDecoderTable))
71 const FeatureBitset &FeatureBits =
72 static_cast(Decoder)
73 ->getSubtargetInfo()
74 .getFeatureBits();
75 bool IsRV32E = FeatureBits[RISCV::FeatureRV32E];
76
77 if (RegNo > array_lengthof(GPRDecoderTable) || (IsRV32E && RegNo > 15))
7278 return MCDisassembler::Fail;
7379
7480 // We must define our own mapping from RegNo to register identifier.
3535 TargetOptions(Options) {
3636 TargetABI = RISCVABI::computeTargetABI(
3737 STI.getTargetTriple(), STI.getFeatureBits(), Options.getABIName());
38 RISCVFeatures::validate(STI.getTargetTriple(), STI.getFeatureBits());
3839 }
3940 ~RISCVAsmBackend() override {}
4041
5353 def RV64 : HwMode<"+64bit">;
5454 def RV32 : HwMode<"-64bit">;
5555
56 def FeatureRV32E
57 : SubtargetFeature<"e", "IsRV32E", "true",
58 "Implements RV32E (provides 16 rather than 32 GPRs)">;
59 def IsRV32E : Predicate<"Subtarget->isRV32E()">,
60 AssemblerPredicate<"FeatureRV32E">;
61
5662 def FeatureRelax
5763 : SubtargetFeature<"relax", "EnableLinkerRelax", "true",
5864 "Enable Linker relaxation.">;
4141 RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
4242 const RISCVSubtarget &STI)
4343 : TargetLowering(TM), Subtarget(STI) {
44
45 if (Subtarget.isRV32E())
46 report_fatal_error("Codegen not yet implemented for RV32E");
4447
4548 RISCVABI::ABI ABI = Subtarget.getTargetABI();
4649 assert(ABI != RISCVABI::ABI_Unknown && "Improperly initialised target ABI");
3838 }
3939
4040 TargetABI = RISCVABI::computeTargetABI(TT, getFeatureBits(), ABIName);
41 RISCVFeatures::validate(TT, getFeatureBits());
4142 return *this;
4243 }
4344
3535 bool HasStdExtD = false;
3636 bool HasStdExtC = false;
3737 bool HasRV64 = false;
38 bool IsRV32E = false;
3839 bool EnableLinkerRelax = false;
3940 unsigned XLen = 32;
4041 MVT XLenVT = MVT::i32;
7980 bool hasStdExtD() const { return HasStdExtD; }
8081 bool hasStdExtC() const { return HasStdExtC; }
8182 bool is64Bit() const { return HasRV64; }
83 bool isRV32E() const { return IsRV32E; }
8284 bool enableLinkerRelax() const { return EnableLinkerRelax; }
8385 MVT getXLenVT() const { return XLenVT; }
8486 unsigned getXLen() const { return XLen; }
2121 .Case("lp64d", ABI_LP64D)
2222 .Default(ABI_Unknown);
2323
24 bool IsRV64 = TT.isArch64Bit();
25 bool IsRV32E = FeatureBits[RISCV::FeatureRV32E];
26
2427 if (!ABIName.empty() && TargetABI == ABI_Unknown) {
2528 errs()
2629 << "'" << ABIName
2730 << "' is not a recognized ABI for this target (ignoring target-abi)\n";
28 } else if (ABIName.startswith("ilp32") && TT.isArch64Bit()) {
31 } else if (ABIName.startswith("ilp32") && IsRV64) {
2932 errs() << "32-bit ABIs are not supported for 64-bit targets (ignoring "
3033 "target-abi)\n";
3134 TargetABI = ABI_Unknown;
32 } else if (ABIName.startswith("lp64") && !TT.isArch64Bit()) {
35 } else if (ABIName.startswith("lp64") && !IsRV64) {
3336 errs() << "64-bit ABIs are not supported for 32-bit targets (ignoring "
3437 "target-abi)\n";
3538 TargetABI = ABI_Unknown;
4346 "doesn't support the D instruction set extension (ignoring "
4447 "target-abi)\n";
4548 TargetABI = ABI_Unknown;
49 } else if (IsRV32E && TargetABI != ABI_ILP32E && TargetABI != ABI_Unknown) {
50 errs()
51 << "Only the ilp32e ABI is supported for RV32E (ignoring target-abi)\n";
52 TargetABI = ABI_Unknown;
4653 }
4754
48 // For now, default to the ilp32/lp64 if no explicit ABI is given or an
49 // invalid/unrecognised string is given. In the future, it might be worth
50 // changing this to default to ilp32f/lp64f and ilp32d/lp64d when hardware
51 // support for floating point is present.
52 if (TargetABI == ABI_Unknown) {
53 TargetABI = TT.isArch64Bit() ? ABI_LP64 : ABI_ILP32;
54 }
55 if (TargetABI != ABI_Unknown)
56 return TargetABI;
5557
56 return TargetABI;
58 // For now, default to the ilp32/ilp32e/lp64 ABI if no explicit ABI is given
59 // or an invalid/unrecognised string is given. In the future, it might be
60 // worth changing this to default to ilp32f/lp64f and ilp32d/lp64d when
61 // hardware support for floating point is present.
62 if (IsRV32E)
63 return ABI_ILP32E;
64 if (IsRV64)
65 return ABI_LP64;
66 return ABI_ILP32;
5767 }
5868 } // namespace RISCVABI
69
70 namespace RISCVFeatures {
71
72 void validate(const Triple &TT, const FeatureBitset &FeatureBits) {
73 if (TT.isArch64Bit() && FeatureBits[RISCV::FeatureRV32E])
74 report_fatal_error("RV32E can't be enabled for an RV64 target");
75 }
76
77 } // namespace RISCVFeatures
78
5979 } // namespace llvm
171171
172172 } // namespace RISCVABI
173173
174 namespace RISCVFeatures {
175
176 // Validates if the given combination of features are valid for the target
177 // triple. Exits with report_fatal_error if not.
178 void validate(const Triple &TT, const FeatureBitset &FeatureBits);
179
180 } // namespace RISCVFeatures
181
174182 } // namespace llvm
175183
176184 #endif
0 ; RUN: not llc -mtriple=riscv64 -mattr=+e < %s 2>&1 \
1 ; RUN: | FileCheck -check-prefix=RV64E %s
2
3 ; RV64E: LLVM ERROR: RV32E can't be enabled for an RV64 target
0 ; RUN: not llc -mtriple=riscv32 -mattr=+e < %s 2>&1 | FileCheck %s
1
2 ; CHECK: LLVM ERROR: Codegen not yet implemented for RV32E
3
4 define void @nothing() nounwind {
5 ret void
6 }
11 # RUN: llvm-mc -triple=riscv64 -filetype=obj < %s | llvm-readobj -file-headers - | FileCheck -check-prefixes=CHECK-RVI %s
22 # RUN: llvm-mc -triple=riscv32 -mattr=+c -filetype=obj < %s | llvm-readobj -file-headers - | FileCheck -check-prefixes=CHECK-RVIC %s
33 # RUN: llvm-mc -triple=riscv64 -mattr=+c -filetype=obj < %s | llvm-readobj -file-headers - | FileCheck -check-prefixes=CHECK-RVIC %s
4 # RUN: llvm-mc -triple=riscv32 -mattr=+e -filetype=obj < %s \
5 # RUN: | llvm-readobj -file-headers - \
6 # RUN: | FileCheck -check-prefix=CHECK-RVE %s
47
58 # CHECK-RVI: Flags [ (0x0)
69 # CHECK-RVI-NEXT: ]
912 # CHECK-RVIC-NEXT: EF_RISCV_RVC (0x1)
1013 # CHECK-RVIC-NEXT: ]
1114
15 # CHECK-RVE: Flags [ (0x8)
16 # CHECK-RVE-NEXT: EF_RISCV_RVE (0x8)
17 # CHECK-RVE-NEXT: ]
18
1219 nop
0 # RUN: not llvm-mc -triple riscv64 -mattr=+e < %s 2>&1 \
1 # RUN: | FileCheck %s -check-prefix=RV64E
2
3 # RV64E: LLVM ERROR: RV32E can't be enabled for an RV64 target
0 # RUN: not llvm-mc -triple riscv32 -mattr=+e < %s 2>&1 | FileCheck %s
1 # RUN: llvm-mc -filetype=obj -triple=riscv32 < %s \
2 # RUN: | llvm-objdump -mattr=+e -riscv-no-aliases -d -r - \
3 # RUN: | FileCheck -check-prefix=CHECK-DIS %s
4
5 # Perform a simple sanity check that registers x16-x31 (and the equivalent
6 # ABI names) are rejected for RV32E, when both assembling and disassembling.
7
8
9 # CHECK-DIS: 37 18 00 00
10 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
11 lui x16, 1
12 # CHECK-DIS: b7 28 00 00
13 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
14 lui x17, 2
15 # CHECK-DIS: 37 39 00 00
16 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
17 lui x18, 3
18 # CHECK-DIS: b7 49 00 00
19 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
20 lui x19, 4
21 # CHECK-DIS: 37 5a 00 00
22 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
23 lui x20, 5
24 # CHECK-DIS: b7 6a 00 00
25 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
26 lui x21, 6
27 # CHECK-DIS: 37 7b 00 00
28 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
29 lui x22, 7
30 # CHECK-DIS: b7 8b 00 00
31 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
32 lui x23, 8
33 # CHECK-DIS: 37 9c 00 00
34 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
35 lui x24, 9
36 # CHECK-DIS: b7 ac 00 00
37 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
38 lui x25, 10
39 # CHECK-DIS: 37 bd 00 00
40 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
41 lui x26, 11
42 # CHECK-DIS: b7 cd 00 00
43 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
44 lui x27, 12
45 # CHECK-DIS: 37 de 00 00
46 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
47 lui x28, 13
48 # CHECK-DIS: b7 ee 00 00
49 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
50 lui x29, 14
51 # CHECK-DIS: 37 ff 00 00
52 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
53 lui x30, 15
54 # CHECK-DIS: b7 0f 01 00
55 # CHECK: :[[@LINE+1]]:5: error: invalid operand for instruction
56 lui x31, 16
57
58 # CHECK-DIS: 17 18 01 00
59 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
60 auipc a6, 17
61 # CHECK-DIS: 97 28 01 00
62 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
63 auipc a7, 18
64 # CHECK-DIS: 17 39 01 00
65 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
66 auipc s2, 19
67 # CHECK-DIS: 97 49 01 00
68 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
69 auipc s3, 20
70 # CHECK-DIS: 17 5a 01 00
71 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
72 auipc s4, 21
73 # CHECK-DIS: 97 6a 01 00
74 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
75 auipc s5, 22
76 # CHECK-DIS: 17 7b 01 00
77 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
78 auipc s6, 23
79 # CHECK-DIS: 97 8b 01 00
80 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
81 auipc s7, 24
82 # CHECK-DIS: 17 9c 01 00
83 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
84 auipc s8, 25
85 # CHECK-DIS: 97 ac 01 00
86 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
87 auipc s9, 26
88 # CHECK-DIS: 17 bd 01 00
89 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
90 auipc s10, 27
91 # CHECK-DIS: 97 cd 01 00
92 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
93 auipc s11, 28
94 # CHECK-DIS: 17 de 01 00
95 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
96 auipc t3, 29
97 # CHECK-DIS: 97 ee 01 00
98 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
99 auipc t4, 30
100 # CHECK-DIS: 17 ff 01 00
101 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
102 auipc t5, 31
103 # CHECK-DIS: 97 0f 02 00
104 # CHECK: :[[@LINE+1]]:7: error: invalid operand for instruction
105 auipc t6, 32
0 # RUN: llvm-mc %s -triple=riscv32 -riscv-no-aliases -mattr=+e -show-encoding \
1 # RUN: | FileCheck -check-prefix=CHECK-ASM-AND-OBJ %s
2 # RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+e < %s \
3 # RUN: | llvm-objdump -riscv-no-aliases -d -r - \
4 # RUN: | FileCheck -check-prefix=CHECK-ASM-AND-OBJ %s
5
6 # This file provides a basic sanity check for RV32E, checking that the expected
7 # set of registers and instructions are accepted.
8
9 # CHECK-ASM-AND-OBJ: lui zero, 1
10 lui x0, 1
11 # CHECK-ASM-AND-OBJ: auipc ra, 2
12 auipc x1, 2
13
14 # CHECK-ASM-AND-OBJ: jal sp, 4
15 jal x2, 4
16 # CHECK-ASM-AND-OBJ: jalr gp, gp, 4
17 jalr x3, x3, 4
18
19 # CHECK-ASM-AND-OBJ: beq tp, t0, 8
20 beq x4, x5, 8
21 # CHECK-ASM-AND-OBJ: bne t1, t2, 12
22 bne x6, x7, 12
23 # CHECK-ASM-AND-OBJ: blt s0, s1, 16
24 blt x8, x9, 16
25 # CHECK-ASM-AND-OBJ: bge a0, a1, 20
26 bge x10, x11, 20
27 # CHECK-ASM-AND-OBJ: bgeu a2, a3, 24
28 bgeu x12, x13, 24
29
30 # CHECK-ASM-AND-OBJ: lb a4, 25(a5)
31 lb x14, 25(x15)
32 # CHECK-ASM-AND-OBJ: lh zero, 26(ra)
33 lh zero, 26(ra)
34 # CHECK-ASM-AND-OBJ: lw sp, 28(gp)
35 lw sp, 28(gp)
36 # CHECK-ASM-AND-OBJ: lbu tp, 29(t0)
37 lbu tp, 29(t0)
38 # CHECK-ASM-AND-OBJ: lhu t1, 30(t2)
39 lhu t1, 30(t2)
40 # CHECK-ASM-AND-OBJ: sb s0, 31(s1)
41 sb s0, 31(s1)
42 # CHECK-ASM-AND-OBJ: sh a0, 32(a1)
43 sh a0, 32(a1)
44 # CHECK-ASM-AND-OBJ: sw a2, 36(a3)
45 sw a2, 36(a3)
46
47 # CHECK-ASM-AND-OBJ: addi a4, a5, 37
48 addi a4, a5, 37
49 # CHECK-ASM-AND-OBJ: slti a0, a2, -20
50 slti a0, a2, -20
51 # CHECK-ASM-AND-OBJ: xori tp, t1, -99
52 xori tp, t1, -99
53 # CHECK-ASM-AND-OBJ: ori a0, a1, -2048
54 ori a0, a1, -2048
55 # CHECK-ASM-AND-OBJ: andi ra, sp, 2047
56 andi ra, sp, 2047
57 # CHECK-ASM-AND-OBJ: slli t1, t1, 31
58 slli t1, t1, 31
59 # CHECK-ASM-AND-OBJ: srli a0, a4, 0
60 srli a0, a4, 0
61 # CHECK-ASM-AND-OBJ: srai a1, sp, 15
62 srai a1, sp, 15
63 # CHECK-ASM-AND-OBJ: slli t0, t1, 13
64 slli t0, t1, 13
65
66 # CHECK-ASM-AND-OBJ: add ra, zero, zero
67 add ra, zero, zero
68 # CHECK-ASM-AND-OBJ: sub t0, t2, t1
69 sub t0, t2, t1
70 # CHECK-ASM-AND-OBJ: sll a5, a4, a3
71 sll a5, a4, a3
72 # CHECK-ASM-AND-OBJ: slt s0, s0, s0
73 slt s0, s0, s0
74 # CHECK-ASM-AND-OBJ: sltu gp, a0, a1
75 sltu gp, a0, a1
76 # CHECK-ASM-AND-OBJ: xor s1, s0, s1
77 xor s1, s0, s1
78 # CHECK-ASM-AND-OBJ: srl a0, s0, t0
79 srl a0, s0, t0
80 # CHECK-ASM-AND-OBJ: sra t0, a3, zero
81 sra t0, a3, zero
82 # CHECK-ASM-AND-OBJ: or a5, t1, ra
83 or a5, t1, ra
84 # CHECK-ASM-AND-OBJ: and a0, s1, a3
85 and a0, s1, a3
86
87 # CHECK-ASM-AND-OBJ: fence iorw, iorw
88 fence iorw, iorw
89 # CHECK-ASM-AND-OBJ: fence.tso
90 fence.tso
91 # CHECK-ASM-AND-OBJ: fence.i
92 fence.i
93
94 # CHECK-ASM-AND-OBJ: ecall
95 ecall
96 # CHECK-ASM-AND-OBJ: ebreak
97 ebreak
98 # CHECK-ASM-AND-OBJ: unimp
99 unimp
100
101 # CHECK-ASM-AND-OBJ: csrrw t0, 4095, t1
102 csrrw t0, 0xfff, t1
103 # CHECK-ASM-AND-OBJ: csrrs s0, cycle, zero
104 csrrs s0, 0xc00, x0
105 # CHECK-ASM-AND-OBJ: csrrs s0, fflags, a5
106 csrrs s0, 0x001, a5
107 # CHECK-ASM-AND-OBJ: csrrc sp, ustatus, ra
108 csrrc sp, 0x000, ra
109 # CHECK-ASM-AND-OBJ: csrrwi a5, ustatus, 0
110 csrrwi a5, 0x000, 0
111 # CHECK-ASM-AND-OBJ: csrrsi t2, 4095, 31
112 csrrsi t2, 0xfff, 31
113 # CHECK-ASM-AND-OBJ: csrrci t1, sscratch, 5
114 csrrci t1, 0x140, 5
2525 # RUN: | FileCheck -check-prefix=RV32IF-LP64F %s
2626 # RUN: llvm-mc -triple=riscv32 -mattr=+d -target-abi lp64d < %s 2>&1 \
2727 # RUN: | FileCheck -check-prefix=RV32IFD-LP64D %s
28 # RUN: llvm-mc -triple=riscv32 -mattr=+e -target-abi lp64 < %s 2>&1 \
29 # RUN: | FileCheck -check-prefix=RV32E-LP64 %s
30 # RUN: llvm-mc -triple=riscv32 -mattr=+e,+f -target-abi lp64f < %s 2>&1 \
31 # RUN: | FileCheck -check-prefix=RV32EF-LP64F %s
32 # RUN: llvm-mc -triple=riscv32 -mattr=+e,+d -target-abi lp64f < %s 2>&1 \
33 # RUN: | FileCheck -check-prefix=RV32EFD-LP64D %s
2834
2935 # RV32I-LP64: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi)
3036 # RV32IF-LP64F: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi)
3137 # RV32IFD-LP64D: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi)
38 # RV32E-LP64: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi)
39 # RV32EF-LP64F: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi)
40 # RV32EFD-LP64D: 64-bit ABIs are not supported for 32-bit targets (ignoring target-abi)
3241
3342 # RUN: llvm-mc -triple=riscv32 -target-abi ilp32f < %s 2>&1 \
3443 # RUN: | FileCheck -check-prefix=RV32I-ILP32F %s
5261 # RV64I-LP64D: Hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension (ignoring target-abi)
5362 # RV64IF-LP64D: Hard-float 'd' ABI can't be used for a target that doesn't support the D instruction set extension (ignoring target-abi)
5463
64 # RUN: llvm-mc -triple=riscv32 -mattr=+e -target-abi ilp32 < %s 2>&1 \
65 # RUN: | FileCheck -check-prefix=RV32EF-ILP32F %s
66 # RUN: llvm-mc -triple=riscv32 -mattr=+e,+f -target-abi ilp32f < %s 2>&1 \
67 # RUN: | FileCheck -check-prefix=RV32EF-ILP32F %s
68 # RUN: llvm-mc -triple=riscv32 -mattr=+e,+d -target-abi ilp32f < %s 2>&1 \
69 # RUN: | FileCheck -check-prefix=RV32EFD-ILP32F %s
70 # RUN: llvm-mc -triple=riscv32 -mattr=+e,+d -target-abi ilp32d < %s 2>&1 \
71 # RUN: | FileCheck -check-prefix=RV32EFD-ILP32D %s
72
73 # RV32E-ILP32: Only the ilp32e ABI is supported for RV32E (ignoring target-abi)
74 # RV32EF-ILP32F: Only the ilp32e ABI is supported for RV32E (ignoring target-abi)
75 # RV32EFD-ILP32F: Only the ilp32e ABI is supported for RV32E (ignoring target-abi)
76 # RV32EFD-ILP32D: Only the ilp32e ABI is supported for RV32E (ignoring target-abi)
77
5578 nop