[llvm] [Xtensa] Implement Xtensa MAC16 Option. (PR #130004)
Andrei Safronov via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 6 15:04:23 PST 2025
https://github.com/andreisfr updated https://github.com/llvm/llvm-project/pull/130004
>From 298aeddf3a97c3357cadf523e4def702cf768c53 Mon Sep 17 00:00:00 2001
From: Andrei Safronov <safronov at espressif.com>
Date: Thu, 6 Mar 2025 10:56:44 +0300
Subject: [PATCH 1/2] [Xtensa] Implement Xtensa MAC16 Option.
---
.../Disassembler/XtensaDisassembler.cpp | 44 ++-
llvm/lib/Target/Xtensa/XtensaDSPInstrInfo.td | 353 ++++++++++++++++++
llvm/lib/Target/Xtensa/XtensaFeatures.td | 5 +
llvm/lib/Target/Xtensa/XtensaInstrInfo.td | 5 +
llvm/lib/Target/Xtensa/XtensaRegisterInfo.td | 14 +-
llvm/lib/Target/Xtensa/XtensaSubtarget.h | 2 +
llvm/test/MC/Xtensa/xtensa-mac16.s | 233 ++++++++++++
7 files changed, 654 insertions(+), 2 deletions(-)
create mode 100644 llvm/lib/Target/Xtensa/XtensaDSPInstrInfo.td
create mode 100644 llvm/test/MC/Xtensa/xtensa-mac16.s
diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
index b1027488904df..c1f6b39555223 100644
--- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
+++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
@@ -73,8 +73,50 @@ static DecodeStatus DecodeARRegisterClass(MCInst &Inst, uint64_t RegNo,
return MCDisassembler::Success;
}
+static const unsigned MRDecoderTable[] = {Xtensa::M0, Xtensa::M1, Xtensa::M2,
+ Xtensa::M3};
+
+static DecodeStatus DecodeMRRegisterClass(MCInst &Inst, uint64_t RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ if (RegNo >= std::size(MRDecoderTable))
+ return MCDisassembler::Fail;
+
+ unsigned Reg = MRDecoderTable[RegNo];
+ Inst.addOperand(MCOperand::createReg(Reg));
+ return MCDisassembler::Success;
+}
+
+static const unsigned MR01DecoderTable[] = {Xtensa::M0, Xtensa::M1};
+
+static DecodeStatus DecodeMR01RegisterClass(MCInst &Inst, uint64_t RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ if (RegNo > 2)
+ return MCDisassembler::Fail;
+
+ unsigned Reg = MR01DecoderTable[RegNo];
+ Inst.addOperand(MCOperand::createReg(Reg));
+ return MCDisassembler::Success;
+}
+
+static const unsigned MR23DecoderTable[] = {Xtensa::M2, Xtensa::M3};
+
+static DecodeStatus DecodeMR23RegisterClass(MCInst &Inst, uint64_t RegNo,
+ uint64_t Address,
+ const void *Decoder) {
+ if ((RegNo < 2) || (RegNo > 3))
+ return MCDisassembler::Fail;
+
+ unsigned Reg = MR23DecoderTable[RegNo - 2];
+ Inst.addOperand(MCOperand::createReg(Reg));
+ return MCDisassembler::Success;
+}
+
const MCPhysReg SRDecoderTable[] = {
- Xtensa::SAR, 3, Xtensa::WINDOWBASE, 72, Xtensa::WINDOWSTART, 73};
+ Xtensa::SAR, 3, Xtensa::ACCLO, 16, Xtensa::ACCHI, 17,
+ Xtensa::M0, 32, Xtensa::M1, 33, Xtensa::M2, 34,
+ Xtensa::M3, 35, Xtensa::WINDOWBASE, 72, Xtensa::WINDOWSTART, 73};
static DecodeStatus DecodeSRRegisterClass(MCInst &Inst, uint64_t RegNo,
uint64_t Address,
diff --git a/llvm/lib/Target/Xtensa/XtensaDSPInstrInfo.td b/llvm/lib/Target/Xtensa/XtensaDSPInstrInfo.td
new file mode 100644
index 0000000000000..d80df46320643
--- /dev/null
+++ b/llvm/lib/Target/Xtensa/XtensaDSPInstrInfo.td
@@ -0,0 +1,353 @@
+//===- XtensaDSPInstrInfo.td - Xtensa Target Description ---*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the Xtensa DSP instructions in TableGen format.
+//
+//===----------------------------------------------------------------------===//
+
+// Multiply
+class UMUL_AA<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x07, (outs), (ins AR:$s, AR:$t),
+ instrAsm#"\t$s, $t", []>, Requires<[HasMAC16]> {
+ let r = 0;
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def UMUL_AA_LL : UMUL_AA<0x00, "umul.aa.ll">;
+def UMUL_AA_HL : UMUL_AA<0x01, "umul.aa.hl">;
+def UMUL_AA_LH : UMUL_AA<0x02, "umul.aa.lh">;
+def UMUL_AA_HH : UMUL_AA<0x03, "umul.aa.hh">;
+
+class MUL_AA<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x07, (outs), (ins AR:$s, AR:$t),
+ instrAsm#"\t$s, $t", []>, Requires<[HasMAC16]> {
+ let r = 0;
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MUL_AA_LL : MUL_AA<0x04, "mul.aa.ll">;
+def MUL_AA_HL : MUL_AA<0x05, "mul.aa.hl">;
+def MUL_AA_LH : MUL_AA<0x06, "mul.aa.lh">;
+def MUL_AA_HH : MUL_AA<0x07, "mul.aa.hh">;
+
+class MUL_AD<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x03, (outs), (ins AR:$s, MR23:$y),
+ instrAsm#"\t$s, $y", []>, Requires<[HasMAC16]> {
+ bits<2> y;
+
+ let r = 0;
+ let t{3} = 0;
+ let t{2} = y{0};
+ let t{1-0} = 0;
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MUL_AD_LL : MUL_AD<0x04, "mul.ad.ll">;
+def MUL_AD_HL : MUL_AD<0x05, "mul.ad.hl">;
+def MUL_AD_LH : MUL_AD<0x06, "mul.ad.lh">;
+def MUL_AD_HH : MUL_AD<0x07, "mul.ad.hh">;
+
+class MUL_DA<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x06, (outs), (ins MR01:$x, AR:$t),
+ instrAsm#"\t$x, $t", []>, Requires<[HasMAC16]> {
+ bits<2> x;
+
+ let r{3} = 0;
+ let r{2} = x{0};
+ let r{1-0} = 0;
+ let s = 0;
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MUL_DA_LL : MUL_DA<0x04, "mul.da.ll">;
+def MUL_DA_HL : MUL_DA<0x05, "mul.da.hl">;
+def MUL_DA_LH : MUL_DA<0x06, "mul.da.lh">;
+def MUL_DA_HH : MUL_DA<0x07, "mul.da.hh">;
+
+class MUL_DD<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x02, (outs), (ins MR01:$x, MR23:$y),
+ instrAsm#"\t$x, $y", []>, Requires<[HasMAC16]> {
+ bits<2> x;
+ bits<2> y;
+
+ let r{3} = 0;
+ let r{2} = x{0};
+ let r{1-0} = 0;
+ let s = 0;
+ let t{3} = 0;
+ let t{2} = y{0};
+ let t{1-0} = 0;
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MUL_DD_LL : MUL_DD<0x04, "mul.dd.ll">;
+def MUL_DD_HL : MUL_DD<0x05, "mul.dd.hl">;
+def MUL_DD_LH : MUL_DD<0x06, "mul.dd.lh">;
+def MUL_DD_HH : MUL_DD<0x07, "mul.dd.hh">;
+
+class MULA_AA<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x07, (outs), (ins AR:$s, AR:$t),
+ instrAsm#"\t$s, $t", []>, Requires<[HasMAC16]> {
+ let r = 0;
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MULA_AA_LL : MULA_AA<0x08, "mula.aa.ll">;
+def MULA_AA_HL : MULA_AA<0x09, "mula.aa.hl">;
+def MULA_AA_LH : MULA_AA<0x0A, "mula.aa.lh">;
+def MULA_AA_HH : MULA_AA<0x0B, "mula.aa.hh">;
+
+class MULA_AD<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x03, (outs), (ins AR:$s, MR23:$y),
+ instrAsm#"\t$s, $y", []>, Requires<[HasMAC16]> {
+ bits<2> y;
+
+ let r = 0;
+ let t{3} = 0;
+ let t{2} = y{0};
+ let t{1-0} = 0;
+
+ let Uses = [ACCLO, ACCHI];
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MULA_AD_LL : MULA_AD<0x08, "mula.ad.ll">;
+def MULA_AD_HL : MULA_AD<0x09, "mula.ad.hl">;
+def MULA_AD_LH : MULA_AD<0x0A, "mula.ad.lh">;
+def MULA_AD_HH : MULA_AD<0x0B, "mula.ad.hh">;
+
+class MULA_DA<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x06, (outs), (ins MR01:$x, AR:$t),
+ instrAsm#"\t$x, $t", []>, Requires<[HasMAC16]> {
+ bits<2> x;
+
+ let r{3} = 0;
+ let r{2} = x{0};
+ let r{1-0} = 0;
+ let s = 0;
+
+ let Uses = [ACCLO, ACCHI];
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MULA_DA_LL : MULA_DA<0x08, "mula.da.ll">;
+def MULA_DA_HL : MULA_DA<0x09, "mula.da.hl">;
+def MULA_DA_LH : MULA_DA<0x0A, "mula.da.lh">;
+def MULA_DA_HH : MULA_DA<0x0B, "mula.da.hh">;
+
+class MULA_DD<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x02, (outs), (ins MR01:$x, MR23:$y),
+ instrAsm#"\t$x, $y", []>, Requires<[HasMAC16]> {
+ bits<2> x;
+ bits<2> y;
+
+ let r{3} = 0;
+ let r{2} = x{0};
+ let r{1-0} = 0;
+ let s = 0;
+ let t{3} = 0;
+ let t{2} = y{0};
+ let t{1-0} = 0;
+
+ let Uses = [ACCLO, ACCHI];
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MULA_DD_LL : MULA_DD<0x08, "mula.dd.ll">;
+def MULA_DD_HL : MULA_DD<0x09, "mula.dd.hl">;
+def MULA_DD_LH : MULA_DD<0x0A, "mula.dd.lh">;
+def MULA_DD_HH : MULA_DD<0x0B, "mula.dd.hh">;
+
+class MULS_AA<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x07, (outs), (ins AR:$s, AR:$t),
+ instrAsm#"\t$s, $t", []>, Requires<[HasMAC16]> {
+ let r = 0;
+ let Uses = [ACCLO, ACCHI];
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MULS_AA_LL : MULS_AA<0x0C, "muls.aa.ll">;
+def MULS_AA_HL : MULS_AA<0x0D, "muls.aa.hl">;
+def MULS_AA_LH : MULS_AA<0x0E, "muls.aa.lh">;
+def MULS_AA_HH : MULS_AA<0x0F, "muls.aa.hh">;
+
+class MULS_AD<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x03, (outs), (ins AR:$s, MR23:$y),
+ instrAsm#"\t$s, $y", []>, Requires<[HasMAC16]> {
+ bits<2> y;
+
+ let r = 0;
+ let t{3} = 0;
+ let t{2} = y{0};
+ let t{1-0} = 0;
+
+ let Uses = [ACCLO, ACCHI];
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MULS_AD_LL : MULS_AD<0x0C, "muls.ad.ll">;
+def MULS_AD_HL : MULS_AD<0x0D, "muls.ad.hl">;
+def MULS_AD_LH : MULS_AD<0x0E, "muls.ad.lh">;
+def MULS_AD_HH : MULS_AD<0x0F, "muls.ad.hh">;
+
+class MULS_DA<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x06, (outs), (ins MR01:$x, AR:$t),
+ instrAsm#"\t$x, $t", []>, Requires<[HasMAC16]> {
+ bits<2> x;
+
+ let r{3} = 0;
+ let r{2} = x{0};
+ let r{1-0} = 0;
+ let s = 0;
+
+ let Uses = [ACCLO, ACCHI];
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MULS_DA_LL : MULS_DA<0x0C, "muls.da.ll">;
+def MULS_DA_HL : MULS_DA<0x0D, "muls.da.hl">;
+def MULS_DA_LH : MULS_DA<0x0E, "muls.da.lh">;
+def MULS_DA_HH : MULS_DA<0x0F, "muls.da.hh">;
+
+class MULS_DD<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x02, (outs), (ins MR01:$x, MR23:$y),
+ instrAsm#"\t$x, $y", []>, Requires<[HasMAC16]> {
+ bits<2> x;
+ bits<2> y;
+
+ let r{3} = 0;
+ let r{2} = x{0};
+ let r{1-0} = 0;
+ let s = 0;
+ let t{3} = 0;
+ let t{2} = y{0};
+ let t{1-0} = 0;
+
+ let Uses = [ACCLO, ACCHI];
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MULS_DD_LL : MULS_DD<0x0C, "muls.dd.ll">;
+def MULS_DD_HL : MULS_DD<0x0D, "muls.dd.hl">;
+def MULS_DD_LH : MULS_DD<0x0E, "muls.dd.lh">;
+def MULS_DD_HH : MULS_DD<0x0F, "muls.dd.hh">;
+
+//===----------------------------------------------------------------------===//
+// Multiply-accumulate with load
+
+class MULA_DA_LDDEC<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x05, (outs MR:$w, AR:$d), (ins AR:$s, MR01:$x, AR:$t),
+ instrAsm#"\t $w, $s, $x, $t", []>, Requires<[HasMAC16]> {
+ bits<2> x;
+ bits<2> w;
+
+ let Constraints = "$s = $d";
+ let mayLoad = 1;
+ let r{3} = 0;
+ let r{2} = x{0};
+ let r{1-0} = w{1-0};
+ let Uses = [ACCLO, ACCHI];
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MULA_DA_LL_LDDEC : MULA_DA_LDDEC<0x08, "mula.da.ll.lddec">;
+def MULA_DA_HL_LDDEC : MULA_DA_LDDEC<0x09, "mula.da.hl.lddec">;
+def MULA_DA_LH_LDDEC : MULA_DA_LDDEC<0x0A, "mula.da.lh.lddec">;
+def MULA_DA_HH_LDDEC : MULA_DA_LDDEC<0x0B, "mula.da.hh.lddec">;
+
+class MULA_DA_LDINC<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x04, (outs MR:$w, AR:$d), (ins AR:$s, MR:$x, AR:$t),
+ instrAsm#"\t $w, $s, $x, $t", []>, Requires<[HasMAC16]> {
+ bits<1> x;
+ bits<2> w;
+
+ let Constraints = "$s = $d";
+ let mayLoad = 1;
+ let r{3} = 0;
+ let r{2} = x{0};
+ let r{1-0} = w{1-0};
+ let Uses = [ACCLO, ACCHI];
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MULA_DA_LL_LDINC: MULA_DA_LDINC<0x08, "mula.da.ll.ldinc">;
+def MULA_DA_HL_LDINC: MULA_DA_LDINC<0x09, "mula.da.hl.ldinc">;
+def MULA_DA_LH_LDINC: MULA_DA_LDINC<0x0A, "mula.da.lh.ldinc">;
+def MULA_DA_HH_LDINC: MULA_DA_LDINC<0x0B, "mula.da.hh.ldinc">;
+
+class MULA_DD_LDDEC<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x01, (outs MR:$w, AR:$d), (ins AR:$s, MR01:$x, MR23:$y),
+ instrAsm#"\t $w, $s, $x, $y", []>, Requires<[HasMAC16]> {
+ bits<2> x;
+ bits<2> y;
+ bits<2> w;
+
+ let Constraints = "$s = $d";
+ let mayLoad = 1;
+ let r{3} = 0;
+ let r{2} = x{0};
+ let r{1-0} = w{1-0};
+ let t{3} = 0;
+ let t{2} = y{0};
+ let t{1-0} = 0;
+ let Uses = [ACCLO, ACCHI];
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MULA_DD_LL_LDDEC : MULA_DD_LDDEC<0x08, "mula.dd.ll.lddec">;
+def MULA_DD_HL_LDDEC : MULA_DD_LDDEC<0x09, "mula.dd.hl.lddec">;
+def MULA_DD_LH_LDDEC : MULA_DD_LDDEC<0x0A, "mula.dd.lh.lddec">;
+def MULA_DD_HH_LDDEC : MULA_DD_LDDEC<0x0B, "mula.dd.hh.lddec">;
+
+class MULA_DD_LDINC<bits<4> oper1, string instrAsm>
+ : RRR_Inst<0x04, oper1, 0x00, (outs MR:$w, AR:$d), (ins AR:$s, MR01:$x, MR23:$y),
+ instrAsm#"\t $w, $s, $x, $y", []>, Requires<[HasMAC16]> {
+ bits<2> x;
+ bits<2> y;
+ bits<2> w;
+
+ let Constraints = "$s = $d";
+ let mayLoad = 1;
+ let r{3} = 0;
+ let r{2} = x{0};
+ let r{1-0} = w{1-0};
+ let t{3} = 0;
+ let t{2} = y{0};
+ let t{1-0} = 0;
+ let Uses = [ACCLO, ACCHI];
+ let Defs = [M1, M2, ACCLO, ACCHI];
+}
+
+def MULA_DD_LL_LDINC : MULA_DD_LDINC<0x08, "mula.dd.ll.ldinc">;
+def MULA_DD_HL_LDINC : MULA_DD_LDINC<0x09, "mula.dd.hl.ldinc">;
+def MULA_DD_LH_LDINC : MULA_DD_LDINC<0x0A, "mula.dd.lh.ldinc">;
+def MULA_DD_HH_LDINC : MULA_DD_LDINC<0x0B, "mula.dd.hh.ldinc">;
+
+def LDDEC : RRR_Inst<0x04, 0x00, 0x09, (outs MR:$w, AR:$d), (ins AR:$s),
+ "lddec\t $w, $s", []>, Requires<[HasMAC16]> {
+ bits<2> w;
+
+ let Constraints = "$s = $d";
+ let mayLoad = 1;
+ let r{3-2} = 0;
+ let r{1-0} = w{1-0};
+ let t = 0x00;
+}
+
+def LDINC : RRR_Inst<0x04, 0x00, 0x08, (outs MR:$w, AR:$d), (ins AR:$s),
+ "ldinc\t $w, $s", []>, Requires<[HasMAC16]> {
+ bits<2> w;
+
+ let Constraints = "$s = $d";
+ let mayLoad = 1;
+ let r{3-2} = 0;
+ let r{1-0} = w{1-0};
+ let t = 0;
+}
diff --git a/llvm/lib/Target/Xtensa/XtensaFeatures.td b/llvm/lib/Target/Xtensa/XtensaFeatures.td
index b0cbeb9456796..184828cd253f3 100644
--- a/llvm/lib/Target/Xtensa/XtensaFeatures.td
+++ b/llvm/lib/Target/Xtensa/XtensaFeatures.td
@@ -13,6 +13,11 @@ def FeatureWindowed : SubtargetFeature<"windowed", "HasWindowed", "true",
def HasWindowed : Predicate<"Subtarget->hasWindowed()">,
AssemblerPredicate<(all_of FeatureWindowed)>;
+def FeatureMAC16 : SubtargetFeature<"mac16", "HasMAC16", "true",
+ "Enable Xtensa MAC16 instructions">;
+def HasMAC16 : Predicate<"Subtarget->hasMAC16()">,
+ AssemblerPredicate<(all_of FeatureMAC16)>;
+
def FeatureBoolean : SubtargetFeature<"bool", "HasBoolean", "true",
"Enable Xtensa Boolean extension">;
def HasBoolean : Predicate<"Subtarget->hasBoolean()">,
diff --git a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
index e52dcbf1377c5..1f397e3ecac35 100644
--- a/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
+++ b/llvm/lib/Target/Xtensa/XtensaInstrInfo.td
@@ -849,3 +849,8 @@ let Constraints = "$dr = $r, at earlyclobber $dr" in {
def MOVT : RRR_Inst<0x00, 0x03, 0x0D, (outs AR:$dr), (ins AR:$r, AR:$s, BR:$t),
"movt\t$r, $s, $t", []>, Requires<[HasBoolean]>;
}
+
+//===----------------------------------------------------------------------===//
+// DSP Instructions
+//===----------------------------------------------------------------------===//
+include "XtensaDSPInstrInfo.td"
diff --git a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
index 920354ff41ba5..2934018318406 100644
--- a/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
+++ b/llvm/lib/Target/Xtensa/XtensaRegisterInfo.td
@@ -83,7 +83,19 @@ def BREG : SRReg<4, "br", ["BR","4"]>;
def WINDOWBASE : SRReg<72, "windowbase", ["WINDOWBASE", "72"]>;
def WINDOWSTART : SRReg<73, "windowstart", ["WINDOWSTART", "73"]>;
-def SR : RegisterClass<"Xtensa", [i32], 32, (add SAR, BREG,
+// MAC16 Option registers
+def ACCLO : SRReg<16, "acclo", ["ACCLO", "16"]>;
+def ACCHI : SRReg<17, "acchi", ["ACCHI", "17"]>;
+def M0 : SRReg<32, "m0", ["M0", "32"]>;
+def M1 : SRReg<33, "m1", ["M1", "33"]>;
+def M2 : SRReg<34, "m2", ["M2", "34"]>;
+def M3 : SRReg<35, "m3", ["M3", "35"]>;
+
+def MR01 : RegisterClass<"Xtensa", [i32], 32, (add M0, M1)>;
+def MR23 : RegisterClass<"Xtensa", [i32], 32, (add M2, M3)>;
+def MR : RegisterClass<"Xtensa", [i32], 32, (add MR01, MR23)>;
+
+def SR : RegisterClass<"Xtensa", [i32], 32, (add SAR, BREG, MR,
WINDOWBASE, WINDOWSTART)>;
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Xtensa/XtensaSubtarget.h b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
index 962bed2c2e36f..770f73905b337 100644
--- a/llvm/lib/Target/Xtensa/XtensaSubtarget.h
+++ b/llvm/lib/Target/Xtensa/XtensaSubtarget.h
@@ -66,6 +66,8 @@ class XtensaSubtarget : public XtensaGenSubtargetInfo {
bool hasDensity() const { return HasDensity; }
+ bool hasMAC16() const { return HasMAC16; }
+
bool hasWindowed() const { return HasWindowed; }
bool hasBoolean() const { return HasBoolean; }
diff --git a/llvm/test/MC/Xtensa/xtensa-mac16.s b/llvm/test/MC/Xtensa/xtensa-mac16.s
new file mode 100644
index 0000000000000..15200751ec8a0
--- /dev/null
+++ b/llvm/test/MC/Xtensa/xtensa-mac16.s
@@ -0,0 +1,233 @@
+# RUN: llvm-mc %s -triple=xtensa -mattr=+mac16 -show-encoding \
+# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
+
+.align 4
+LBL0:
+
+# CHECK-INST: umul.aa.ll a2, a3
+# CHECK: encoding: [0x34,0x02,0x70]
+ umul.aa.ll a2, a3
+# CHECK-INST: umul.aa.lh a2, a3
+# CHECK: encoding: [0x34,0x02,0x72]
+ umul.aa.lh a2, a3
+# CHECK-INST: umul.aa.hl a2, a3
+# CHECK: encoding: [0x34,0x02,0x71]
+ umul.aa.hl a2, a3
+# CHECK-INST: umul.aa.hh a2, a3
+# CHECK: encoding: [0x34,0x02,0x73]
+ umul.aa.hh a2, a3
+
+# CHECK-INST: mul.aa.ll a2, a3
+# CHECK: encoding: [0x34,0x02,0x74]
+ mul.aa.ll a2, a3
+# CHECK-INST: mul.aa.lh a2, a3
+# CHECK: encoding: [0x34,0x02,0x76]
+ mul.aa.lh a2, a3
+# CHECK-INST: mul.aa.hl a2, a3
+# CHECK: encoding: [0x34,0x02,0x75]
+ mul.aa.hl a2, a3
+# CHECK-INST: mul.aa.hh a2, a3
+# CHECK: encoding: [0x34,0x02,0x77]
+ mul.aa.hh a2, a3
+
+# CHECK-INST: mul.ad.ll a2, m2
+# CHECK: encoding: [0x04,0x02,0x34]
+ mul.ad.ll a2, m2
+# CHECK-INST: mul.ad.lh a2, m2
+# CHECK: encoding: [0x04,0x02,0x36]
+ mul.ad.lh a2, m2
+# CHECK-INST: mul.ad.hl a2, m2
+# CHECK: encoding: [0x04,0x02,0x35]
+ mul.ad.hl a2, m2
+# CHECK-INST: mul.ad.hh a2, m2
+# CHECK: encoding: [0x04,0x02,0x37]
+ mul.ad.hh a2, m2
+
+# CHECK-INST: mul.da.ll m1, a3
+# CHECK: encoding: [0x34,0x40,0x64]
+ mul.da.ll m1, a3
+# CHECK-INST: mul.da.lh m1, a3
+# CHECK: encoding: [0x34,0x40,0x66]
+ mul.da.lh m1, a3
+# CHECK-INST: mul.da.hl m1, a3
+# CHECK: encoding: [0x34,0x40,0x65]
+ mul.da.hl m1, a3
+# CHECK-INST: mul.da.hh m1, a3
+# CHECK: encoding: [0x34,0x40,0x67]
+ mul.da.hh m1, a3
+
+# CHECK-INST: mul.dd.ll m1, m2
+# CHECK: encoding: [0x04,0x40,0x24]
+ mul.dd.ll m1, m2
+# CHECK-INST: mul.dd.lh m1, m2
+# CHECK: encoding: [0x04,0x40,0x26]
+ mul.dd.lh m1, m2
+# CHECK-INST: mul.dd.hl m1, m2
+# CHECK: encoding: [0x04,0x40,0x25]
+ mul.dd.hl m1, m2
+# CHECK-INST: mul.dd.hh m1, m2
+# CHECK: encoding: [0x04,0x40,0x27]
+ mul.dd.hh m1, m2
+
+# CHECK-INST: mula.aa.ll a2, a3
+# CHECK: encoding: [0x34,0x02,0x78]
+ mula.aa.ll a2, a3
+# CHECK-INST: mula.aa.lh a2, a3
+# CHECK: encoding: [0x34,0x02,0x7a]
+ mula.aa.lh a2, a3
+# CHECK-INST: mula.aa.hl a2, a3
+# CHECK: encoding: [0x34,0x02,0x79]
+ mula.aa.hl a2, a3
+# CHECK-INST: mula.aa.hh a2, a3
+# CHECK: encoding: [0x34,0x02,0x7b]
+ mula.aa.hh a2, a3
+
+# CHECK-INST: mula.ad.ll a2, m2
+# CHECK: encoding: [0x04,0x02,0x38]
+ mula.ad.ll a2, m2
+# CHECK-INST: mula.ad.lh a2, m2
+# CHECK: encoding: [0x04,0x02,0x3a]
+ mula.ad.lh a2, m2
+# CHECK-INST: mula.ad.hl a2, m2
+# CHECK: encoding: [0x04,0x02,0x39]
+ mula.ad.hl a2, m2
+# CHECK-INST: mula.ad.hh a2, m2
+# CHECK: encoding: [0x04,0x02,0x3b]
+ mula.ad.hh a2, m2
+
+# CHECK-INST: mula.da.ll m1, a3
+# CHECK: encoding: [0x34,0x40,0x68]
+ mula.da.ll m1, a3
+# CHECK-INST: mula.da.lh m1, a3
+# CHECK: encoding: [0x34,0x40,0x6a]
+ mula.da.lh m1, a3
+# CHECK-INST: mula.da.hl m1, a3
+# CHECK: encoding: [0x34,0x40,0x69]
+ mula.da.hl m1, a3
+# CHECK-INST: mula.da.hh m1, a3
+# CHECK: encoding: [0x34,0x40,0x6b]
+ mula.da.hh m1, a3
+
+# CHECK-INST: mula.dd.ll m1, m2
+# CHECK: encoding: [0x04,0x40,0x28]
+ mula.dd.ll m1, m2
+# CHECK-INST: mula.dd.lh m1, m2
+# CHECK: encoding: [0x04,0x40,0x2a]
+ mula.dd.lh m1, m2
+# CHECK-INST: mula.dd.hl m1, m2
+# CHECK: encoding: [0x04,0x40,0x29]
+ mula.dd.hl m1, m2
+# CHECK-INST: mula.dd.hh m1, m2
+# CHECK: encoding: [0x04,0x40,0x2b]
+ mula.dd.hh m1, m2
+
+# CHECK-INST: muls.aa.ll a2, a3
+# CHECK: encoding: [0x34,0x02,0x7c]
+ muls.aa.ll a2, a3
+# CHECK-INST: muls.aa.lh a2, a3
+# CHECK: encoding: [0x34,0x02,0x7e]
+ muls.aa.lh a2, a3
+# CHECK-INST: muls.aa.hl a2, a3
+# CHECK: encoding: [0x34,0x02,0x7d]
+ muls.aa.hl a2, a3
+# CHECK-INST: muls.aa.hh a2, a3
+# CHECK: encoding: [0x34,0x02,0x7f]
+ muls.aa.hh a2, a3
+
+# CHECK-INST: muls.ad.ll a2, m2
+# CHECK: encoding: [0x04,0x02,0x3c]
+ muls.ad.ll a2, m2
+# CHECK-INST: muls.ad.lh a2, m2
+# CHECK: encoding: [0x04,0x02,0x3e]
+ muls.ad.lh a2, m2
+# CHECK-INST: muls.ad.hl a2, m2
+# CHECK: encoding: [0x04,0x02,0x3d]
+ muls.ad.hl a2, m2
+# CHECK-INST: muls.ad.hh a2, m2
+# CHECK: encoding: [0x04,0x02,0x3f]
+ muls.ad.hh a2, m2
+
+# CHECK-INST: muls.da.ll m1, a3
+# CHECK: encoding: [0x34,0x40,0x6c]
+ muls.da.ll m1, a3
+# CHECK-INST: muls.da.lh m1, a3
+# CHECK: encoding: [0x34,0x40,0x6e]
+ muls.da.lh m1, a3
+# CHECK-INST: muls.da.hl m1, a3
+# CHECK: encoding: [0x34,0x40,0x6d]
+ muls.da.hl m1, a3
+# CHECK-INST: muls.da.hh m1, a3
+# CHECK: encoding: [0x34,0x40,0x6f]
+ muls.da.hh m1, a3
+
+# CHECK-INST: muls.dd.ll m1, m2
+# CHECK: encoding: [0x04,0x40,0x2c]
+ muls.dd.ll m1, m2
+# CHECK-INST: muls.dd.lh m1, m2
+# CHECK: encoding: [0x04,0x40,0x2e]
+ muls.dd.lh m1, m2
+# CHECK-INST: muls.dd.hl m1, m2
+# CHECK: encoding: [0x04,0x40,0x2d]
+ muls.dd.hl m1, m2
+# CHECK-INST: muls.dd.hh m1, m2
+# CHECK: encoding: [0x04,0x40,0x2f]
+ muls.dd.hh m1, m2
+
+# CHECK-INST: mula.da.ll.lddec m1, a8, m0, a3
+# CHECK: encoding: [0x34,0x18,0x58]
+ mula.da.ll.lddec m1, a8, m0, a3
+# CHECK-INST: mula.da.hl.lddec m1, a8, m0, a3
+# CHECK: encoding: [0x34,0x18,0x59]
+ mula.da.hl.lddec m1, a8, m0, a3
+# CHECK-INST: mula.da.lh.lddec m1, a8, m0, a3
+# CHECK: encoding: [0x34,0x18,0x5a]
+ mula.da.lh.lddec m1, a8, m0, a3
+# CHECK-INST: mula.da.hh.lddec m1, a8, m0, a3
+# CHECK: encoding: [0x34,0x18,0x5b]
+ mula.da.hh.lddec m1, a8, m0, a3
+
+# CHECK-INST: mula.dd.ll.lddec m1, a8, m0, m2
+# CHECK: encoding: [0x04,0x18,0x18]
+ mula.dd.ll.lddec m1, a8, m0, m2
+# CHECK-INST: mula.dd.hl.lddec m1, a8, m0, m2
+# CHECK: encoding: [0x04,0x18,0x19]
+ mula.dd.hl.lddec m1, a8, m0, m2
+# CHECK-INST: mula.dd.lh.lddec m1, a8, m0, m2
+# CHECK: encoding: [0x04,0x18,0x1a]
+ mula.dd.lh.lddec m1, a8, m0, m2
+# CHECK-INST: mula.dd.hh.lddec m1, a8, m0, m2
+# CHECK: encoding: [0x04,0x18,0x1b]
+ mula.dd.hh.lddec m1, a8, m0, m2
+
+# CHECK-INST: mula.da.ll.ldinc m1, a8, m0, a3
+# CHECK: encoding: [0x34,0x18,0x48]
+ mula.da.ll.ldinc m1, a8, m0, a3
+# CHECK-INST: mula.da.hl.ldinc m1, a8, m0, a3
+# CHECK: encoding: [0x34,0x18,0x49]
+ mula.da.hl.ldinc m1, a8, m0, a3
+# CHECK-INST: mula.da.lh.ldinc m1, a8, m0, a3
+# CHECK: encoding: [0x34,0x18,0x4a]
+ mula.da.lh.ldinc m1, a8, m0, a3
+# CHECK-INST: mula.da.hh.ldinc m1, a8, m0, a3
+# CHECK: encoding: [0x34,0x18,0x4b]
+ mula.da.hh.ldinc m1, a8, m0, a3
+
+# CHECK-INST: mula.dd.ll.ldinc m1, a8, m0, m2
+# CHECK: encoding: [0x04,0x18,0x08]
+ mula.dd.ll.ldinc m1, a8, m0, m2
+# CHECK-INST: mula.dd.hl.ldinc m1, a8, m0, m2
+# CHECK: encoding: [0x04,0x18,0x09]
+ mula.dd.hl.ldinc m1, a8, m0, m2
+# CHECK-INST: mula.dd.lh.ldinc m1, a8, m0, m2
+# CHECK: encoding: [0x04,0x18,0x0a]
+ mula.dd.lh.ldinc m1, a8, m0, m2
+# CHECK-INST: mula.dd.hh.ldinc m1, a8, m0, m2
+# CHECK: encoding: [0x04,0x18,0x0b]
+ mula.dd.hh.ldinc m1, a8, m0, m2
+
+# CHECK-INST: lddec m0, a8
+# CHECK: encoding: [0x04,0x08,0x90]
+ lddec m0, a8
+# CHECK-INST: ldinc m0, a8
+# CHECK: encoding: [0x04,0x08,0x80]
+ ldinc m0, a8
>From f1e3f333d39f316b76eb7b8950880e7a45e7d475 Mon Sep 17 00:00:00 2001
From: Andrei Safronov <safronov at espressif.com>
Date: Fri, 7 Mar 2025 02:02:45 +0300
Subject: [PATCH 2/2] [Xtensa] Minor fixes.
---
.../Xtensa/Disassembler/XtensaDisassembler.cpp | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
index c1f6b39555223..b949b893953fe 100644
--- a/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
+++ b/llvm/lib/Target/Xtensa/Disassembler/XtensaDisassembler.cpp
@@ -73,8 +73,8 @@ static DecodeStatus DecodeARRegisterClass(MCInst &Inst, uint64_t RegNo,
return MCDisassembler::Success;
}
-static const unsigned MRDecoderTable[] = {Xtensa::M0, Xtensa::M1, Xtensa::M2,
- Xtensa::M3};
+static const MCPhysReg MRDecoderTable[] = {Xtensa::M0, Xtensa::M1, Xtensa::M2,
+ Xtensa::M3};
static DecodeStatus DecodeMRRegisterClass(MCInst &Inst, uint64_t RegNo,
uint64_t Address,
@@ -82,12 +82,12 @@ static DecodeStatus DecodeMRRegisterClass(MCInst &Inst, uint64_t RegNo,
if (RegNo >= std::size(MRDecoderTable))
return MCDisassembler::Fail;
- unsigned Reg = MRDecoderTable[RegNo];
+ MCPhysReg Reg = MRDecoderTable[RegNo];
Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}
-static const unsigned MR01DecoderTable[] = {Xtensa::M0, Xtensa::M1};
+static const MCPhysReg MR01DecoderTable[] = {Xtensa::M0, Xtensa::M1};
static DecodeStatus DecodeMR01RegisterClass(MCInst &Inst, uint64_t RegNo,
uint64_t Address,
@@ -95,20 +95,20 @@ static DecodeStatus DecodeMR01RegisterClass(MCInst &Inst, uint64_t RegNo,
if (RegNo > 2)
return MCDisassembler::Fail;
- unsigned Reg = MR01DecoderTable[RegNo];
+ MCPhysReg Reg = MR01DecoderTable[RegNo];
Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}
-static const unsigned MR23DecoderTable[] = {Xtensa::M2, Xtensa::M3};
+static const MCPhysReg MR23DecoderTable[] = {Xtensa::M2, Xtensa::M3};
static DecodeStatus DecodeMR23RegisterClass(MCInst &Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder) {
- if ((RegNo < 2) || (RegNo > 3))
+ if (RegNo != 2 && RegNo != 3)
return MCDisassembler::Fail;
- unsigned Reg = MR23DecoderTable[RegNo - 2];
+ MCPhysReg Reg = MR23DecoderTable[RegNo - 2];
Inst.addOperand(MCOperand::createReg(Reg));
return MCDisassembler::Success;
}
More information about the llvm-commits
mailing list