[llvm] [Xtensa] Fix S32C1I instruction encoding and copyPhysReg. (PR #165174)
Andrei Safronov via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 2 17:57:21 PST 2025
https://github.com/andreisfr updated https://github.com/llvm/llvm-project/pull/165174
>From 373d80fb8fffea26eedb68ec945a99d7ca306895 Mon Sep 17 00:00:00 2001
From: Andrei Safronov <safronov at espressif.com>
Date: Mon, 27 Oct 2025 00:11:19 +0300
Subject: [PATCH 1/3] [Xtensa] Fix S32C1I instruction encoding and copyPhysReg.
Fix S21C1I instruction encoding.Fix special registers parsing for S32C1I
feature. Fix copyPhysReg function for f32 registers copy.
---
.../MCTargetDesc/XtensaMCCodeEmitter.cpp | 2 +-
.../MCTargetDesc/XtensaMCTargetDesc.cpp | 2 +-
llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp | 20 ++++++++++++++++---
3 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
index bd4d4ebd2a729..5977a276b1236 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCCodeEmitter.cpp
@@ -320,7 +320,7 @@ XtensaMCCodeEmitter::getMemRegEncoding(const MCInst &MI, unsigned OpNo,
case Xtensa::SSIP:
case Xtensa::LSI:
case Xtensa::LSIP:
-
+ case Xtensa::S32C1I:
if (Res & 0x3) {
report_fatal_error("Unexpected operand value!");
}
diff --git a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
index 080a9c0bdd9e0..5feb0838da9e4 100644
--- a/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
+++ b/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaMCTargetDesc.cpp
@@ -202,7 +202,7 @@ bool Xtensa::checkRegister(MCRegister RegNo, const FeatureBitset &FeatureBits,
return FeatureBits[Xtensa::FeatureWindowed];
case Xtensa::ATOMCTL:
case Xtensa::SCOMPARE1:
- return FeatureBits[Xtensa::FeatureWindowed];
+ return FeatureBits[Xtensa::FeatureS32C1I];
case Xtensa::NoRegister:
return false;
}
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp b/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
index b0f924f2cd58e..30976be3f33c9 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
@@ -114,14 +114,28 @@ void XtensaInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
const DebugLoc &DL, Register DestReg,
Register SrcReg, bool KillSrc,
bool RenamableDest, bool RenamableSrc) const {
- // The MOV instruction is not present in core ISA,
- // so use OR instruction.
- if (Xtensa::ARRegClass.contains(DestReg, SrcReg))
+ unsigned Opcode;
+
+ // when we are copying a phys reg we want the bits for fp
+ if (Xtensa::ARRegClass.contains(DestReg, SrcReg)) {
BuildMI(MBB, MBBI, DL, get(Xtensa::OR), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc))
.addReg(SrcReg, getKillRegState(KillSrc));
+ return;
+ } else if (STI.hasSingleFloat() && Xtensa::FPRRegClass.contains(SrcReg) &&
+ Xtensa::FPRRegClass.contains(DestReg))
+ Opcode = Xtensa::MOV_S;
+ else if (STI.hasSingleFloat() && Xtensa::FPRRegClass.contains(SrcReg) &&
+ Xtensa::ARRegClass.contains(DestReg))
+ Opcode = Xtensa::RFR;
+ else if (STI.hasSingleFloat() && Xtensa::ARRegClass.contains(SrcReg) &&
+ Xtensa::FPRRegClass.contains(DestReg))
+ Opcode = Xtensa::WFR;
else
report_fatal_error("Impossible reg-to-reg copy");
+
+ BuildMI(MBB, MBBI, DL, get(Opcode), DestReg)
+ .addReg(SrcReg, getKillRegState(KillSrc));
}
void XtensaInstrInfo::storeRegToStackSlot(
>From cf86faa46043537966e592635e3f58ec8486f69b Mon Sep 17 00:00:00 2001
From: Andrei Safronov <safronov at espressif.com>
Date: Thu, 30 Oct 2025 20:22:00 +0300
Subject: [PATCH 2/3] [Xtensa] Minor fix and added tests.
---
llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp | 6 ++++--
llvm/test/CodeGen/Xtensa/s32c1i.ll | 7 +++++++
llvm/test/MC/Xtensa/s32c1i.s | 13 +++++++++++++
3 files changed, 24 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/CodeGen/Xtensa/s32c1i.ll
create mode 100644 llvm/test/MC/Xtensa/s32c1i.s
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp b/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
index 30976be3f33c9..21da759528532 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
@@ -122,8 +122,10 @@ void XtensaInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
.addReg(SrcReg, getKillRegState(KillSrc))
.addReg(SrcReg, getKillRegState(KillSrc));
return;
- } else if (STI.hasSingleFloat() && Xtensa::FPRRegClass.contains(SrcReg) &&
- Xtensa::FPRRegClass.contains(DestReg))
+ }
+
+ if (STI.hasSingleFloat() && Xtensa::FPRRegClass.contains(SrcReg) &&
+ Xtensa::FPRRegClass.contains(DestReg))
Opcode = Xtensa::MOV_S;
else if (STI.hasSingleFloat() && Xtensa::FPRRegClass.contains(SrcReg) &&
Xtensa::ARRegClass.contains(DestReg))
diff --git a/llvm/test/CodeGen/Xtensa/s32c1i.ll b/llvm/test/CodeGen/Xtensa/s32c1i.ll
new file mode 100644
index 0000000000000..aad738abe6a4c
--- /dev/null
+++ b/llvm/test/CodeGen/Xtensa/s32c1i.ll
@@ -0,0 +1,7 @@
+; RUN: llc -mtriple=xtensa -mattr=+s32c1i -filetype=obj %s -o - | llvm-objdump --arch=xtensa --mattr=s32c1i -d - | FileCheck %s -check-prefix=XTENSA
+
+define i32 @constraint_i(i32 %a) {
+; XTENSA: 0: 22 e2 01 s32c1i a2, a2, 4
+ %res = tail call i32 asm "s32c1i $0, $1, $2", "=r,r,i"(i32 %a, i32 4)
+ ret i32 %res
+}
diff --git a/llvm/test/MC/Xtensa/s32c1i.s b/llvm/test/MC/Xtensa/s32c1i.s
new file mode 100644
index 0000000000000..218a86dd56752
--- /dev/null
+++ b/llvm/test/MC/Xtensa/s32c1i.s
@@ -0,0 +1,13 @@
+# RUN: llvm-mc %s -triple=xtensa -show-encoding --mattr=+s32c1i \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+
+.align 4
+LBL0:
+
+# CHECK-INST: xsr a3, atomctl
+# CHECK: # encoding: [0x30,0x63,0x61]
+xsr a3, atomctl
+
+# CHECK-INST: xsr a3, scompare1
+# CHECK: # encoding: [0x30,0x0c,0x61]
+xsr a3, scompare1
>From 51e7b49ea8615cbb7488ecbaa69d7c9e1d157d16 Mon Sep 17 00:00:00 2001
From: Andrei Safronov <safronov at espressif.com>
Date: Mon, 3 Nov 2025 04:50:33 +0300
Subject: [PATCH 3/3] [PATCH] [Xtensa] Fix comment
---
llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp b/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
index 21da759528532..be69cefb5b78f 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp
@@ -116,7 +116,8 @@ void XtensaInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
bool RenamableDest, bool RenamableSrc) const {
unsigned Opcode;
- // when we are copying a phys reg we want the bits for fp
+ // The MOV instruction is not present in core ISA for AR registers,
+ // so use OR instruction.
if (Xtensa::ARRegClass.contains(DestReg, SrcReg)) {
BuildMI(MBB, MBBI, DL, get(Xtensa::OR), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc))
More information about the llvm-commits
mailing list