Skip to content

Commit a31365f

Browse files
zRedShiftgerekon
authored andcommitted
[Xtensa] Implement CTLZ/CTTZ with NSAU
Close espressif#77
1 parent aeabf29 commit a31365f

File tree

5 files changed

+104
-5
lines changed

5 files changed

+104
-5
lines changed

llvm/lib/Target/Xtensa/XtensaISelLowering.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,12 @@ XtensaTargetLowering::XtensaTargetLowering(const TargetMachine &tm,
201201
setOperationAction(ISD::ROTL, MVT::i32, Expand);
202202
setOperationAction(ISD::ROTR, MVT::i32, Expand);
203203
setOperationAction(ISD::CTPOP, MVT::i32, Expand);
204-
setOperationAction(ISD::CTTZ, MVT::i32, Expand);
205-
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
206-
setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);
207-
setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);
204+
setOperationAction({ISD::CTTZ, ISD::CTTZ_ZERO_UNDEF}, MVT::i32, Expand);
205+
if (Subtarget.hasNSA())
206+
setOperationAction(ISD::CTLZ, MVT::i32, Legal);
207+
else
208+
setOperationAction({ISD::CTLZ, ISD::CTLZ_ZERO_UNDEF}, MVT::i32, Expand);
209+
208210

209211
setOperationAction({ISD::SMIN, ISD::SMAX, ISD::UMIN, ISD::UMAX},
210212
MVT::i32, Subtarget.hasMINMAX() ? Legal : Expand);
@@ -409,6 +411,18 @@ bool XtensaTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
409411
return false;
410412
}
411413

414+
bool XtensaTargetLowering::isCheapToSpeculateCtlz(Type *) const {
415+
return Subtarget.hasNSA();
416+
}
417+
418+
bool XtensaTargetLowering::isCheapToSpeculateCttz(Type *) const {
419+
return Subtarget.hasNSA();
420+
}
421+
422+
bool XtensaTargetLowering::isCtlzFast() const {
423+
return Subtarget.hasNSA();
424+
}
425+
412426
/// If a physical register, this returns the register that receives the
413427
/// exception address on entry to an EH pad.
414428
Register XtensaTargetLowering::getExceptionPointerRegister(

llvm/lib/Target/Xtensa/XtensaISelLowering.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ class XtensaTargetLowering : public TargetLowering {
121121
EVT VT) const override;
122122

123123
bool isFNegFree(EVT VT) const override;
124+
bool isCheapToSpeculateCtlz(Type *Ty) const override;
125+
126+
bool isCheapToSpeculateCttz(Type *Ty) const override;
127+
128+
bool isCtlzFast() const override;
124129

125130
/// If a physical register, this returns the register that receives the
126131
/// exception address on entry to an EH pad.

llvm/lib/Target/Xtensa/XtensaInstrInfo.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1362,7 +1362,8 @@ def NSA : RRR_Inst<0x00, 0x00, 0x04, (outs AR:$t), (ins AR:$s),
13621362
}
13631363

13641364
def NSAU : RRR_Inst<0x00, 0x00, 0x04, (outs AR:$t), (ins AR:$s),
1365-
"nsau\t$t, $s", []>, Requires<[HasNSA]> {
1365+
"nsau\t$t, $s",
1366+
[(set AR:$t, (ctlz AR:$s))]>, Requires<[HasNSA]> {
13661367
let r = 0xF;
13671368
}
13681369

llvm/test/CodeGen/Xtensa/ctlz-cttz.ll

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=xtensa -mcpu=esp32 -verify-machineinstrs < %s \
3+
; RUN: | FileCheck -check-prefix=XTENSA %s
4+
5+
declare i32 @llvm.ctlz.i32(i32, i1)
6+
7+
define i32 @test1_ctlz(i32 %v) {
8+
; XTENSA-LABEL: test1_ctlz:
9+
; XTENSA: # %bb.0:
10+
; XTENSA-NEXT: entry a1, 32
11+
; XTENSA-NEXT: .cfi_def_cfa_offset 32
12+
; XTENSA-NEXT: nsau a2, a2
13+
; XTENSA-NEXT: retw.n
14+
%1 = tail call i32 @llvm.ctlz.i32(i32 %v, i1 false)
15+
ret i32 %1
16+
}
17+
18+
define i32 @test2_ctlz(i32 %v) {
19+
; XTENSA-LABEL: test2_ctlz:
20+
; XTENSA: # %bb.0:
21+
; XTENSA-NEXT: entry a1, 32
22+
; XTENSA-NEXT: .cfi_def_cfa_offset 32
23+
; XTENSA-NEXT: nsau a2, a2
24+
; XTENSA-NEXT: retw.n
25+
%cnt = tail call i32 @llvm.ctlz.i32(i32 %v, i1 true)
26+
%tobool = icmp eq i32 %v, 0
27+
%cond = select i1 %tobool, i32 32, i32 %cnt
28+
ret i32 %cond
29+
}
30+
31+
declare i32 @llvm.cttz.i32(i32, i1)
32+
33+
define i32 @test1_cttz(i32 %v) {
34+
; XTENSA-LABEL: test1_cttz:
35+
; XTENSA: # %bb.0:
36+
; XTENSA-NEXT: entry a1, 32
37+
; XTENSA-NEXT: .cfi_def_cfa_offset 32
38+
; XTENSA-NEXT: movi.n a8, -1
39+
; XTENSA-NEXT: xor a8, a2, a8
40+
; XTENSA-NEXT: addi.n a9, a2, -1
41+
; XTENSA-NEXT: and a8, a8, a9
42+
; XTENSA-NEXT: nsau a8, a8
43+
; XTENSA-NEXT: movi.n a9, 32
44+
; XTENSA-NEXT: sub a2, a9, a8
45+
; XTENSA-NEXT: retw.n
46+
%1 = tail call i32 @llvm.cttz.i32(i32 %v, i1 false)
47+
ret i32 %1
48+
}
49+
50+
define i32 @test2_cttz(i32 %v) {
51+
; XTENSA-LABEL: test2_cttz:
52+
; XTENSA: # %bb.0:
53+
; XTENSA-NEXT: entry a1, 32
54+
; XTENSA-NEXT: .cfi_def_cfa_offset 32
55+
; XTENSA-NEXT: movi.n a8, -1
56+
; XTENSA-NEXT: xor a8, a2, a8
57+
; XTENSA-NEXT: addi.n a9, a2, -1
58+
; XTENSA-NEXT: and a8, a8, a9
59+
; XTENSA-NEXT: nsau a8, a8
60+
; XTENSA-NEXT: movi.n a9, 32
61+
; XTENSA-NEXT: sub a2, a9, a8
62+
; XTENSA-NEXT: retw.n
63+
%cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true)
64+
%tobool = icmp eq i32 %v, 0
65+
%cond = select i1 %tobool, i32 32, i32 %cnt
66+
ret i32 %cond
67+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# RUN: llvm-mc %s -triple=xtensa -mattr=+nsa -show-encoding \
2+
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
3+
4+
# Instruction format RRR
5+
# CHECK-INST: nsa a3, a2
6+
# CHECK: encoding: [0x30,0xe2,0x40]
7+
nsa a3, a2
8+
9+
# Instruction format RRR
10+
# CHECK-INST: nsau a3, a2
11+
# CHECK: encoding: [0x30,0xf2,0x40]
12+
nsau a3, a2

0 commit comments

Comments
 (0)