llvm.org GIT mirror llvm / 0febe88
Merging r367403: ------------------------------------------------------------------------ r367403 | lenary | 2019-07-31 11:45:55 +0200 (Wed, 31 Jul 2019) | 20 lines [RISCV] Support 'f' Inline Assembly Constraint Summary: This adds the 'f' inline assembly constraint, as supported by GCC. An 'f'-constrained operand is passed in a floating point register. Exactly which kind of floating-point register (32-bit or 64-bit) is decided based on the operand type and the available standard extensions (-f and -d, respectively). This patch adds support in both the clang frontend, and LLVM itself. Reviewers: asb, lewis-revill Reviewed By: asb Subscribers: hiraditya, rbar, johnrusso, simoncook, apazos, sabuasal, niosHD, kito-cheng, shiva0217, jrtc27, MaskRay, zzheng, edward-jones, rogfer01, MartinMosbeck, brucehoult, the_o, rkruppe, PkmX, jocewei, psnobl, benna, Jim, s.egerton, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D65500 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_90@368419 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 1 year, 3 months ago
5 changed file(s) with 104 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
23962396 return nullptr;
23972397 }
23982398
2399 /// getConstraintType - Given a constraint letter, return the type of
2400 /// constraint it is for this target.
2401 RISCVTargetLowering::ConstraintType
2402 RISCVTargetLowering::getConstraintType(StringRef Constraint) const {
2403 if (Constraint.size() == 1) {
2404 switch (Constraint[0]) {
2405 default:
2406 break;
2407 case 'f':
2408 return C_RegisterClass;
2409 }
2410 }
2411 return TargetLowering::getConstraintType(Constraint);
2412 }
2413
23992414 std::pair
24002415 RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
24012416 StringRef Constraint,
24062421 switch (Constraint[0]) {
24072422 case 'r':
24082423 return std::make_pair(0U, &RISCV::GPRRegClass);
2424 case 'f':
2425 if (Subtarget.hasStdExtF() && VT == MVT::f32)
2426 return std::make_pair(0U, &RISCV::FPR32RegClass);
2427 if (Subtarget.hasStdExtD() && VT == MVT::f64)
2428 return std::make_pair(0U, &RISCV::FPR64RegClass);
2429 break;
24092430 default:
24102431 break;
24112432 }
9191 // This method returns the name of a target specific DAG node.
9292 const char *getTargetNodeName(unsigned Opcode) const override;
9393
94 ConstraintType getConstraintType(StringRef Constraint) const override;
9495 std::pair
9596 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
9697 StringRef Constraint, MVT VT) const override;
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
2 ; RUN: | FileCheck -check-prefix=RV32F %s
3 ; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs < %s \
4 ; RUN: | FileCheck -check-prefix=RV64F %s
5
6 @gd = external global double
7
8 define double @constraint_f_double(double %a) nounwind {
9 ; RV32F-LABEL: constraint_f_double:
10 ; RV32F: # %bb.0:
11 ; RV32F-NEXT: addi sp, sp, -16
12 ; RV32F-NEXT: sw a0, 8(sp)
13 ; RV32F-NEXT: sw a1, 12(sp)
14 ; RV32F-NEXT: fld ft0, 8(sp)
15 ; RV32F-NEXT: lui a0, %hi(gd)
16 ; RV32F-NEXT: fld ft1, %lo(gd)(a0)
17 ; RV32F-NEXT: #APP
18 ; RV32F-NEXT: fadd.d ft0, ft0, ft1
19 ; RV32F-NEXT: #NO_APP
20 ; RV32F-NEXT: fsd ft0, 8(sp)
21 ; RV32F-NEXT: lw a0, 8(sp)
22 ; RV32F-NEXT: lw a1, 12(sp)
23 ; RV32F-NEXT: addi sp, sp, 16
24 ; RV32F-NEXT: ret
25 ;
26 ; RV64F-LABEL: constraint_f_double:
27 ; RV64F: # %bb.0:
28 ; RV64F-NEXT: fmv.d.x ft0, a0
29 ; RV64F-NEXT: lui a0, %hi(gd)
30 ; RV64F-NEXT: fld ft1, %lo(gd)(a0)
31 ; RV64F-NEXT: #APP
32 ; RV64F-NEXT: fadd.d ft0, ft0, ft1
33 ; RV64F-NEXT: #NO_APP
34 ; RV64F-NEXT: fmv.x.d a0, ft0
35 ; RV64F-NEXT: ret
36 %1 = load double, double* @gd
37 %2 = tail call double asm "fadd.d $0, $1, $2", "=f,f,f"(double %a, double %1)
38 ret double %2
39 }
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \
2 ; RUN: | FileCheck -check-prefix=RV32F %s
3 ; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs < %s \
4 ; RUN: | FileCheck -check-prefix=RV64F %s
5
6 @gf = external global float
7
8 define float @constraint_f_float(float %a) nounwind {
9 ; RV32F-LABEL: constraint_f_float:
10 ; RV32F: # %bb.0:
11 ; RV32F-NEXT: fmv.w.x ft0, a0
12 ; RV32F-NEXT: lui a0, %hi(gf)
13 ; RV32F-NEXT: flw ft1, %lo(gf)(a0)
14 ; RV32F-NEXT: #APP
15 ; RV32F-NEXT: fadd.s ft0, ft0, ft1
16 ; RV32F-NEXT: #NO_APP
17 ; RV32F-NEXT: fmv.x.w a0, ft0
18 ; RV32F-NEXT: ret
19 ;
20 ; RV64F-LABEL: constraint_f_float:
21 ; RV64F: # %bb.0:
22 ; RV64F-NEXT: fmv.w.x ft0, a0
23 ; RV64F-NEXT: lui a0, %hi(gf)
24 ; RV64F-NEXT: flw ft1, %lo(gf)(a0)
25 ; RV64F-NEXT: #APP
26 ; RV64F-NEXT: fadd.s ft0, ft0, ft1
27 ; RV64F-NEXT: #NO_APP
28 ; RV64F-NEXT: fmv.x.w a0, ft0
29 ; RV64F-NEXT: ret
30 %1 = load float, float* @gf
31 %2 = tail call float asm "fadd.s $0, $1, $2", "=f,f,f"(float %a, float %1)
32 ret float %2
33 }
2121 tail call void asm sideeffect "csrwi mstatus, $0", "K"(i32 -1)
2222 ret void
2323 }
24
25 define void @constraint_f() nounwind {
26 ; CHECK: error: couldn't allocate input reg for constraint 'f'
27 tail call void asm "fadd.s fa0, fa0, $0", "f"(float 0.0)
28 ; CHECK: error: couldn't allocate input reg for constraint 'f'
29 tail call void asm "fadd.d fa0, fa0, $0", "f"(double 0.0)
30 ret void
31 }