Skip to content

Commit 541a2f7

Browse files
committed
[Xtensa] Support 'f' Inline Assembly Constraint
This adds the 'f' inline assembly constraint, as supported by GCC. An 'f'-constrained operand is passed in a floating point register. This patch adds support in both the clang frontend, and LLVM itself.
1 parent 7569ae1 commit 541a2f7

File tree

5 files changed

+57
-1
lines changed

5 files changed

+57
-1
lines changed

clang/lib/Basic/Targets/Xtensa.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class LLVM_LIBRARY_VISIBILITY XtensaTargetInfo : public TargetInfo {
8282
default:
8383
return false;
8484
case 'a':
85+
case 'f':
8586
Info.setAllowsRegister();
8687
return true;
8788
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clang_cc1 -triple xtensa -O1 -emit-llvm %s -o - \
2+
// RUN: | FileCheck %s
3+
4+
// Test Xtensa specific inline assembly constraints.
5+
6+
float f;
7+
void test_f() {
8+
// CHECK-LABEL: define dso_local void @test_f() local_unnamed_addr #0 {
9+
// CHECK: [[FLT_ARG:%[a-zA-Z_0-9]+]] = load float, float* @f
10+
// CHECK: call void asm sideeffect "", "f"(float [[FLT_ARG]])
11+
asm volatile ("" :: "f"(f));
12+
}
13+

llvm/lib/Target/Xtensa/XtensaISelLowering.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ XtensaTargetLowering::getConstraintType(StringRef Constraint) const {
376376
switch (Constraint[0]) {
377377
case 'a':
378378
case 'd':
379+
case 'f':
379380
case 'r':
380381
return C_RegisterClass;
381382

@@ -396,6 +397,8 @@ XtensaTargetLowering::getSingleConstraintMatchWeight(
396397
if (CallOperandVal == NULL)
397398
return CW_Default;
398399

400+
Type *type = CallOperandVal->getType();
401+
399402
// Look at the constraint type.
400403
switch (*constraint) {
401404
default:
@@ -405,9 +408,14 @@ XtensaTargetLowering::getSingleConstraintMatchWeight(
405408
case 'a':
406409
case 'd':
407410
case 'r':
408-
if (CallOperandVal->getType()->isIntegerTy())
411+
if (type->isIntegerTy())
412+
weight = CW_Register;
413+
break;
414+
case 'f':
415+
if (type->isFloatingPointTy())
409416
weight = CW_Register;
410417
break;
418+
411419
}
412420
return weight;
413421
}
@@ -424,6 +432,9 @@ XtensaTargetLowering::getRegForInlineAsmConstraint(
424432
case 'd': // Data register (equivalent to 'r')
425433
case 'r': // General-purpose register
426434
return std::make_pair(0U, &Xtensa::ARRegClass);
435+
case 'f': // Floating-point register
436+
if (Subtarget.hasSingleFloat())
437+
return std::make_pair(0U, &Xtensa::FPRRegClass);
427438
}
428439
}
429440
return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
; RUN: llc -mtriple=xtensa -mcpu=esp32 -verify-machineinstrs < %s \
2+
; RUN: | FileCheck -check-prefix=Xtensa %s
3+
4+
5+
@gf = external global float
6+
7+
define float @constraint_f_float(float %a) nounwind {
8+
; Xtensa-LABEL: constraint_f_float:
9+
; Xtensa: # %bb.0:
10+
; Xtensa-NEXT: entry a1, 32
11+
; Xtensa-NEXT: wfr f8, a2
12+
; Xtensa-NEXT: l32r a8, .LCPI0_0
13+
; Xtensa-NEXT: lsi f9, a8, 0
14+
; Xtensa-NEXT: #APP
15+
; Xtensa-NEXT: add.s f8, f8, f9
16+
; Xtensa-NEXT: #NO_APP
17+
; Xtensa-NEXT: rfr a2, f8
18+
; Xtensa-NEXT: retw
19+
%1 = load float, float* @gf
20+
%2 = tail call float asm "add.s $0, $1, $2", "=f,f,f"(float %a, float %1)
21+
ret float %2
22+
}
23+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
; RUN: not llc -mtriple=xtensa -mcpu=generic < %s 2>&1 | FileCheck %s
2+
3+
define void @constraint_f() nounwind {
4+
; CHECK: error: couldn't allocate input reg for constraint 'f'
5+
tail call void asm "add.s f0, f1, $0", "f"(float 0.0)
6+
ret void
7+
}
8+

0 commit comments

Comments
 (0)