summaryrefslogtreecommitdiff
path: root/lib/Target/Hexagon
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Hexagon')
-rw-r--r--lib/Target/Hexagon/CMakeLists.txt25
-rw-r--r--lib/Target/Hexagon/Disassembler/CMakeLists.txt3
-rw-r--r--lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp181
-rw-r--r--lib/Target/Hexagon/Disassembler/LLVMBuild.txt (renamed from lib/Target/Hexagon/InstPrinter/LLVMBuild.txt)6
-rw-r--r--lib/Target/Hexagon/Disassembler/Makefile (renamed from lib/Target/Hexagon/InstPrinter/Makefile)9
-rw-r--r--lib/Target/Hexagon/Hexagon.h4
-rw-r--r--lib/Target/Hexagon/Hexagon.td14
-rw-r--r--lib/Target/Hexagon/HexagonAsmPrinter.cpp26
-rwxr-xr-xlib/Target/Hexagon/HexagonAsmPrinter.h4
-rw-r--r--lib/Target/Hexagon/HexagonCFGOptimizer.cpp28
-rw-r--r--lib/Target/Hexagon/HexagonCallingConvLower.cpp6
-rw-r--r--lib/Target/Hexagon/HexagonCallingConvLower.h4
-rw-r--r--lib/Target/Hexagon/HexagonCopyToCombine.cpp40
-rw-r--r--lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp46
-rw-r--r--lib/Target/Hexagon/HexagonFixupHwLoops.cpp14
-rw-r--r--lib/Target/Hexagon/HexagonFrameLowering.cpp31
-rw-r--r--lib/Target/Hexagon/HexagonFrameLowering.h4
-rw-r--r--lib/Target/Hexagon/HexagonHardwareLoops.cpp53
-rw-r--r--lib/Target/Hexagon/HexagonISelDAGToDAG.cpp152
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.cpp61
-rw-r--r--lib/Target/Hexagon/HexagonISelLowering.h15
-rw-r--r--lib/Target/Hexagon/HexagonInstrFormats.td22
-rw-r--r--lib/Target/Hexagon/HexagonInstrFormatsV4.td5
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.cpp672
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.h9
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfo.td5302
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfoV3.td141
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfoV4.td3628
-rw-r--r--lib/Target/Hexagon/HexagonInstrInfoV5.td495
-rw-r--r--lib/Target/Hexagon/HexagonIntrinsics.td9
-rw-r--r--lib/Target/Hexagon/HexagonIntrinsicsDerived.td7
-rw-r--r--lib/Target/Hexagon/HexagonIntrinsicsV4.td9
-rw-r--r--lib/Target/Hexagon/HexagonMCInstLower.cpp1
-rw-r--r--lib/Target/Hexagon/HexagonMachineFunctionInfo.h4
-rw-r--r--lib/Target/Hexagon/HexagonMachineScheduler.cpp10
-rw-r--r--lib/Target/Hexagon/HexagonMachineScheduler.h20
-rw-r--r--lib/Target/Hexagon/HexagonNewValueJump.cpp51
-rw-r--r--lib/Target/Hexagon/HexagonOperands.td23
-rw-r--r--lib/Target/Hexagon/HexagonPeephole.cpp27
-rw-r--r--lib/Target/Hexagon/HexagonRegisterInfo.cpp37
-rw-r--r--lib/Target/Hexagon/HexagonRegisterInfo.h4
-rw-r--r--lib/Target/Hexagon/HexagonRegisterInfo.td164
-rw-r--r--lib/Target/Hexagon/HexagonSelectionDAGInfo.h4
-rw-r--r--lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp15
-rw-r--r--lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp26
-rw-r--r--lib/Target/Hexagon/HexagonSubtarget.h28
-rw-r--r--lib/Target/Hexagon/HexagonTargetMachine.cpp43
-rw-r--r--lib/Target/Hexagon/HexagonTargetMachine.h31
-rw-r--r--lib/Target/Hexagon/HexagonTargetObjectFile.cpp5
-rw-r--r--lib/Target/Hexagon/HexagonTargetObjectFile.h4
-rw-r--r--lib/Target/Hexagon/HexagonVLIWPacketizer.cpp142
-rw-r--r--lib/Target/Hexagon/HexagonVarargsCallingConvention.h20
-rw-r--r--lib/Target/Hexagon/InstPrinter/CMakeLists.txt3
-rw-r--r--lib/Target/Hexagon/LLVMBuild.txt4
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt6
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp74
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h14
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp62
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp (renamed from lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp)62
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h (renamed from lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h)4
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp1
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h4
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp88
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h60
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp128
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h124
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp63
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h26
-rw-r--r--lib/Target/Hexagon/MCTargetDesc/LLVMBuild.txt2
-rw-r--r--lib/Target/Hexagon/Makefile16
70 files changed, 8535 insertions, 3890 deletions
diff --git a/lib/Target/Hexagon/CMakeLists.txt b/lib/Target/Hexagon/CMakeLists.txt
index 81b0e5680547..af7914f30366 100644
--- a/lib/Target/Hexagon/CMakeLists.txt
+++ b/lib/Target/Hexagon/CMakeLists.txt
@@ -1,28 +1,32 @@
set(LLVM_TARGET_DEFINITIONS Hexagon.td)
-tablegen(LLVM HexagonGenRegisterInfo.inc -gen-register-info)
-tablegen(LLVM HexagonGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM HexagonGenAsmWriter.inc -gen-asm-writer)
-tablegen(LLVM HexagonGenDAGISel.inc -gen-dag-isel)
tablegen(LLVM HexagonGenCallingConv.inc -gen-callingconv)
-tablegen(LLVM HexagonGenSubtargetInfo.inc -gen-subtarget)
+tablegen(LLVM HexagonGenDAGISel.inc -gen-dag-isel)
tablegen(LLVM HexagonGenDFAPacketizer.inc -gen-dfa-packetizer)
+tablegen(LLVM HexagonGenDisassemblerTables.inc -gen-disassembler)
+tablegen(LLVM HexagonGenInstrInfo.inc -gen-instr-info)
+tablegen(LLVM HexagonGenMCCodeEmitter.inc -gen-emitter)
+tablegen(LLVM HexagonGenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM HexagonGenSubtargetInfo.inc -gen-subtarget)
add_public_tablegen_target(HexagonCommonTableGen)
add_llvm_target(HexagonCodeGen
HexagonAsmPrinter.cpp
HexagonCallingConvLower.cpp
HexagonCFGOptimizer.cpp
+ HexagonCopyToCombine.cpp
HexagonExpandPredSpillCode.cpp
+ HexagonFixupHwLoops.cpp
HexagonFrameLowering.cpp
HexagonHardwareLoops.cpp
- HexagonFixupHwLoops.cpp
- HexagonMachineFunctionInfo.cpp
- HexagonMachineScheduler.cpp
- HexagonMCInstLower.cpp
HexagonInstrInfo.cpp
HexagonISelDAGToDAG.cpp
HexagonISelLowering.cpp
+ HexagonMachineFunctionInfo.cpp
+ HexagonMachineScheduler.cpp
+ HexagonMCInstLower.cpp
+ HexagonNewValueJump.cpp
HexagonPeephole.cpp
HexagonRegisterInfo.cpp
HexagonRemoveSZExtArgs.cpp
@@ -33,11 +37,8 @@ add_llvm_target(HexagonCodeGen
HexagonTargetMachine.cpp
HexagonTargetObjectFile.cpp
HexagonVLIWPacketizer.cpp
- HexagonNewValueJump.cpp
- HexagonCopyToCombine.cpp
)
add_subdirectory(TargetInfo)
-add_subdirectory(InstPrinter)
add_subdirectory(MCTargetDesc)
-
+add_subdirectory(Disassembler)
diff --git a/lib/Target/Hexagon/Disassembler/CMakeLists.txt b/lib/Target/Hexagon/Disassembler/CMakeLists.txt
new file mode 100644
index 000000000000..755a45e2df8b
--- /dev/null
+++ b/lib/Target/Hexagon/Disassembler/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_llvm_library(LLVMHexagonDisassembler
+ HexagonDisassembler.cpp
+ )
diff --git a/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
new file mode 100644
index 000000000000..44f9d93e8fc7
--- /dev/null
+++ b/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
@@ -0,0 +1,181 @@
+//===-- HexagonDisassembler.cpp - Disassembler for Hexagon ISA ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MCTargetDesc/HexagonBaseInfo.h"
+#include "MCTargetDesc/HexagonMCInst.h"
+#include "MCTargetDesc/HexagonMCTargetDesc.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCFixedLenDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/LEB128.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/raw_ostream.h"
+#include <array>
+#include <vector>
+
+using namespace llvm;
+
+#define DEBUG_TYPE "hexagon-disassembler"
+
+// Pull DecodeStatus and its enum values into the global namespace.
+typedef llvm::MCDisassembler::DecodeStatus DecodeStatus;
+
+namespace {
+/// \brief Hexagon disassembler for all Hexagon platforms.
+class HexagonDisassembler : public MCDisassembler {
+public:
+ HexagonDisassembler(MCSubtargetInfo const &STI, MCContext &Ctx)
+ : MCDisassembler(STI, Ctx) {}
+
+ DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
+ ArrayRef<uint8_t> Bytes, uint64_t Address,
+ raw_ostream &VStream,
+ raw_ostream &CStream) const override;
+};
+}
+
+static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
+ uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
+ uint64_t Address, const void *Decoder);
+
+static const uint16_t IntRegDecoderTable[] = {
+ Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
+ Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9,
+ Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
+ Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
+ Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24,
+ Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29,
+ Hexagon::R30, Hexagon::R31 };
+
+static const uint16_t PredRegDecoderTable[] = { Hexagon::P0, Hexagon::P1,
+Hexagon::P2, Hexagon::P3 };
+
+static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo,
+ const uint16_t Table[], size_t Size) {
+ if (RegNo < Size) {
+ Inst.addOperand(MCOperand::CreateReg(Table[RegNo]));
+ return MCDisassembler::Success;
+ }
+ else
+ return MCDisassembler::Fail;
+}
+
+static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
+ uint64_t /*Address*/,
+ void const *Decoder) {
+ if (RegNo > 31)
+ return MCDisassembler::Fail;
+
+ unsigned Register = IntRegDecoderTable[RegNo];
+ Inst.addOperand(MCOperand::CreateReg(Register));
+ return MCDisassembler::Success;
+}
+
+static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
+ uint64_t /*Address*/, const void *Decoder) {
+ static const uint16_t CtrlRegDecoderTable[] = {
+ Hexagon::SA0, Hexagon::LC0, Hexagon::SA1, Hexagon::LC1,
+ Hexagon::P3_0, Hexagon::NoRegister, Hexagon::C6, Hexagon::C7,
+ Hexagon::USR, Hexagon::PC, Hexagon::UGP, Hexagon::GP,
+ Hexagon::CS0, Hexagon::CS1, Hexagon::UPCL, Hexagon::UPCH
+ };
+
+ if (RegNo >= sizeof(CtrlRegDecoderTable) / sizeof(CtrlRegDecoderTable[0]))
+ return MCDisassembler::Fail;
+
+ if (CtrlRegDecoderTable[RegNo] == Hexagon::NoRegister)
+ return MCDisassembler::Fail;
+
+ unsigned Register = CtrlRegDecoderTable[RegNo];
+ Inst.addOperand(MCOperand::CreateReg(Register));
+ return MCDisassembler::Success;
+}
+
+static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
+ uint64_t /*Address*/, const void *Decoder) {
+ unsigned Register = 0;
+ switch (RegNo) {
+ case 0:
+ Register = Hexagon::M0;
+ break;
+ case 1:
+ Register = Hexagon::M1;
+ break;
+ default:
+ return MCDisassembler::Fail;
+ }
+ Inst.addOperand(MCOperand::CreateReg(Register));
+ return MCDisassembler::Success;
+}
+
+static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo,
+ uint64_t /*Address*/, const void *Decoder) {
+ static const uint16_t DoubleRegDecoderTable[] = {
+ Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3,
+ Hexagon::D4, Hexagon::D5, Hexagon::D6, Hexagon::D7,
+ Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11,
+ Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15
+ };
+
+ return (DecodeRegisterClass(Inst, RegNo >> 1,
+ DoubleRegDecoderTable,
+ sizeof (DoubleRegDecoderTable)));
+}
+
+static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
+ uint64_t /*Address*/,
+ void const *Decoder) {
+ if (RegNo > 3)
+ return MCDisassembler::Fail;
+
+ unsigned Register = PredRegDecoderTable[RegNo];
+ Inst.addOperand(MCOperand::CreateReg(Register));
+ return MCDisassembler::Success;
+}
+
+#include "HexagonGenDisassemblerTables.inc"
+
+static MCDisassembler *createHexagonDisassembler(Target const &T,
+ MCSubtargetInfo const &STI,
+ MCContext &Ctx) {
+ return new HexagonDisassembler(STI, Ctx);
+}
+
+extern "C" void LLVMInitializeHexagonDisassembler() {
+ TargetRegistry::RegisterMCDisassembler(TheHexagonTarget,
+ createHexagonDisassembler);
+}
+
+DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
+ ArrayRef<uint8_t> Bytes,
+ uint64_t Address,
+ raw_ostream &os,
+ raw_ostream &cs) const {
+ Size = 4;
+ if (Bytes.size() < 4)
+ return MCDisassembler::Fail;
+
+ uint32_t insn =
+ llvm::support::endian::read<uint32_t, llvm::support::little,
+ llvm::support::unaligned>(Bytes.data());
+
+ // Remove parse bits.
+ insn &= ~static_cast<uint32_t>(HexagonII::InstParseBits::INST_PARSE_MASK);
+ DecodeStatus Result = decodeInstruction(DecoderTable32, MI, insn, Address, this, STI);
+ HexagonMCInst::AppendImplicitOperands(MI);
+ return Result;
+}
diff --git a/lib/Target/Hexagon/InstPrinter/LLVMBuild.txt b/lib/Target/Hexagon/Disassembler/LLVMBuild.txt
index 59849aa7e1c7..43bace75a852 100644
--- a/lib/Target/Hexagon/InstPrinter/LLVMBuild.txt
+++ b/lib/Target/Hexagon/Disassembler/LLVMBuild.txt
@@ -1,4 +1,4 @@
-;===- ./lib/Target/Hexagon/InstPrinter/LLVMBuild.txt -----------*- Conf -*--===;
+;===-- ./lib/Target/Hexagon/Disassembler/LLVMBuild.txt ---------*- Conf -*--===;
;
; The LLVM Compiler Infrastructure
;
@@ -17,7 +17,7 @@
[component_0]
type = Library
-name = HexagonAsmPrinter
+name = HexagonDisassembler
parent = Hexagon
-required_libraries = HexagonDesc MC Support
+required_libraries = HexagonDesc HexagonInfo MCDisassembler Support
add_to_library_groups = Hexagon
diff --git a/lib/Target/Hexagon/InstPrinter/Makefile b/lib/Target/Hexagon/Disassembler/Makefile
index 20331d8807ec..16c305fe4074 100644
--- a/lib/Target/Hexagon/InstPrinter/Makefile
+++ b/lib/Target/Hexagon/Disassembler/Makefile
@@ -1,4 +1,4 @@
-##===- lib/Target/Hexagon/InstPrinter/Makefile ----------------------------===##
+##===-- lib/Target/Hexagon/Disassembler/Makefile -----------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -6,10 +6,11 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+
LEVEL = ../../../..
-LIBRARYNAME = LLVMHexagonAsmPrinter
+LIBRARYNAME = LLVMHexagonDisassembler
-# Hack: we need to include 'main' Hexagon target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
+# Hack: we need to include 'main' target directory to grab private headers
+CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
include $(LEVEL)/Makefile.common
diff --git a/lib/Target/Hexagon/Hexagon.h b/lib/Target/Hexagon/Hexagon.h
index 5467ee361257..64ae69c60e5d 100644
--- a/lib/Target/Hexagon/Hexagon.h
+++ b/lib/Target/Hexagon/Hexagon.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef TARGET_Hexagon_H
-#define TARGET_Hexagon_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGON_H
+#define LLVM_LIB_TARGET_HEXAGON_HEXAGON_H
#include "MCTargetDesc/HexagonMCTargetDesc.h"
#include "llvm/Target/TargetLowering.h"
diff --git a/lib/Target/Hexagon/Hexagon.td b/lib/Target/Hexagon/Hexagon.td
index 5f4a6c64f703..2068c6da4e48 100644
--- a/lib/Target/Hexagon/Hexagon.td
+++ b/lib/Target/Hexagon/Hexagon.td
@@ -50,6 +50,8 @@ def IEEERndNearV5T : Predicate<"Subtarget.modeIEEERndNear()">;
//===----------------------------------------------------------------------===//
// Classes used for relation maps.
//===----------------------------------------------------------------------===//
+
+class ImmRegShl;
// PredRel - Filter class used to relate non-predicated instructions with their
// predicated forms.
class PredRel;
@@ -137,7 +139,7 @@ def getPredOldOpcode : InstrMapping {
//
def getNewValueOpcode : InstrMapping {
let FilterClass = "NewValueRel";
- let RowFields = ["BaseOpcode", "PredSense", "PNewValue"];
+ let RowFields = ["BaseOpcode", "PredSense", "PNewValue", "addrMode"];
let ColFields = ["NValueST"];
let KeyCol = ["false"];
let ValueCols = [["true"]];
@@ -149,7 +151,7 @@ def getNewValueOpcode : InstrMapping {
//
def getNonNVStore : InstrMapping {
let FilterClass = "NewValueRel";
- let RowFields = ["BaseOpcode", "PredSense", "PNewValue"];
+ let RowFields = ["BaseOpcode", "PredSense", "PNewValue", "addrMode"];
let ColFields = ["NValueST"];
let KeyCol = ["true"];
let ValueCols = [["false"]];
@@ -180,6 +182,14 @@ def getRegForm : InstrMapping {
let ValueCols = [["reg"]];
}
+def getRegShlForm : InstrMapping {
+ let FilterClass = "ImmRegShl";
+ let RowFields = ["CextOpcode", "PredSense", "PNewValue", "isNVStore"];
+ let ColFields = ["InputType"];
+ let KeyCol = ["imm"];
+ let ValueCols = [["reg"]];
+}
+
//===----------------------------------------------------------------------===//
// Register File, Calling Conv, Instruction Descriptions
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/lib/Target/Hexagon/HexagonAsmPrinter.cpp
index 2e011bd12741..50f2eca63693 100644
--- a/lib/Target/Hexagon/HexagonAsmPrinter.cpp
+++ b/lib/Target/Hexagon/HexagonAsmPrinter.cpp
@@ -18,7 +18,7 @@
#include "HexagonMachineFunctionInfo.h"
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
-#include "InstPrinter/HexagonInstPrinter.h"
+#include "MCTargetDesc/HexagonInstPrinter.h"
#include "MCTargetDesc/HexagonMCInst.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
@@ -174,7 +174,7 @@ bool HexagonAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
///
void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
if (MI->isBundle()) {
- std::vector<const MachineInstr*> BundleMIs;
+ std::vector<MachineInstr const *> BundleMIs;
const MachineBasicBlock *MBB = MI->getParent();
MachineBasicBlock::const_instr_iterator MII = MI;
@@ -183,33 +183,35 @@ void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
while (MII != MBB->end() && MII->isInsideBundle()) {
const MachineInstr *MInst = MII;
if (MInst->getOpcode() == TargetOpcode::DBG_VALUE ||
- MInst->getOpcode() == TargetOpcode::IMPLICIT_DEF) {
- IgnoreCount++;
- ++MII;
- continue;
+ MInst->getOpcode() == TargetOpcode::IMPLICIT_DEF) {
+ IgnoreCount++;
+ ++MII;
+ continue;
}
- //BundleMIs.push_back(&*MII);
+ // BundleMIs.push_back(&*MII);
BundleMIs.push_back(MInst);
++MII;
}
unsigned Size = BundleMIs.size();
- assert((Size+IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!");
+ assert((Size + IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!");
for (unsigned Index = 0; Index < Size; Index++) {
HexagonMCInst MCI;
- MCI.setPacketStart(Index == 0);
- MCI.setPacketEnd(Index == (Size-1));
HexagonLowerToMC(BundleMIs[Index], MCI, *this);
+ HexagonMCInst::AppendImplicitOperands(MCI);
+ MCI.setPacketBegin(Index == 0);
+ MCI.setPacketEnd(Index == (Size - 1));
EmitToStreamer(OutStreamer, MCI);
}
}
else {
HexagonMCInst MCI;
+ HexagonLowerToMC(MI, MCI, *this);
+ HexagonMCInst::AppendImplicitOperands(MCI);
if (MI->getOpcode() == Hexagon::ENDLOOP0) {
- MCI.setPacketStart(true);
+ MCI.setPacketBegin(true);
MCI.setPacketEnd(true);
}
- HexagonLowerToMC(MI, MCI, *this);
EmitToStreamer(OutStreamer, MCI);
}
diff --git a/lib/Target/Hexagon/HexagonAsmPrinter.h b/lib/Target/Hexagon/HexagonAsmPrinter.h
index 7fe8c5790c6b..5f4c162b0070 100755
--- a/lib/Target/Hexagon/HexagonAsmPrinter.h
+++ b/lib/Target/Hexagon/HexagonAsmPrinter.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef HEXAGONASMPRINTER_H
-#define HEXAGONASMPRINTER_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONASMPRINTER_H
+#define LLVM_LIB_TARGET_HEXAGON_HEXAGONASMPRINTER_H
#include "Hexagon.h"
#include "HexagonTargetMachine.h"
diff --git a/lib/Target/Hexagon/HexagonCFGOptimizer.cpp b/lib/Target/Hexagon/HexagonCFGOptimizer.cpp
index de340e0074db..307adad095c8 100644
--- a/lib/Target/Hexagon/HexagonCFGOptimizer.cpp
+++ b/lib/Target/Hexagon/HexagonCFGOptimizer.cpp
@@ -59,36 +59,36 @@ private:
char HexagonCFGOptimizer::ID = 0;
static bool IsConditionalBranch(int Opc) {
- return (Opc == Hexagon::JMP_t) || (Opc == Hexagon::JMP_f)
- || (Opc == Hexagon::JMP_tnew_t) || (Opc == Hexagon::JMP_fnew_t);
+ return (Opc == Hexagon::J2_jumpt) || (Opc == Hexagon::J2_jumpf)
+ || (Opc == Hexagon::J2_jumptnewpt) || (Opc == Hexagon::J2_jumpfnewpt);
}
static bool IsUnconditionalJump(int Opc) {
- return (Opc == Hexagon::JMP);
+ return (Opc == Hexagon::J2_jump);
}
void
HexagonCFGOptimizer::InvertAndChangeJumpTarget(MachineInstr* MI,
MachineBasicBlock* NewTarget) {
- const HexagonInstrInfo *QII = QTM.getInstrInfo();
+ const HexagonInstrInfo *QII = QTM.getSubtargetImpl()->getInstrInfo();
int NewOpcode = 0;
switch(MI->getOpcode()) {
- case Hexagon::JMP_t:
- NewOpcode = Hexagon::JMP_f;
+ case Hexagon::J2_jumpt:
+ NewOpcode = Hexagon::J2_jumpf;
break;
- case Hexagon::JMP_f:
- NewOpcode = Hexagon::JMP_t;
+ case Hexagon::J2_jumpf:
+ NewOpcode = Hexagon::J2_jumpt;
break;
- case Hexagon::JMP_tnew_t:
- NewOpcode = Hexagon::JMP_fnew_t;
+ case Hexagon::J2_jumptnewpt:
+ NewOpcode = Hexagon::J2_jumpfnewpt;
break;
- case Hexagon::JMP_fnew_t:
- NewOpcode = Hexagon::JMP_tnew_t;
+ case Hexagon::J2_jumpfnewpt:
+ NewOpcode = Hexagon::J2_jumptnewpt;
break;
default:
@@ -163,8 +163,8 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
// The target of the unconditional branch must be JumpAroundTarget.
// TODO: If not, we should not invert the unconditional branch.
MachineBasicBlock* CondBranchTarget = nullptr;
- if ((MI->getOpcode() == Hexagon::JMP_t) ||
- (MI->getOpcode() == Hexagon::JMP_f)) {
+ if ((MI->getOpcode() == Hexagon::J2_jumpt) ||
+ (MI->getOpcode() == Hexagon::J2_jumpf)) {
CondBranchTarget = MI->getOperand(1).getMBB();
}
diff --git a/lib/Target/Hexagon/HexagonCallingConvLower.cpp b/lib/Target/Hexagon/HexagonCallingConvLower.cpp
index f5f958c101b1..8d78409aa01d 100644
--- a/lib/Target/Hexagon/HexagonCallingConvLower.cpp
+++ b/lib/Target/Hexagon/HexagonCallingConvLower.cpp
@@ -21,6 +21,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
Hexagon_CCState::Hexagon_CCState(CallingConv::ID CC, bool isVarArg,
@@ -31,7 +32,8 @@ Hexagon_CCState::Hexagon_CCState(CallingConv::ID CC, bool isVarArg,
// No stack is used.
StackOffset = 0;
- UsedRegs.resize((TM.getRegisterInfo()->getNumRegs()+31)/32);
+ UsedRegs.resize(
+ (TM.getSubtargetImpl()->getRegisterInfo()->getNumRegs() + 31) / 32);
}
// HandleByVal - Allocate a stack slot large enough to pass an argument by
@@ -55,7 +57,7 @@ void Hexagon_CCState::HandleByVal(unsigned ValNo, EVT ValVT,
/// MarkAllocated - Mark a register and all of its aliases as allocated.
void Hexagon_CCState::MarkAllocated(unsigned Reg) {
- const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
+ const TargetRegisterInfo &TRI = *TM.getSubtargetImpl()->getRegisterInfo();
for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)
UsedRegs[*AI/32] |= 1 << (*AI&31);
}
diff --git a/lib/Target/Hexagon/HexagonCallingConvLower.h b/lib/Target/Hexagon/HexagonCallingConvLower.h
index 70b8b643441a..738ed1a52a09 100644
--- a/lib/Target/Hexagon/HexagonCallingConvLower.h
+++ b/lib/Target/Hexagon/HexagonCallingConvLower.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_Hexagon_CODEGEN_CALLINGCONVLOWER_H
-#define LLVM_Hexagon_CODEGEN_CALLINGCONVLOWER_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONCALLINGCONVLOWER_H
+#define LLVM_LIB_TARGET_HEXAGON_HEXAGONCALLINGCONVLOWER_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/CallingConvLower.h"
diff --git a/lib/Target/Hexagon/HexagonCopyToCombine.cpp b/lib/Target/Hexagon/HexagonCopyToCombine.cpp
index aeff680e6a9e..1883ad8f2e51 100644
--- a/lib/Target/Hexagon/HexagonCopyToCombine.cpp
+++ b/lib/Target/Hexagon/HexagonCopyToCombine.cpp
@@ -114,7 +114,7 @@ static bool isCombinableInstType(MachineInstr *MI,
const HexagonInstrInfo *TII,
bool ShouldCombineAggressively) {
switch(MI->getOpcode()) {
- case Hexagon::TFR: {
+ case Hexagon::A2_tfr: {
// A COPY instruction can be combined if its arguments are IntRegs (32bit).
assert(MI->getOperand(0).isReg() && MI->getOperand(1).isReg());
@@ -124,7 +124,7 @@ static bool isCombinableInstType(MachineInstr *MI,
Hexagon::IntRegsRegClass.contains(SrcReg);
}
- case Hexagon::TFRI: {
+ case Hexagon::A2_tfrsi: {
// A transfer-immediate can be combined if its argument is a signed 8bit
// value.
assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
@@ -158,11 +158,11 @@ static bool isCombinableInstType(MachineInstr *MI,
}
static bool isGreaterThan8BitTFRI(MachineInstr *I) {
- return I->getOpcode() == Hexagon::TFRI &&
+ return I->getOpcode() == Hexagon::A2_tfrsi &&
!isInt<8>(I->getOperand(1).getImm());
}
static bool isGreaterThan6BitTFRI(MachineInstr *I) {
- return I->getOpcode() == Hexagon::TFRI &&
+ return I->getOpcode() == Hexagon::A2_tfrsi &&
!isUInt<6>(I->getOperand(1).getImm());
}
@@ -171,11 +171,11 @@ static bool isGreaterThan6BitTFRI(MachineInstr *I) {
static bool areCombinableOperations(const TargetRegisterInfo *TRI,
MachineInstr *HighRegInst,
MachineInstr *LowRegInst) {
- assert((HighRegInst->getOpcode() == Hexagon::TFR ||
- HighRegInst->getOpcode() == Hexagon::TFRI ||
+ assert((HighRegInst->getOpcode() == Hexagon::A2_tfr ||
+ HighRegInst->getOpcode() == Hexagon::A2_tfrsi ||
HighRegInst->getOpcode() == Hexagon::TFRI_V4) &&
- (LowRegInst->getOpcode() == Hexagon::TFR ||
- LowRegInst->getOpcode() == Hexagon::TFRI ||
+ (LowRegInst->getOpcode() == Hexagon::A2_tfr ||
+ LowRegInst->getOpcode() == Hexagon::A2_tfrsi ||
LowRegInst->getOpcode() == Hexagon::TFRI_V4) &&
"Assume individual instructions are of a combinable type");
@@ -417,8 +417,8 @@ bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) {
bool HasChanged = false;
// Get target info.
- TRI = MF.getTarget().getRegisterInfo();
- TII = static_cast<const HexagonInstrInfo *>(MF.getTarget().getInstrInfo());
+ TRI = MF.getSubtarget().getRegisterInfo();
+ TII = static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());
// Combine aggressively (for code size)
ShouldCombineAggressively =
@@ -563,14 +563,14 @@ void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt,
// Handle globals.
if (HiOperand.isGlobal()) {
- BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ii), DoubleDestReg)
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
.addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
HiOperand.getTargetFlags())
.addImm(LoOperand.getImm());
return;
}
if (LoOperand.isGlobal()) {
- BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_iI_V4), DoubleDestReg)
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
.addImm(HiOperand.getImm())
.addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
LoOperand.getTargetFlags());
@@ -580,7 +580,7 @@ void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt,
// Handle constant extended immediates.
if (!isInt<8>(HiOperand.getImm())) {
assert(isInt<8>(LoOperand.getImm()));
- BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ii), DoubleDestReg)
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
.addImm(HiOperand.getImm())
.addImm(LoOperand.getImm());
return;
@@ -588,7 +588,7 @@ void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt,
if (!isUInt<6>(LoOperand.getImm())) {
assert(isInt<8>(HiOperand.getImm()));
- BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_iI_V4), DoubleDestReg)
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
.addImm(HiOperand.getImm())
.addImm(LoOperand.getImm());
return;
@@ -596,7 +596,7 @@ void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt,
// Insert new combine instruction.
// DoubleRegDest = combine #HiImm, #LoImm
- BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ii), DoubleDestReg)
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
.addImm(HiOperand.getImm())
.addImm(LoOperand.getImm());
}
@@ -613,7 +613,7 @@ void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt,
// Handle global.
if (HiOperand.isGlobal()) {
- BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ir_V4), DoubleDestReg)
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
.addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
HiOperand.getTargetFlags())
.addReg(LoReg, LoRegKillFlag);
@@ -621,7 +621,7 @@ void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt,
}
// Insert new combine instruction.
// DoubleRegDest = combine #HiImm, LoReg
- BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_Ir_V4), DoubleDestReg)
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg)
.addImm(HiOperand.getImm())
.addReg(LoReg, LoRegKillFlag);
}
@@ -638,7 +638,7 @@ void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt,
// Handle global.
if (LoOperand.isGlobal()) {
- BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_rI_V4), DoubleDestReg)
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
.addReg(HiReg, HiRegKillFlag)
.addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
LoOperand.getTargetFlags());
@@ -647,7 +647,7 @@ void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt,
// Insert new combine instruction.
// DoubleRegDest = combine HiReg, #LoImm
- BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_rI_V4), DoubleDestReg)
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
.addReg(HiReg, HiRegKillFlag)
.addImm(LoOperand.getImm());
}
@@ -666,7 +666,7 @@ void HexagonCopyToCombine::emitCombineRR(MachineBasicBlock::iterator &InsertPt,
// Insert new combine instruction.
// DoubleRegDest = combine HiReg, LoReg
- BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::COMBINE_rr), DoubleDestReg)
+ BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combinew), DoubleDestReg)
.addReg(HiReg, HiRegKillFlag)
.addReg(LoReg, LoRegKillFlag);
}
diff --git a/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp b/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp
index 3dafe80ffc48..a2a847c47a20 100644
--- a/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp
+++ b/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp
@@ -72,7 +72,7 @@ char HexagonExpandPredSpillCode::ID = 0;
bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) {
- const HexagonInstrInfo *TII = QTM.getInstrInfo();
+ const HexagonInstrInfo *TII = QTM.getSubtargetImpl()->getInstrInfo();
// Loop over all of the basic blocks.
for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
@@ -86,43 +86,45 @@ bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) {
if (Opc == Hexagon::STriw_pred) {
// STriw_pred [R30], ofst, SrcReg;
unsigned FP = MI->getOperand(0).getReg();
- assert(FP == QTM.getRegisterInfo()->getFrameRegister() &&
- "Not a Frame Pointer, Nor a Spill Slot");
+ assert(
+ FP ==
+ QTM.getSubtargetImpl()->getRegisterInfo()->getFrameRegister() &&
+ "Not a Frame Pointer, Nor a Spill Slot");
assert(MI->getOperand(1).isImm() && "Not an offset");
int Offset = MI->getOperand(1).getImm();
int SrcReg = MI->getOperand(2).getReg();
assert(Hexagon::PredRegsRegClass.contains(SrcReg) &&
"Not a predicate register");
- if (!TII->isValidOffset(Hexagon::STriw_indexed, Offset)) {
+ if (!TII->isValidOffset(Hexagon::S2_storeri_io, Offset)) {
if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) {
BuildMI(*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::CONST32_Int_Real),
HEXAGON_RESERVED_REG_1).addImm(Offset);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr),
+ BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_add),
HEXAGON_RESERVED_REG_1)
.addReg(FP).addReg(HEXAGON_RESERVED_REG_1);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
+ BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr),
HEXAGON_RESERVED_REG_2).addReg(SrcReg);
BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Hexagon::STriw_indexed))
+ TII->get(Hexagon::S2_storeri_io))
.addReg(HEXAGON_RESERVED_REG_1)
.addImm(0).addReg(HEXAGON_RESERVED_REG_2);
} else {
BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri),
HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
+ BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr),
HEXAGON_RESERVED_REG_2).addReg(SrcReg);
BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Hexagon::STriw_indexed))
+ TII->get(Hexagon::S2_storeri_io))
.addReg(HEXAGON_RESERVED_REG_1)
.addImm(0)
.addReg(HEXAGON_RESERVED_REG_2);
}
} else {
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
+ BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr),
HEXAGON_RESERVED_REG_2).addReg(SrcReg);
BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Hexagon::STriw_indexed)).
+ TII->get(Hexagon::S2_storeri_io)).
addReg(FP).addImm(Offset).addReg(HEXAGON_RESERVED_REG_2);
}
MII = MBB->erase(MI);
@@ -133,39 +135,41 @@ bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) {
assert(Hexagon::PredRegsRegClass.contains(DstReg) &&
"Not a predicate register");
unsigned FP = MI->getOperand(1).getReg();
- assert(FP == QTM.getRegisterInfo()->getFrameRegister() &&
- "Not a Frame Pointer, Nor a Spill Slot");
+ assert(
+ FP ==
+ QTM.getSubtargetImpl()->getRegisterInfo()->getFrameRegister() &&
+ "Not a Frame Pointer, Nor a Spill Slot");
assert(MI->getOperand(2).isImm() && "Not an offset");
int Offset = MI->getOperand(2).getImm();
- if (!TII->isValidOffset(Hexagon::LDriw, Offset)) {
+ if (!TII->isValidOffset(Hexagon::L2_loadri_io, Offset)) {
if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) {
BuildMI(*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::CONST32_Int_Real),
HEXAGON_RESERVED_REG_1).addImm(Offset);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr),
+ BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_add),
HEXAGON_RESERVED_REG_1)
.addReg(FP)
.addReg(HEXAGON_RESERVED_REG_1);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw),
+ BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io),
HEXAGON_RESERVED_REG_2)
.addReg(HEXAGON_RESERVED_REG_1)
.addImm(0);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs),
+ BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp),
DstReg).addReg(HEXAGON_RESERVED_REG_2);
} else {
BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri),
HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw),
+ BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io),
HEXAGON_RESERVED_REG_2)
.addReg(HEXAGON_RESERVED_REG_1)
.addImm(0);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs),
+ BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp),
DstReg).addReg(HEXAGON_RESERVED_REG_2);
}
} else {
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw),
+ BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io),
HEXAGON_RESERVED_REG_2).addReg(FP).addImm(Offset);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs),
+ BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp),
DstReg).addReg(HEXAGON_RESERVED_REG_2);
}
MII = MBB->erase(MI);
diff --git a/lib/Target/Hexagon/HexagonFixupHwLoops.cpp b/lib/Target/Hexagon/HexagonFixupHwLoops.cpp
index d41939a57a45..e8d8f1497bdb 100644
--- a/lib/Target/Hexagon/HexagonFixupHwLoops.cpp
+++ b/lib/Target/Hexagon/HexagonFixupHwLoops.cpp
@@ -81,8 +81,8 @@ FunctionPass *llvm::createHexagonFixupHwLoops() {
/// \brief Returns true if the instruction is a hardware loop instruction.
static bool isHardwareLoop(const MachineInstr *MI) {
- return MI->getOpcode() == Hexagon::LOOP0_r ||
- MI->getOpcode() == Hexagon::LOOP0_i;
+ return MI->getOpcode() == Hexagon::J2_loop0r ||
+ MI->getOpcode() == Hexagon::J2_loop0i;
}
@@ -160,7 +160,7 @@ bool HexagonFixupHwLoops::fixupLoopInstrs(MachineFunction &MF) {
void HexagonFixupHwLoops::convertLoopInstr(MachineFunction &MF,
MachineBasicBlock::iterator &MII,
RegScavenger &RS) {
- const TargetInstrInfo *TII = MF.getTarget().getInstrInfo();
+ const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
MachineBasicBlock *MBB = MII->getParent();
DebugLoc DL = MII->getDebugLoc();
unsigned Scratch = RS.scavengeRegister(&Hexagon::IntRegsRegClass, MII, 0);
@@ -168,18 +168,18 @@ void HexagonFixupHwLoops::convertLoopInstr(MachineFunction &MF,
// First, set the LC0 with the trip count.
if (MII->getOperand(1).isReg()) {
// Trip count is a register
- BuildMI(*MBB, MII, DL, TII->get(Hexagon::TFCR), Hexagon::LC0)
+ BuildMI(*MBB, MII, DL, TII->get(Hexagon::A2_tfrrcr), Hexagon::LC0)
.addReg(MII->getOperand(1).getReg());
} else {
// Trip count is an immediate.
- BuildMI(*MBB, MII, DL, TII->get(Hexagon::TFRI), Scratch)
+ BuildMI(*MBB, MII, DL, TII->get(Hexagon::A2_tfrsi), Scratch)
.addImm(MII->getOperand(1).getImm());
- BuildMI(*MBB, MII, DL, TII->get(Hexagon::TFCR), Hexagon::LC0)
+ BuildMI(*MBB, MII, DL, TII->get(Hexagon::A2_tfrrcr), Hexagon::LC0)
.addReg(Scratch);
}
// Then, set the SA0 with the loop start address.
BuildMI(*MBB, MII, DL, TII->get(Hexagon::CONST32_Label), Scratch)
.addMBB(MII->getOperand(0).getMBB());
- BuildMI(*MBB, MII, DL, TII->get(Hexagon::TFCR), Hexagon::SA0)
+ BuildMI(*MBB, MII, DL, TII->get(Hexagon::A2_tfrrcr), Hexagon::SA0)
.addReg(Scratch);
}
diff --git a/lib/Target/Hexagon/HexagonFrameLowering.cpp b/lib/Target/Hexagon/HexagonFrameLowering.cpp
index 21df12faefae..9d1a527eddb3 100644
--- a/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -50,7 +50,10 @@ void HexagonFrameLowering::determineFrameLayout(MachineFunction &MF) const {
unsigned FrameSize = MFI->getStackSize();
// Get the alignments provided by the target.
- unsigned TargetAlign = MF.getTarget().getFrameLowering()->getStackAlignment();
+ unsigned TargetAlign = MF.getTarget()
+ .getSubtargetImpl()
+ ->getFrameLowering()
+ ->getStackAlignment();
// Get the maximum call frame size of all the calls.
unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
@@ -77,8 +80,8 @@ void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front();
MachineFrameInfo *MFI = MF.getFrameInfo();
MachineBasicBlock::iterator MBBI = MBB.begin();
- const HexagonRegisterInfo *QRI =
- static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo());
+ const HexagonRegisterInfo *QRI = static_cast<const HexagonRegisterInfo *>(
+ MF.getSubtarget().getRegisterInfo());
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
determineFrameLayout(MF);
@@ -115,21 +118,21 @@ void HexagonFrameLowering::emitPrologue(MachineFunction &MF) const {
// Check for overflow.
// Hexagon_TODO: Ugh! hardcoding. Is there an API that can be used?
const int ALLOCFRAME_MAX = 16384;
- const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
+ const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
if (NumBytes >= ALLOCFRAME_MAX) {
// Emit allocframe(#0).
- BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(0);
+ BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::S2_allocframe)).addImm(0);
// Subtract offset from frame pointer.
BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::CONST32_Int_Real),
HEXAGON_RESERVED_REG_1).addImm(NumBytes);
- BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::SUB_rr),
+ BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::A2_sub),
QRI->getStackRegister()).
addReg(QRI->getStackRegister()).
addReg(HEXAGON_RESERVED_REG_1);
} else {
- BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::ALLOCFRAME)).addImm(NumBytes);
+ BuildMI(MBB, InsertPt, dl, TII.get(Hexagon::S2_allocframe)).addImm(NumBytes);
}
}
}
@@ -154,12 +157,12 @@ void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock::iterator MBBI = std::prev(MBB.end());
MachineBasicBlock::iterator MBBI_end = MBB.end();
- const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo();
+ const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
// Handle EH_RETURN.
if (MBBI->getOpcode() == Hexagon::EH_RETURN_JMPR) {
assert(MBBI->getOperand(0).isReg() && "Offset should be in register!");
- BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME));
- BuildMI(MBB, MBBI, dl, TII.get(Hexagon::ADD_rr),
+ BuildMI(MBB, MBBI, dl, TII.get(Hexagon::L2_deallocframe));
+ BuildMI(MBB, MBBI, dl, TII.get(Hexagon::A2_add),
Hexagon::R29).addReg(Hexagon::R29).addReg(Hexagon::R28);
return;
}
@@ -180,7 +183,7 @@ void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
// Add dealloc_return.
MachineInstrBuilder MIB =
- BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::DEALLOC_RET_V4));
+ BuildMI(MBB, MBBI_end, dl, TII.get(Hexagon::L4_return));
// Transfer the function live-out registers.
MIB->copyImplicitOps(*MBB.getParent(), &*MBBI);
// Remove the JUMPR node.
@@ -195,7 +198,7 @@ void HexagonFrameLowering::emitEpilogue(MachineFunction &MF,
I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4)
return;
- BuildMI(MBB, MBBI, dl, TII.get(Hexagon::DEALLOCFRAME));
+ BuildMI(MBB, MBBI, dl, TII.get(Hexagon::L2_deallocframe));
}
}
}
@@ -225,7 +228,7 @@ HexagonFrameLowering::spillCalleeSavedRegisters(
const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const {
MachineFunction *MF = MBB.getParent();
- const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
+ const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
if (CSI.empty()) {
return false;
@@ -280,7 +283,7 @@ bool HexagonFrameLowering::restoreCalleeSavedRegisters(
const TargetRegisterInfo *TRI) const {
MachineFunction *MF = MBB.getParent();
- const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo();
+ const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
if (CSI.empty()) {
return false;
diff --git a/lib/Target/Hexagon/HexagonFrameLowering.h b/lib/Target/Hexagon/HexagonFrameLowering.h
index 2d4b0b9d7eb3..2d6b45793809 100644
--- a/lib/Target/Hexagon/HexagonFrameLowering.h
+++ b/lib/Target/Hexagon/HexagonFrameLowering.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef HEXAGON_FRAMEINFO_H
-#define HEXAGON_FRAMEINFO_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONFRAMELOWERING_H
+#define LLVM_LIB_TARGET_HEXAGON_HEXAGONFRAMELOWERING_H
#include "Hexagon.h"
#include "llvm/Target/TargetFrameLowering.h"
diff --git a/lib/Target/Hexagon/HexagonHardwareLoops.cpp b/lib/Target/Hexagon/HexagonHardwareLoops.cpp
index 7f76421ac3e0..637b0a0d0bff 100644
--- a/lib/Target/Hexagon/HexagonHardwareLoops.cpp
+++ b/lib/Target/Hexagon/HexagonHardwareLoops.cpp
@@ -220,7 +220,7 @@ namespace {
int HexagonHardwareLoops::Counter = 0;
#endif
- /// \brief Abstraction for a trip count of a loop. A smaller vesrsion
+ /// \brief Abstraction for a trip count of a loop. A smaller version
/// of the MachineOperand class without the concerns of changing the
/// operand representation.
class CountValue {
@@ -266,7 +266,8 @@ namespace {
}
void print(raw_ostream &OS, const TargetMachine *TM = nullptr) const {
- const TargetRegisterInfo *TRI = TM ? TM->getRegisterInfo() : nullptr;
+ const TargetRegisterInfo *TRI =
+ TM ? TM->getSubtargetImpl()->getRegisterInfo() : nullptr;
if (isReg()) { OS << PrintReg(Contents.R.Reg, TRI, Contents.R.Sub); }
if (isImm()) { OS << Contents.ImmVal; }
}
@@ -284,8 +285,8 @@ INITIALIZE_PASS_END(HexagonHardwareLoops, "hwloops",
/// \brief Returns true if the instruction is a hardware loop instruction.
static bool isHardwareLoop(const MachineInstr *MI) {
- return MI->getOpcode() == Hexagon::LOOP0_r ||
- MI->getOpcode() == Hexagon::LOOP0_i;
+ return MI->getOpcode() == Hexagon::J2_loop0r ||
+ MI->getOpcode() == Hexagon::J2_loop0i;
}
FunctionPass *llvm::createHexagonHardwareLoops() {
@@ -302,8 +303,10 @@ bool HexagonHardwareLoops::runOnMachineFunction(MachineFunction &MF) {
MRI = &MF.getRegInfo();
MDT = &getAnalysis<MachineDominatorTree>();
TM = static_cast<const HexagonTargetMachine*>(&MF.getTarget());
- TII = static_cast<const HexagonInstrInfo*>(TM->getInstrInfo());
- TRI = static_cast<const HexagonRegisterInfo*>(TM->getRegisterInfo());
+ TII = static_cast<const HexagonInstrInfo *>(
+ TM->getSubtargetImpl()->getInstrInfo());
+ TRI = static_cast<const HexagonRegisterInfo *>(
+ TM->getSubtargetImpl()->getRegisterInfo());
for (MachineLoopInfo::iterator I = MLI->begin(), E = MLI->end();
I != E; ++I) {
@@ -537,16 +540,16 @@ CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L,
return nullptr;
switch (CondOpc) {
- case Hexagon::CMPEQri:
- case Hexagon::CMPEQrr:
+ case Hexagon::C2_cmpeqi:
+ case Hexagon::C2_cmpeq:
Cmp = !Negated ? Comparison::EQ : Comparison::NE;
break;
- case Hexagon::CMPGTUri:
- case Hexagon::CMPGTUrr:
+ case Hexagon::C2_cmpgtui:
+ case Hexagon::C2_cmpgtu:
Cmp = !Negated ? Comparison::GTu : Comparison::LEu;
break;
- case Hexagon::CMPGTri:
- case Hexagon::CMPGTrr:
+ case Hexagon::C2_cmpgti:
+ case Hexagon::C2_cmpgt:
Cmp = !Negated ? Comparison::GTs : Comparison::LEs;
break;
// Very limited support for byte/halfword compares.
@@ -623,12 +626,12 @@ CountValue *HexagonHardwareLoops::computeCount(MachineLoop *Loop,
// If so, use the immediate value rather than the register.
if (Start->isReg()) {
const MachineInstr *StartValInstr = MRI->getVRegDef(Start->getReg());
- if (StartValInstr && StartValInstr->getOpcode() == Hexagon::TFRI)
+ if (StartValInstr && StartValInstr->getOpcode() == Hexagon::A2_tfrsi)
Start = &StartValInstr->getOperand(1);
}
if (End->isReg()) {
const MachineInstr *EndValInstr = MRI->getVRegDef(End->getReg());
- if (EndValInstr && EndValInstr->getOpcode() == Hexagon::TFRI)
+ if (EndValInstr && EndValInstr->getOpcode() == Hexagon::A2_tfrsi)
End = &EndValInstr->getOperand(1);
}
@@ -778,7 +781,7 @@ CountValue *HexagonHardwareLoops::computeCount(MachineLoop *Loop,
DistR = End->getReg();
DistSR = End->getSubReg();
} else {
- const MCInstrDesc &SubD = RegToReg ? TII->get(Hexagon::SUB_rr) :
+ const MCInstrDesc &SubD = RegToReg ? TII->get(Hexagon::A2_sub) :
(RegToImm ? TII->get(Hexagon::SUB_ri) :
TII->get(Hexagon::ADD_ri));
unsigned SubR = MRI->createVirtualRegister(IntRC);
@@ -829,7 +832,7 @@ CountValue *HexagonHardwareLoops::computeCount(MachineLoop *Loop,
// Generate NormR = LSR DistR, Shift.
unsigned LsrR = MRI->createVirtualRegister(IntRC);
- const MCInstrDesc &LsrD = TII->get(Hexagon::LSR_ri);
+ const MCInstrDesc &LsrD = TII->get(Hexagon::S2_lsr_i_r);
BuildMI(*PH, InsertPos, DL, LsrD, LsrR)
.addReg(AdjR, 0, AdjSR)
.addImm(Shift);
@@ -1083,7 +1086,7 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) {
BuildMI(*Preheader, InsertPos, DL, TII->get(TargetOpcode::COPY), CountReg)
.addReg(TripCount->getReg(), 0, TripCount->getSubReg());
// Add the Loop instruction to the beginning of the loop.
- BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::LOOP0_r))
+ BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::J2_loop0r))
.addMBB(LoopStart)
.addReg(CountReg);
} else {
@@ -1092,14 +1095,14 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) {
// if the immediate fits in the instructions. Otherwise, we need to
// create a new virtual register.
int64_t CountImm = TripCount->getImm();
- if (!TII->isValidOffset(Hexagon::LOOP0_i, CountImm)) {
+ if (!TII->isValidOffset(Hexagon::J2_loop0i, CountImm)) {
unsigned CountReg = MRI->createVirtualRegister(&Hexagon::IntRegsRegClass);
- BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::TFRI), CountReg)
+ BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::A2_tfrsi), CountReg)
.addImm(CountImm);
- BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::LOOP0_r))
+ BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::J2_loop0r))
.addMBB(LoopStart).addReg(CountReg);
} else
- BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::LOOP0_i))
+ BuildMI(*Preheader, InsertPos, DL, TII->get(Hexagon::J2_loop0i))
.addMBB(LoopStart).addImm(CountImm);
}
@@ -1119,8 +1122,8 @@ bool HexagonHardwareLoops::convertToHardwareLoop(MachineLoop *L) {
// The loop ends with either:
// - a conditional branch followed by an unconditional branch, or
// - a conditional branch to the loop start.
- if (LastI->getOpcode() == Hexagon::JMP_t ||
- LastI->getOpcode() == Hexagon::JMP_f) {
+ if (LastI->getOpcode() == Hexagon::J2_jumpt ||
+ LastI->getOpcode() == Hexagon::J2_jumpf) {
// Delete one and change/add an uncond. branch to out of the loop.
MachineBasicBlock *BranchTarget = LastI->getOperand(1).getMBB();
LastI = LastMBB->erase(LastI);
@@ -1191,8 +1194,8 @@ MachineInstr *HexagonHardwareLoops::defWithImmediate(unsigned R) {
MachineInstr *DI = MRI->getVRegDef(R);
unsigned DOpc = DI->getOpcode();
switch (DOpc) {
- case Hexagon::TFRI:
- case Hexagon::TFRI64:
+ case Hexagon::A2_tfrsi:
+ case Hexagon::A2_tfrpi:
case Hexagon::CONST32_Int_Real:
case Hexagon::CONST64_Int_Real:
return DI;
diff --git a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
index dabe650a5b70..ea3a1770ac31 100644
--- a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
+++ b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
@@ -320,38 +320,38 @@ static unsigned doesIntrinsicContainPredicate(unsigned ID)
default:
return 0;
case Intrinsic::hexagon_C2_tfrpr:
- return Hexagon::TFR_RsPd;
+ return Hexagon::C2_tfrpr;
case Intrinsic::hexagon_C2_and:
- return Hexagon::AND_pp;
+ return Hexagon::C2_and;
case Intrinsic::hexagon_C2_xor:
- return Hexagon::XOR_pp;
+ return Hexagon::C2_xor;
case Intrinsic::hexagon_C2_or:
- return Hexagon::OR_pp;
+ return Hexagon::C2_or;
case Intrinsic::hexagon_C2_not:
- return Hexagon::NOT_p;
+ return Hexagon::C2_not;
case Intrinsic::hexagon_C2_any8:
- return Hexagon::ANY_pp;
+ return Hexagon::C2_any8;
case Intrinsic::hexagon_C2_all8:
- return Hexagon::ALL_pp;
+ return Hexagon::C2_all8;
case Intrinsic::hexagon_C2_vitpack:
- return Hexagon::VITPACK_pp;
+ return Hexagon::C2_vitpack;
case Intrinsic::hexagon_C2_mask:
- return Hexagon::MASK_p;
+ return Hexagon::C2_mask;
case Intrinsic::hexagon_C2_mux:
- return Hexagon::MUX_rr;
+ return Hexagon::C2_mux;
// Mapping hexagon_C2_muxir to MUX_pri. This is pretty weird - but
// that's how it's mapped in q6protos.h.
case Intrinsic::hexagon_C2_muxir:
- return Hexagon::MUX_ri;
+ return Hexagon::C2_muxri;
// Mapping hexagon_C2_muxri to MUX_pir. This is pretty weird - but
// that's how it's mapped in q6protos.h.
case Intrinsic::hexagon_C2_muxri:
- return Hexagon::MUX_ir;
+ return Hexagon::C2_muxir;
case Intrinsic::hexagon_C2_muxii:
- return Hexagon::MUX_ii;
+ return Hexagon::C2_muxii;
case Intrinsic::hexagon_C2_vmux:
return Hexagon::VMUX_prr64;
case Intrinsic::hexagon_S2_valignrb:
@@ -404,10 +404,10 @@ SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, SDLoc dl) {
dl, PointerTy,
TargAddr);
// Figure out base + offset opcode
- if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed;
- else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed;
- else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed;
- else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed;
+ if (LoadedVT == MVT::i64) Opcode = Hexagon::L2_loadrd_io;
+ else if (LoadedVT == MVT::i32) Opcode = Hexagon::L2_loadri_io;
+ else if (LoadedVT == MVT::i16) Opcode = Hexagon::L2_loadrh_io;
+ else if (LoadedVT == MVT::i8) Opcode = Hexagon::L2_loadrb_io;
else llvm_unreachable("unknown memory type");
// Build indexed load.
@@ -446,14 +446,14 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
N1.getNode()->getValueType(0) == MVT::i32) {
- const HexagonInstrInfo *TII =
- static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
+ const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
+ TM.getSubtargetImpl()->getInstrInfo());
if (TII->isValidAutoIncImm(LoadedVT, Val)) {
SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
MVT::Other, Base, TargetConst,
Chain);
- SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64,
+ SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_sxtw, dl, MVT::i64,
SDValue(Result_1, 0));
MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
MemOp[0] = LD->getMemOperand();
@@ -474,7 +474,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
MVT::Other, Base, TargetConst0,
Chain);
- SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl,
+ SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_sxtw, dl,
MVT::i64, SDValue(Result_1, 0));
SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
MVT::i32, Base, TargetConstVal,
@@ -513,17 +513,17 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
N1.getNode()->getValueType(0) == MVT::i32) {
- const HexagonInstrInfo *TII =
- static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
+ const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
+ TM.getSubtargetImpl()->getInstrInfo());
if (TII->isValidAutoIncImm(LoadedVT, Val)) {
SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
MVT::i32, MVT::Other, Base,
TargetConstVal, Chain);
- SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
+ SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
TargetConst0);
- SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
+ SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
MVT::i64, MVT::Other,
SDValue(Result_2,0),
SDValue(Result_1,0));
@@ -548,9 +548,9 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
MVT::Other,
Base, TargetConst0, Chain);
- SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
+ SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
TargetConst0);
- SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
+ SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
MVT::i64, MVT::Other,
SDValue(Result_2,0),
SDValue(Result_1,0));
@@ -591,28 +591,28 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, SDLoc dl) {
bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
// Figure out the opcode.
- const HexagonInstrInfo *TII =
- static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
+ const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
+ TM.getSubtargetImpl()->getInstrInfo());
if (LoadedVT == MVT::i64) {
if (TII->isValidAutoIncImm(LoadedVT, Val))
- Opcode = Hexagon::POST_LDrid;
+ Opcode = Hexagon::L2_loadrd_pi;
else
- Opcode = Hexagon::LDrid;
+ Opcode = Hexagon::L2_loadrd_io;
} else if (LoadedVT == MVT::i32) {
if (TII->isValidAutoIncImm(LoadedVT, Val))
- Opcode = Hexagon::POST_LDriw;
+ Opcode = Hexagon::L2_loadri_pi;
else
- Opcode = Hexagon::LDriw;
+ Opcode = Hexagon::L2_loadri_io;
} else if (LoadedVT == MVT::i16) {
if (TII->isValidAutoIncImm(LoadedVT, Val))
- Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih;
+ Opcode = zextval ? Hexagon::L2_loadruh_pi : Hexagon::L2_loadrh_pi;
else
- Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih;
+ Opcode = zextval ? Hexagon::L2_loadruh_io : Hexagon::L2_loadrh_io;
} else if (LoadedVT == MVT::i8) {
if (TII->isValidAutoIncImm(LoadedVT, Val))
- Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib;
+ Opcode = zextval ? Hexagon::L2_loadrub_pi : Hexagon::L2_loadrb_pi;
else
- Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib;
+ Opcode = zextval ? Hexagon::L2_loadrub_io : Hexagon::L2_loadrb_io;
} else
llvm_unreachable("unknown memory type");
@@ -701,18 +701,18 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
// Offset value must be within representable range
// and must have correct alignment properties.
- const HexagonInstrInfo *TII =
- static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
+ const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
+ TM.getSubtargetImpl()->getInstrInfo());
if (TII->isValidAutoIncImm(StoredVT, Val)) {
SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
Chain};
unsigned Opcode = 0;
// Figure out the post inc version of opcode.
- if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri;
- else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri;
- else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri;
- else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri;
+ if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_pi;
+ else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_pi;
+ else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_pi;
+ else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_pi;
else llvm_unreachable("unknown memory type");
// Build post increment store.
@@ -735,10 +735,10 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, SDLoc dl) {
unsigned Opcode = 0;
// Figure out the opcode.
- if (StoredVT == MVT::i64) Opcode = Hexagon::STrid;
- else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
- else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih;
- else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib;
+ if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_io;
+ else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_io;
+ else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_io;
+ else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_io;
else llvm_unreachable("unknown memory type");
// Build regular store.
@@ -788,10 +788,10 @@ SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
TargAddr);
// Figure out base + offset opcode
- if (StoredVT == MVT::i64) Opcode = Hexagon::STrid_indexed;
- else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
- else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed;
- else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed;
+ if (StoredVT == MVT::i64) Opcode = Hexagon::S2_storerd_io;
+ else if (StoredVT == MVT::i32) Opcode = Hexagon::S2_storeri_io;
+ else if (StoredVT == MVT::i16) Opcode = Hexagon::S2_storerh_io;
+ else if (StoredVT == MVT::i8) Opcode = Hexagon::S2_storerb_io;
else llvm_unreachable("unknown memory type");
SDValue Ops[] = {SDValue(NewBase,0),
@@ -865,7 +865,7 @@ SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
SDValue Chain = LD->getChain();
SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
- OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
+ OP0 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
MVT::Other,
LD->getBasePtr(), TargetConst0,
Chain), 0);
@@ -891,7 +891,7 @@ SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
SDValue Chain = LD->getChain();
SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
- OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
+ OP1 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
MVT::Other,
LD->getBasePtr(), TargetConst0,
Chain), 0);
@@ -900,7 +900,7 @@ SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
}
// Generate a mpy instruction.
- SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY64, dl, MVT::i64,
+ SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_dpmpyss_s0, dl, MVT::i64,
OP0, OP1);
ReplaceUses(N, Result);
return Result;
@@ -934,9 +934,9 @@ SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
if (N000 == N2 &&
N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
- SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
+ SDNode *SextNode = CurDAG->getMachineNode(Hexagon::A2_sxth, dl,
MVT::i32, N000);
- SDNode *Result = CurDAG->getMachineNode(Hexagon::MAXw_rr, dl,
+ SDNode *Result = CurDAG->getMachineNode(Hexagon::A2_max, dl,
MVT::i32,
SDValue(SextNode, 0),
N1);
@@ -958,9 +958,9 @@ SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
if (N000 == N2 &&
N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
- SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
+ SDNode *SextNode = CurDAG->getMachineNode(Hexagon::A2_sxth, dl,
MVT::i32, N000);
- SDNode *Result = CurDAG->getMachineNode(Hexagon::MINw_rr, dl,
+ SDNode *Result = CurDAG->getMachineNode(Hexagon::A2_min, dl,
MVT::i32,
SDValue(SextNode, 0),
N1);
@@ -1045,7 +1045,7 @@ SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
SDValue Chain = LD->getChain();
SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
- OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
+ OP0 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
MVT::Other,
LD->getBasePtr(),
TargetConst0, Chain), 0);
@@ -1070,7 +1070,7 @@ SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
SDValue Chain = LD->getChain();
SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
- OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
+ OP1 = SDValue(CurDAG->getMachineNode(Hexagon::L2_loadri_io, dl, MVT::i32,
MVT::Other,
LD->getBasePtr(),
TargetConst0, Chain), 0);
@@ -1079,7 +1079,7 @@ SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
}
// Generate a mpy instruction.
- SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY, dl, MVT::i32,
+ SDNode *Result = CurDAG->getMachineNode(Hexagon::M2_mpy_up, dl, MVT::i32,
OP0, OP1);
ReplaceUses(N, Result);
return Result;
@@ -1112,7 +1112,7 @@ SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
if (isInt<9>(CN->getSExtValue())) {
SDNode* Result =
- CurDAG->getMachineNode(Hexagon::MPYI_ri, dl,
+ CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl,
MVT::i32, Mul_0, Val);
ReplaceUses(N, Result);
return Result;
@@ -1140,7 +1140,7 @@ SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
dyn_cast<ConstantSDNode>(Val.getNode()))
if (isInt<9>(CN->getSExtValue())) {
SDNode* Result =
- CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, MVT::i32,
+ CurDAG->getMachineNode(Hexagon::M2_mpysmi, dl, MVT::i32,
Shl2_0, Val);
ReplaceUses(N, Result);
return Result;
@@ -1177,13 +1177,13 @@ SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
if (N->getValueType(0) == MVT::i64) {
// Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
- SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
+ SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
MVT::i32,
SDValue(IsIntrinsic, 0));
- SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl,
+ SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl,
MVT::i32,
TargetConst0);
- SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
+ SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::A2_combinew, dl,
MVT::i64, MVT::Other,
SDValue(Result_2, 0),
SDValue(Result_1, 0));
@@ -1192,7 +1192,7 @@ SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
}
if (N->getValueType(0) == MVT::i32) {
// Convert the zero_extend to Rs = Pd
- SDNode* RsPd = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
+ SDNode* RsPd = CurDAG->getMachineNode(Hexagon::C2_tfrpr, dl,
MVT::i32,
SDValue(IsIntrinsic, 0));
ReplaceUses(N, RsPd);
@@ -1218,10 +1218,10 @@ SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
// as at least one of the operands.
if (IntrinsicWithPred) {
SmallVector<SDValue, 8> Ops;
- const HexagonInstrInfo *TII =
- static_cast<const HexagonInstrInfo*>(TM.getInstrInfo());
+ const HexagonInstrInfo *TII = static_cast<const HexagonInstrInfo *>(
+ TM.getSubtargetImpl()->getInstrInfo());
const MCInstrDesc &MCID = TII->get(IntrinsicWithPred);
- const TargetRegisterInfo *TRI = TM.getRegisterInfo();
+ const TargetRegisterInfo *TRI = TM.getSubtargetImpl()->getRegisterInfo();
// Iterate over all the operands of the intrinsics.
// For PredRegs, do the transfer.
@@ -1236,7 +1236,7 @@ SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
Ops.push_back(SDValue(Arg, 0));
} else if (RC == &Hexagon::PredRegsRegClass) {
// Do the transfer.
- SDNode *PdRs = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
+ SDNode *PdRs = CurDAG->getMachineNode(Hexagon::C2_tfrrp, dl, MVT::i1,
SDValue(Arg, 0));
Ops.push_back(SDValue(PdRs,0));
} else if (!RC && (dyn_cast<ConstantSDNode>(Arg) != nullptr)) {
@@ -1289,19 +1289,19 @@ SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
if (Val == -1) {
// Create the IntReg = 1 node.
SDNode* IntRegTFR =
- CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
+ CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::i32,
CurDAG->getTargetConstant(0, MVT::i32));
// Pd = IntReg
- SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
+ SDNode* Pd = CurDAG->getMachineNode(Hexagon::C2_tfrrp, dl, MVT::i1,
SDValue(IntRegTFR, 0));
// not(Pd)
- SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1,
+ SDNode* NotPd = CurDAG->getMachineNode(Hexagon::C2_not, dl, MVT::i1,
SDValue(Pd, 0));
// xor(not(Pd))
- Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1,
+ Result = CurDAG->getMachineNode(Hexagon::C2_xor, dl, MVT::i1,
SDValue(Pd, 0), SDValue(NotPd, 0));
// We have just built:
@@ -1334,7 +1334,7 @@ SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
// Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
// Rd and Rd' are assigned to the same register
- SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_ADD_rr, dl, MVT::i32,
+ SDNode* Result = CurDAG->getMachineNode(Hexagon::S2_asr_r_r_acc, dl, MVT::i32,
N->getOperand(1),
Src1->getOperand(0),
Src1->getOperand(1));
diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp
index a460ea4f3420..ef5d6b97fd6f 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -51,9 +51,9 @@ class HexagonCCState : public CCState {
public:
HexagonCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF,
- const TargetMachine &TM, SmallVectorImpl<CCValAssign> &locs,
- LLVMContext &C, int NumNamedVarArgParams)
- : CCState(CC, isVarArg, MF, TM, locs, C),
+ SmallVectorImpl<CCValAssign> &locs, LLVMContext &C,
+ int NumNamedVarArgParams)
+ : CCState(CC, isVarArg, MF, locs, C),
NumNamedVarArgParams(NumNamedVarArgParams) {}
int getNumNamedVarArgParams() const { return NumNamedVarArgParams; }
@@ -322,8 +322,8 @@ HexagonTargetLowering::LowerReturn(SDValue Chain,
SmallVector<CCValAssign, 16> RVLocs;
// CCState - Info about the registers and stack slot.
- CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
- getTargetMachine(), RVLocs, *DAG.getContext());
+ CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
+ *DAG.getContext());
// Analyze return values of ISD::RET
CCInfo.AnalyzeReturn(Outs, RetCC_Hexagon);
@@ -372,8 +372,8 @@ HexagonTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag,
// Assign locations to each value returned by this call.
SmallVector<CCValAssign, 16> RVLocs;
- CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
- getTargetMachine(), RVLocs, *DAG.getContext());
+ CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), RVLocs,
+ *DAG.getContext());
CCInfo.AnalyzeCallResult(Ins, RetCC_Hexagon);
@@ -427,9 +427,8 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
- HexagonCCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
- getTargetMachine(), ArgLocs, *DAG.getContext(),
- NumNamedVarArgParams);
+ HexagonCCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
+ *DAG.getContext(), NumNamedVarArgParams);
if (NumNamedVarArgParams > 0)
CCInfo.AnalyzeCallOperands(Outs, CC_Hexagon_VarArg);
@@ -464,7 +463,7 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVector<SDValue, 8> MemOpChains;
const HexagonRegisterInfo *QRI = static_cast<const HexagonRegisterInfo *>(
- DAG.getTarget().getRegisterInfo());
+ DAG.getSubtarget().getRegisterInfo());
SDValue StackPtr =
DAG.getCopyFromReg(Chain, dl, QRI->getStackRegister(), getPointerTy());
@@ -723,7 +722,7 @@ SDValue HexagonTargetLowering::LowerINLINEASM(SDValue Op,
// Check it to be lr
const HexagonRegisterInfo *QRI =
static_cast<const HexagonRegisterInfo *>(
- DAG.getTarget().getRegisterInfo());
+ DAG.getSubtarget().getRegisterInfo());
if (Reg == QRI->getRARegister()) {
FuncInfo->setHasClobberLR(true);
break;
@@ -817,7 +816,7 @@ HexagonTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
// The Sub result contains the new stack start address, so it
// must be placed in the stack pointer register.
const HexagonRegisterInfo *QRI = static_cast<const HexagonRegisterInfo *>(
- DAG.getTarget().getRegisterInfo());
+ DAG.getSubtarget().getRegisterInfo());
SDValue CopyChain = DAG.getCopyToReg(Chain, dl, QRI->getStackRegister(), Sub);
SDValue Ops[2] = { ArgAdjust, CopyChain };
@@ -843,8 +842,8 @@ const {
// Assign locations to all of the incoming arguments.
SmallVector<CCValAssign, 16> ArgLocs;
- CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
- getTargetMachine(), ArgLocs, *DAG.getContext());
+ CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs,
+ *DAG.getContext());
CCInfo.AnalyzeFormalArguments(Ins, CC_Hexagon);
@@ -964,7 +963,7 @@ HexagonTargetLowering::LowerConstantPool(SDValue Op, SelectionDAG &DAG) const {
SDValue
HexagonTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const {
- const TargetRegisterInfo *TRI = DAG.getTarget().getRegisterInfo();
+ const TargetRegisterInfo *TRI = DAG.getSubtarget().getRegisterInfo();
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo *MFI = MF.getFrameInfo();
MFI->setReturnAddressIsTaken(true);
@@ -990,8 +989,8 @@ HexagonTargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const {
SDValue
HexagonTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
- const HexagonRegisterInfo *TRI =
- static_cast<const HexagonRegisterInfo *>(DAG.getTarget().getRegisterInfo());
+ const HexagonRegisterInfo *TRI = static_cast<const HexagonRegisterInfo *>(
+ DAG.getSubtarget().getRegisterInfo());
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
MFI->setFrameAddressIsTaken(true);
@@ -1044,7 +1043,7 @@ HexagonTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const {
//===----------------------------------------------------------------------===//
HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &targetmachine)
- : TargetLowering(targetmachine, new HexagonTargetObjectFile()),
+ : TargetLowering(targetmachine),
TM(targetmachine) {
const HexagonSubtarget &Subtarget = TM.getSubtarget<HexagonSubtarget>();
@@ -1302,9 +1301,11 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &targetmachine)
setOperationAction(ISD::BUILD_PAIR, MVT::i64, Expand);
// Turn FP extload into load/fextend.
- setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
+ for (MVT VT : MVT::fp_valuetypes())
+ setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand);
// Hexagon has a i1 sign extending load.
- setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Expand);
+ for (MVT VT : MVT::integer_valuetypes())
+ setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Expand);
// Turn FP truncstore into trunc + store.
setTruncStoreAction(MVT::f64, MVT::f32, Expand);
@@ -1453,8 +1454,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &targetmachine)
setMinFunctionAlignment(2);
// Needed for DYNAMIC_STACKALLOC expansion.
- const HexagonRegisterInfo *QRI =
- static_cast<const HexagonRegisterInfo *>(TM.getRegisterInfo());
+ const HexagonRegisterInfo *QRI = static_cast<const HexagonRegisterInfo *>(
+ TM.getSubtargetImpl()->getRegisterInfo());
setStackPointerRegisterToSaveRestore(QRI->getStackRegister());
setSchedulingPreference(Sched::VLIW);
}
@@ -1706,3 +1707,17 @@ bool HexagonTargetLowering::IsEligibleForTailCallOptimization(
// information is not available.
return true;
}
+
+// Return true when the given node fits in a positive half word.
+bool llvm::isPositiveHalfWord(SDNode *N) {
+ ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N);
+ if (CN && CN->getSExtValue() > 0 && isInt<16>(CN->getSExtValue()))
+ return true;
+
+ switch (N->getOpcode()) {
+ default:
+ return false;
+ case ISD::SIGN_EXTEND_INREG:
+ return true;
+ }
+}
diff --git a/lib/Target/Hexagon/HexagonISelLowering.h b/lib/Target/Hexagon/HexagonISelLowering.h
index ec16cc8f894b..d03b1b8d9f4a 100644
--- a/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/lib/Target/Hexagon/HexagonISelLowering.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef Hexagon_ISELLOWERING_H
-#define Hexagon_ISELLOWERING_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
+#define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H
#include "Hexagon.h"
#include "llvm/CodeGen/CallingConvLower.h"
@@ -21,6 +21,10 @@
#include "llvm/Target/TargetLowering.h"
namespace llvm {
+
+// Return true when the given node fits in a positive half word.
+bool isPositiveHalfWord(SDNode *N);
+
namespace HexagonISD {
enum {
FIRST_NUMBER = ISD::BUILTIN_OP_END,
@@ -48,7 +52,9 @@ namespace llvm {
CALL, // A call instruction.
RET_FLAG, // Return with a flag operand.
BR_JT, // Jump table.
- BARRIER, // Memory barrier.
+ BARRIER, // Memory barrier
+ POPCOUNT,
+ COMBINE,
WrapperJT,
WrapperCP,
WrapperCombineII,
@@ -63,7 +69,8 @@ namespace llvm {
WrapperShuffOB,
WrapperShuffOH,
TC_RETURN,
- EH_RETURN
+ EH_RETURN,
+ DCFETCH
};
}
diff --git a/lib/Target/Hexagon/HexagonInstrFormats.td b/lib/Target/Hexagon/HexagonInstrFormats.td
index 105734349321..8373652c8f64 100644
--- a/lib/Target/Hexagon/HexagonInstrFormats.td
+++ b/lib/Target/Hexagon/HexagonInstrFormats.td
@@ -92,12 +92,18 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
let AsmString = asmstr;
let Pattern = pattern;
let Constraints = cstr;
- let Itinerary = itin;
- let Size = 4;
-
- // *** Must match MCTargetDesc/HexagonBaseInfo.h ***
-
- // Instruction type according to the ISA.
+ let Itinerary = itin;
+ let Size = 4;
+
+ // SoftFail is a field the disassembler can use to provide a way for
+ // instructions to not match without killing the whole decode process. It is
+ // mainly used for ARM, but Tablegen expects this field to exist or it fails
+ // to build the decode table.
+ field bits<32> SoftFail = 0;
+
+ // *** Must match MCTargetDesc/HexagonBaseInfo.h ***
+
+ // Instruction type according to the ISA.
IType Type = type;
let TSFlags{4-0} = Type.Value;
@@ -180,12 +186,13 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
string InputType = ""; // Input is "imm" or "reg" type.
string isMEMri = "false"; // Set to "true" for load/store with MEMri operand.
string isFloat = "false"; // Set to "true" for the floating-point load/store.
- string isBrTaken = ""; // Set to "true"/"false" for jump instructions
+ string isBrTaken = !if(isTaken, "true", "false"); // Set to "true"/"false" for jump instructions
let PredSense = !if(isPredicated, !if(isPredicatedFalse, "false", "true"),
"");
let PNewValue = !if(isPredicatedNew, "new", "");
let NValueST = !if(isNVStore, "true", "false");
+ let isCodeGenOnly = 1;
// *** Must match MCTargetDesc/HexagonBaseInfo.h ***
}
@@ -196,6 +203,7 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
// LD Instruction Class in V2/V3/V4.
// Definition of the instruction class NOT CHANGED.
+let mayLoad = 1 in
class LDInst<dag outs, dag ins, string asmstr, list<dag> pattern = [],
string cstr = "", InstrItinClass itin = LD_tc_ld_SLOT01>
: InstHexagon<outs, ins, asmstr, pattern, cstr, itin, TypeLD>;
diff --git a/lib/Target/Hexagon/HexagonInstrFormatsV4.td b/lib/Target/Hexagon/HexagonInstrFormatsV4.td
index d92f97b0dd2d..5fec80bb570a 100644
--- a/lib/Target/Hexagon/HexagonInstrFormatsV4.td
+++ b/lib/Target/Hexagon/HexagonInstrFormatsV4.td
@@ -19,6 +19,7 @@
def TypeMEMOP : IType<9>;
def TypeNV : IType<10>;
+def TypeCOMPOUND : IType<12>;
def TypePREFIX : IType<30>;
//----------------------------------------------------------------------------//
@@ -65,3 +66,7 @@ let isCodeGenOnly = 1 in
class EXTENDERInst<dag outs, dag ins, string asmstr, list<dag> pattern = []>
: InstHexagon<outs, ins, asmstr, pattern, "", EXTENDER_tc_1_SLOT0123,
TypePREFIX>;
+
+class CJInst<dag outs, dag ins, string asmstr, list<dag> pattern = [],
+ string cstr = "">
+ : InstHexagon<outs, ins, asmstr, pattern, cstr, COMPOUND, TypeCOMPOUND>;
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.cpp b/lib/Target/Hexagon/HexagonInstrInfo.cpp
index 1c95e06c8923..5d962590a705 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.cpp
+++ b/lib/Target/Hexagon/HexagonInstrInfo.cpp
@@ -78,11 +78,11 @@ unsigned HexagonInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
switch (MI->getOpcode()) {
default: break;
- case Hexagon::LDriw:
- case Hexagon::LDrid:
- case Hexagon::LDrih:
- case Hexagon::LDrib:
- case Hexagon::LDriub:
+ case Hexagon::L2_loadri_io:
+ case Hexagon::L2_loadrd_io:
+ case Hexagon::L2_loadrh_io:
+ case Hexagon::L2_loadrb_io:
+ case Hexagon::L2_loadrub_io:
if (MI->getOperand(2).isFI() &&
MI->getOperand(1).isImm() && (MI->getOperand(1).getImm() == 0)) {
FrameIndex = MI->getOperand(2).getIndex();
@@ -103,10 +103,10 @@ unsigned HexagonInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
int &FrameIndex) const {
switch (MI->getOpcode()) {
default: break;
- case Hexagon::STriw:
- case Hexagon::STrid:
- case Hexagon::STrih:
- case Hexagon::STrib:
+ case Hexagon::S2_storeri_io:
+ case Hexagon::S2_storerd_io:
+ case Hexagon::S2_storerh_io:
+ case Hexagon::S2_storerb_io:
if (MI->getOperand(2).isFI() &&
MI->getOperand(1).isImm() && (MI->getOperand(1).getImm() == 0)) {
FrameIndex = MI->getOperand(0).getIndex();
@@ -124,8 +124,8 @@ HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
const SmallVectorImpl<MachineOperand> &Cond,
DebugLoc DL) const{
- int BOpc = Hexagon::JMP;
- int BccOpc = Hexagon::JMP_t;
+ int BOpc = Hexagon::J2_jump;
+ int BccOpc = Hexagon::J2_jumpt;
assert(TBB && "InsertBranch must not be told to insert a fallthrough");
@@ -134,7 +134,7 @@ HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
// If we want to reverse the branch an odd number of times, we want
// JMP_f.
if (!Cond.empty() && Cond[0].isImm() && Cond[0].getImm() == 0) {
- BccOpc = Hexagon::JMP_f;
+ BccOpc = Hexagon::J2_jumpf;
regPos = 1;
}
@@ -213,7 +213,7 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
}
// Delete the JMP if it's equivalent to a fall-through.
- if (AllowModify && I->getOpcode() == Hexagon::JMP &&
+ if (AllowModify && I->getOpcode() == Hexagon::J2_jump &&
MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
DEBUG(dbgs()<< "\nErasing the jump to successor block\n";);
I->eraseFromParent();
@@ -249,7 +249,7 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
// If there is only one terminator instruction, process it.
if (LastInst && !SecondLastInst) {
- if (LastOpcode == Hexagon::JMP) {
+ if (LastOpcode == Hexagon::J2_jump) {
TBB = LastInst->getOperand(0).getMBB();
return false;
}
@@ -274,7 +274,7 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
bool SecLastOpcodeHasNot = PredOpcodeHasNot(SecLastOpcode);
- if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::JMP)) {
+ if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {
TBB = SecondLastInst->getOperand(1).getMBB();
if (SecLastOpcodeHasNot)
Cond.push_back(MachineOperand::CreateImm(0));
@@ -285,7 +285,7 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
// If the block ends with two Hexagon:JMPs, handle it. The second one is not
// executed, so remove it.
- if (SecLastOpcode == Hexagon::JMP && LastOpcode == Hexagon::JMP) {
+ if (SecLastOpcode == Hexagon::J2_jump && LastOpcode == Hexagon::J2_jump) {
TBB = SecondLastInst->getOperand(0).getMBB();
I = LastInst;
if (AllowModify)
@@ -295,7 +295,7 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
// If the block ends with an ENDLOOP, and JMP, handle it.
if (SecLastOpcode == Hexagon::ENDLOOP0 &&
- LastOpcode == Hexagon::JMP) {
+ LastOpcode == Hexagon::J2_jump) {
TBB = SecondLastInst->getOperand(0).getMBB();
Cond.push_back(SecondLastInst->getOperand(0));
FBB = LastInst->getOperand(0).getMBB();
@@ -308,9 +308,9 @@ bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
- int BOpc = Hexagon::JMP;
- int BccOpc = Hexagon::JMP_t;
- int BccOpcNot = Hexagon::JMP_f;
+ int BOpc = Hexagon::J2_jump;
+ int BccOpc = Hexagon::J2_jumpt;
+ int BccOpcNot = Hexagon::J2_jumpf;
MachineBasicBlock::iterator I = MBB.end();
if (I == MBB.begin()) return 0;
@@ -346,15 +346,15 @@ bool HexagonInstrInfo::analyzeCompare(const MachineInstr *MI,
// Set mask and the first source register.
switch (Opc) {
- case Hexagon::CMPEHexagon4rr:
- case Hexagon::CMPEQri:
- case Hexagon::CMPEQrr:
- case Hexagon::CMPGT64rr:
- case Hexagon::CMPGTU64rr:
- case Hexagon::CMPGTUri:
- case Hexagon::CMPGTUrr:
- case Hexagon::CMPGTri:
- case Hexagon::CMPGTrr:
+ case Hexagon::C2_cmpeqp:
+ case Hexagon::C2_cmpeqi:
+ case Hexagon::C2_cmpeq:
+ case Hexagon::C2_cmpgtp:
+ case Hexagon::C2_cmpgtup:
+ case Hexagon::C2_cmpgtui:
+ case Hexagon::C2_cmpgtu:
+ case Hexagon::C2_cmpgti:
+ case Hexagon::C2_cmpgt:
SrcReg = MI->getOperand(1).getReg();
Mask = ~0;
break;
@@ -380,12 +380,12 @@ bool HexagonInstrInfo::analyzeCompare(const MachineInstr *MI,
// Set the value/second source register.
switch (Opc) {
- case Hexagon::CMPEHexagon4rr:
- case Hexagon::CMPEQrr:
- case Hexagon::CMPGT64rr:
- case Hexagon::CMPGTU64rr:
- case Hexagon::CMPGTUrr:
- case Hexagon::CMPGTrr:
+ case Hexagon::C2_cmpeqp:
+ case Hexagon::C2_cmpeq:
+ case Hexagon::C2_cmpgtp:
+ case Hexagon::C2_cmpgtup:
+ case Hexagon::C2_cmpgtu:
+ case Hexagon::C2_cmpgt:
case Hexagon::CMPbEQrr_sbsb_V4:
case Hexagon::CMPbEQrr_ubub_V4:
case Hexagon::CMPbGTUrr_V4:
@@ -397,9 +397,9 @@ bool HexagonInstrInfo::analyzeCompare(const MachineInstr *MI,
SrcReg2 = MI->getOperand(2).getReg();
return true;
- case Hexagon::CMPEQri:
- case Hexagon::CMPGTUri:
- case Hexagon::CMPGTri:
+ case Hexagon::C2_cmpeqi:
+ case Hexagon::C2_cmpgtui:
+ case Hexagon::C2_cmpgti:
case Hexagon::CMPbEQri_V4:
case Hexagon::CMPbGTUri_V4:
case Hexagon::CMPhEQri_V4:
@@ -418,16 +418,16 @@ void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
unsigned DestReg, unsigned SrcReg,
bool KillSrc) const {
if (Hexagon::IntRegsRegClass.contains(SrcReg, DestReg)) {
- BuildMI(MBB, I, DL, get(Hexagon::TFR), DestReg).addReg(SrcReg);
+ BuildMI(MBB, I, DL, get(Hexagon::A2_tfr), DestReg).addReg(SrcReg);
return;
}
if (Hexagon::DoubleRegsRegClass.contains(SrcReg, DestReg)) {
- BuildMI(MBB, I, DL, get(Hexagon::TFR64), DestReg).addReg(SrcReg);
+ BuildMI(MBB, I, DL, get(Hexagon::A2_tfrp), DestReg).addReg(SrcReg);
return;
}
if (Hexagon::PredRegsRegClass.contains(SrcReg, DestReg)) {
// Map Pd = Ps to Pd = or(Ps, Ps).
- BuildMI(MBB, I, DL, get(Hexagon::OR_pp),
+ BuildMI(MBB, I, DL, get(Hexagon::C2_or),
DestReg).addReg(SrcReg).addReg(SrcReg);
return;
}
@@ -436,31 +436,31 @@ void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
// We can have an overlap between single and double reg: r1:0 = r0.
if(SrcReg == RI.getSubReg(DestReg, Hexagon::subreg_loreg)) {
// r1:0 = r0
- BuildMI(MBB, I, DL, get(Hexagon::TFRI), (RI.getSubReg(DestReg,
+ BuildMI(MBB, I, DL, get(Hexagon::A2_tfrsi), (RI.getSubReg(DestReg,
Hexagon::subreg_hireg))).addImm(0);
} else {
// r1:0 = r1 or no overlap.
- BuildMI(MBB, I, DL, get(Hexagon::TFR), (RI.getSubReg(DestReg,
+ BuildMI(MBB, I, DL, get(Hexagon::A2_tfr), (RI.getSubReg(DestReg,
Hexagon::subreg_loreg))).addReg(SrcReg);
- BuildMI(MBB, I, DL, get(Hexagon::TFRI), (RI.getSubReg(DestReg,
+ BuildMI(MBB, I, DL, get(Hexagon::A2_tfrsi), (RI.getSubReg(DestReg,
Hexagon::subreg_hireg))).addImm(0);
}
return;
}
- if (Hexagon::CRRegsRegClass.contains(DestReg) &&
+ if (Hexagon::CtrRegsRegClass.contains(DestReg) &&
Hexagon::IntRegsRegClass.contains(SrcReg)) {
- BuildMI(MBB, I, DL, get(Hexagon::TFCR), DestReg).addReg(SrcReg);
+ BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg).addReg(SrcReg);
return;
}
if (Hexagon::PredRegsRegClass.contains(SrcReg) &&
Hexagon::IntRegsRegClass.contains(DestReg)) {
- BuildMI(MBB, I, DL, get(Hexagon::TFR_RsPd), DestReg).
+ BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg).
addReg(SrcReg, getKillRegState(KillSrc));
return;
}
if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
Hexagon::PredRegsRegClass.contains(DestReg)) {
- BuildMI(MBB, I, DL, get(Hexagon::TFR_PdRs), DestReg).
+ BuildMI(MBB, I, DL, get(Hexagon::C2_tfrrp), DestReg).
addReg(SrcReg, getKillRegState(KillSrc));
return;
}
@@ -488,11 +488,11 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
Align);
if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
- BuildMI(MBB, I, DL, get(Hexagon::STriw))
+ BuildMI(MBB, I, DL, get(Hexagon::S2_storeri_io))
.addFrameIndex(FI).addImm(0)
.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
} else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
- BuildMI(MBB, I, DL, get(Hexagon::STrid))
+ BuildMI(MBB, I, DL, get(Hexagon::S2_storerd_io))
.addFrameIndex(FI).addImm(0)
.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
} else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {
@@ -533,10 +533,10 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
MFI.getObjectSize(FI),
Align);
if (RC == &Hexagon::IntRegsRegClass) {
- BuildMI(MBB, I, DL, get(Hexagon::LDriw), DestReg)
+ BuildMI(MBB, I, DL, get(Hexagon::L2_loadri_io), DestReg)
.addFrameIndex(FI).addImm(0).addMemOperand(MMO);
} else if (RC == &Hexagon::DoubleRegsRegClass) {
- BuildMI(MBB, I, DL, get(Hexagon::LDrid), DestReg)
+ BuildMI(MBB, I, DL, get(Hexagon::L2_loadrd_io), DestReg)
.addFrameIndex(FI).addImm(0).addMemOperand(MMO);
} else if (RC == &Hexagon::PredRegsRegClass) {
BuildMI(MBB, I, DL, get(Hexagon::LDriw_pred), DestReg)
@@ -648,77 +648,67 @@ bool HexagonInstrInfo::isPredicable(MachineInstr *MI) const {
const int Opc = MI->getOpcode();
switch(Opc) {
- case Hexagon::TFRI:
+ case Hexagon::A2_tfrsi:
return isInt<12>(MI->getOperand(1).getImm());
- case Hexagon::STrid:
- case Hexagon::STrid_indexed:
+ case Hexagon::S2_storerd_io:
return isShiftedUInt<6,3>(MI->getOperand(1).getImm());
- case Hexagon::STriw:
- case Hexagon::STriw_indexed:
- case Hexagon::STriw_nv_V4:
+ case Hexagon::S2_storeri_io:
+ case Hexagon::S2_storerinew_io:
return isShiftedUInt<6,2>(MI->getOperand(1).getImm());
- case Hexagon::STrih:
- case Hexagon::STrih_indexed:
- case Hexagon::STrih_nv_V4:
+ case Hexagon::S2_storerh_io:
+ case Hexagon::S2_storerhnew_io:
return isShiftedUInt<6,1>(MI->getOperand(1).getImm());
- case Hexagon::STrib:
- case Hexagon::STrib_indexed:
- case Hexagon::STrib_nv_V4:
+ case Hexagon::S2_storerb_io:
+ case Hexagon::S2_storerbnew_io:
return isUInt<6>(MI->getOperand(1).getImm());
- case Hexagon::LDrid:
- case Hexagon::LDrid_indexed:
+ case Hexagon::L2_loadrd_io:
return isShiftedUInt<6,3>(MI->getOperand(2).getImm());
- case Hexagon::LDriw:
- case Hexagon::LDriw_indexed:
+ case Hexagon::L2_loadri_io:
return isShiftedUInt<6,2>(MI->getOperand(2).getImm());
- case Hexagon::LDrih:
- case Hexagon::LDriuh:
- case Hexagon::LDrih_indexed:
- case Hexagon::LDriuh_indexed:
+ case Hexagon::L2_loadrh_io:
+ case Hexagon::L2_loadruh_io:
return isShiftedUInt<6,1>(MI->getOperand(2).getImm());
- case Hexagon::LDrib:
- case Hexagon::LDriub:
- case Hexagon::LDrib_indexed:
- case Hexagon::LDriub_indexed:
+ case Hexagon::L2_loadrb_io:
+ case Hexagon::L2_loadrub_io:
return isUInt<6>(MI->getOperand(2).getImm());
- case Hexagon::POST_LDrid:
+ case Hexagon::L2_loadrd_pi:
return isShiftedInt<4,3>(MI->getOperand(3).getImm());
- case Hexagon::POST_LDriw:
+ case Hexagon::L2_loadri_pi:
return isShiftedInt<4,2>(MI->getOperand(3).getImm());
- case Hexagon::POST_LDrih:
- case Hexagon::POST_LDriuh:
+ case Hexagon::L2_loadrh_pi:
+ case Hexagon::L2_loadruh_pi:
return isShiftedInt<4,1>(MI->getOperand(3).getImm());
- case Hexagon::POST_LDrib:
- case Hexagon::POST_LDriub:
+ case Hexagon::L2_loadrb_pi:
+ case Hexagon::L2_loadrub_pi:
return isInt<4>(MI->getOperand(3).getImm());
- case Hexagon::STrib_imm_V4:
- case Hexagon::STrih_imm_V4:
- case Hexagon::STriw_imm_V4:
+ case Hexagon::S4_storeirb_io:
+ case Hexagon::S4_storeirh_io:
+ case Hexagon::S4_storeiri_io:
return (isUInt<6>(MI->getOperand(1).getImm()) &&
isInt<6>(MI->getOperand(2).getImm()));
case Hexagon::ADD_ri:
return isInt<8>(MI->getOperand(2).getImm());
- case Hexagon::ASLH:
- case Hexagon::ASRH:
- case Hexagon::SXTB:
- case Hexagon::SXTH:
- case Hexagon::ZXTB:
- case Hexagon::ZXTH:
+ case Hexagon::A2_aslh:
+ case Hexagon::A2_asrh:
+ case Hexagon::A2_sxtb:
+ case Hexagon::A2_sxth:
+ case Hexagon::A2_zxtb:
+ case Hexagon::A2_zxth:
return Subtarget.hasV4TOps();
}
@@ -739,16 +729,16 @@ unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const {
switch(Opc) {
default: llvm_unreachable("Unexpected predicated instruction");
- case Hexagon::COMBINE_rr_cPt:
- return Hexagon::COMBINE_rr_cNotPt;
- case Hexagon::COMBINE_rr_cNotPt:
- return Hexagon::COMBINE_rr_cPt;
+ case Hexagon::C2_ccombinewt:
+ return Hexagon::C2_ccombinewf;
+ case Hexagon::C2_ccombinewf:
+ return Hexagon::C2_ccombinewt;
// Dealloc_return.
- case Hexagon::DEALLOC_RET_cPt_V4:
- return Hexagon::DEALLOC_RET_cNotPt_V4;
- case Hexagon::DEALLOC_RET_cNotPt_V4:
- return Hexagon::DEALLOC_RET_cPt_V4;
+ case Hexagon::L4_return_t:
+ return Hexagon::L4_return_f;
+ case Hexagon::L4_return_f:
+ return Hexagon::L4_return_t;
}
}
@@ -780,22 +770,22 @@ getMatchingCondBranchOpcode(int Opc, bool invertPredicate) const {
case Hexagon::TFRI_f:
return !invertPredicate ? Hexagon::TFRI_cPt_f :
Hexagon::TFRI_cNotPt_f;
- case Hexagon::COMBINE_rr:
- return !invertPredicate ? Hexagon::COMBINE_rr_cPt :
- Hexagon::COMBINE_rr_cNotPt;
+ case Hexagon::A2_combinew:
+ return !invertPredicate ? Hexagon::C2_ccombinewt :
+ Hexagon::C2_ccombinewf;
// Word.
case Hexagon::STriw_f:
- return !invertPredicate ? Hexagon::STriw_cPt :
- Hexagon::STriw_cNotPt;
+ return !invertPredicate ? Hexagon::S2_pstorerit_io:
+ Hexagon::S2_pstorerif_io;
case Hexagon::STriw_indexed_f:
- return !invertPredicate ? Hexagon::STriw_indexed_cPt :
- Hexagon::STriw_indexed_cNotPt;
+ return !invertPredicate ? Hexagon::S2_pstorerit_io:
+ Hexagon::S2_pstorerif_io;
// DEALLOC_RETURN.
- case Hexagon::DEALLOC_RET_V4:
- return !invertPredicate ? Hexagon::DEALLOC_RET_cPt_V4 :
- Hexagon::DEALLOC_RET_cNotPt_V4;
+ case Hexagon::L4_return:
+ return !invertPredicate ? Hexagon::L4_return_t:
+ Hexagon::L4_return_f;
}
llvm_unreachable("Unexpected predicable instruction");
}
@@ -901,7 +891,7 @@ PredicateInstruction(MachineInstr *MI,
continue;
}
else {
- assert(false && "Unexpected operand type");
+ llvm_unreachable("Unexpected operand type");
}
}
}
@@ -1082,13 +1072,13 @@ isProfitableToDupForIfCvt(MachineBasicBlock &MBB,unsigned NumInstrs,
bool HexagonInstrInfo::isDeallocRet(const MachineInstr *MI) const {
switch (MI->getOpcode()) {
default: return false;
- case Hexagon::DEALLOC_RET_V4 :
- case Hexagon::DEALLOC_RET_cPt_V4 :
- case Hexagon::DEALLOC_RET_cNotPt_V4 :
- case Hexagon::DEALLOC_RET_cdnPnt_V4 :
- case Hexagon::DEALLOC_RET_cNotdnPnt_V4 :
- case Hexagon::DEALLOC_RET_cdnPt_V4 :
- case Hexagon::DEALLOC_RET_cNotdnPt_V4 :
+ case Hexagon::L4_return:
+ case Hexagon::L4_return_t:
+ case Hexagon::L4_return_f:
+ case Hexagon::L4_return_tnew_pnt:
+ case Hexagon::L4_return_fnew_pnt:
+ case Hexagon::L4_return_tnew_pt:
+ case Hexagon::L4_return_fnew_pt:
return true;
}
}
@@ -1107,33 +1097,29 @@ isValidOffset(const int Opcode, const int Offset) const {
switch(Opcode) {
- case Hexagon::LDriw:
- case Hexagon::LDriw_indexed:
+ case Hexagon::L2_loadri_io:
case Hexagon::LDriw_f:
- case Hexagon::STriw_indexed:
- case Hexagon::STriw:
+ case Hexagon::S2_storeri_io:
case Hexagon::STriw_f:
return (Offset >= Hexagon_MEMW_OFFSET_MIN) &&
(Offset <= Hexagon_MEMW_OFFSET_MAX);
- case Hexagon::LDrid:
- case Hexagon::LDrid_indexed:
+ case Hexagon::L2_loadrd_io:
case Hexagon::LDrid_f:
- case Hexagon::STrid:
- case Hexagon::STrid_indexed:
+ case Hexagon::S2_storerd_io:
case Hexagon::STrid_f:
return (Offset >= Hexagon_MEMD_OFFSET_MIN) &&
(Offset <= Hexagon_MEMD_OFFSET_MAX);
- case Hexagon::LDrih:
- case Hexagon::LDriuh:
- case Hexagon::STrih:
+ case Hexagon::L2_loadrh_io:
+ case Hexagon::L2_loadruh_io:
+ case Hexagon::S2_storerh_io:
return (Offset >= Hexagon_MEMH_OFFSET_MIN) &&
(Offset <= Hexagon_MEMH_OFFSET_MAX);
- case Hexagon::LDrib:
- case Hexagon::STrib:
- case Hexagon::LDriub:
+ case Hexagon::L2_loadrb_io:
+ case Hexagon::S2_storerb_io:
+ case Hexagon::L2_loadrub_io:
return (Offset >= Hexagon_MEMB_OFFSET_MIN) &&
(Offset <= Hexagon_MEMB_OFFSET_MAX);
@@ -1142,28 +1128,28 @@ isValidOffset(const int Opcode, const int Offset) const {
return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
(Offset <= Hexagon_ADDI_OFFSET_MAX);
- case Hexagon::MemOPw_ADDi_V4 :
- case Hexagon::MemOPw_SUBi_V4 :
- case Hexagon::MemOPw_ADDr_V4 :
- case Hexagon::MemOPw_SUBr_V4 :
- case Hexagon::MemOPw_ANDr_V4 :
- case Hexagon::MemOPw_ORr_V4 :
+ case Hexagon::L4_iadd_memopw_io:
+ case Hexagon::L4_isub_memopw_io:
+ case Hexagon::L4_add_memopw_io:
+ case Hexagon::L4_sub_memopw_io:
+ case Hexagon::L4_and_memopw_io:
+ case Hexagon::L4_or_memopw_io:
return (0 <= Offset && Offset <= 255);
- case Hexagon::MemOPh_ADDi_V4 :
- case Hexagon::MemOPh_SUBi_V4 :
- case Hexagon::MemOPh_ADDr_V4 :
- case Hexagon::MemOPh_SUBr_V4 :
- case Hexagon::MemOPh_ANDr_V4 :
- case Hexagon::MemOPh_ORr_V4 :
+ case Hexagon::L4_iadd_memoph_io:
+ case Hexagon::L4_isub_memoph_io:
+ case Hexagon::L4_add_memoph_io:
+ case Hexagon::L4_sub_memoph_io:
+ case Hexagon::L4_and_memoph_io:
+ case Hexagon::L4_or_memoph_io:
return (0 <= Offset && Offset <= 127);
- case Hexagon::MemOPb_ADDi_V4 :
- case Hexagon::MemOPb_SUBi_V4 :
- case Hexagon::MemOPb_ADDr_V4 :
- case Hexagon::MemOPb_SUBr_V4 :
- case Hexagon::MemOPb_ANDr_V4 :
- case Hexagon::MemOPb_ORr_V4 :
+ case Hexagon::L4_iadd_memopb_io:
+ case Hexagon::L4_isub_memopb_io:
+ case Hexagon::L4_add_memopb_io:
+ case Hexagon::L4_sub_memopb_io:
+ case Hexagon::L4_and_memopb_io:
+ case Hexagon::L4_or_memopb_io:
return (0 <= Offset && Offset <= 63);
// LDri_pred and STriw_pred are pseudo operations, so it has to take offset of
@@ -1172,7 +1158,7 @@ isValidOffset(const int Opcode, const int Offset) const {
case Hexagon::LDriw_pred:
return true;
- case Hexagon::LOOP0_i:
+ case Hexagon::J2_loop0i:
return isUInt<10>(Offset);
// INLINEASM is very special.
@@ -1220,31 +1206,31 @@ isMemOp(const MachineInstr *MI) const {
switch (MI->getOpcode())
{
- default: return false;
- case Hexagon::MemOPw_ADDi_V4 :
- case Hexagon::MemOPw_SUBi_V4 :
- case Hexagon::MemOPw_ADDr_V4 :
- case Hexagon::MemOPw_SUBr_V4 :
- case Hexagon::MemOPw_ANDr_V4 :
- case Hexagon::MemOPw_ORr_V4 :
- case Hexagon::MemOPh_ADDi_V4 :
- case Hexagon::MemOPh_SUBi_V4 :
- case Hexagon::MemOPh_ADDr_V4 :
- case Hexagon::MemOPh_SUBr_V4 :
- case Hexagon::MemOPh_ANDr_V4 :
- case Hexagon::MemOPh_ORr_V4 :
- case Hexagon::MemOPb_ADDi_V4 :
- case Hexagon::MemOPb_SUBi_V4 :
- case Hexagon::MemOPb_ADDr_V4 :
- case Hexagon::MemOPb_SUBr_V4 :
- case Hexagon::MemOPb_ANDr_V4 :
- case Hexagon::MemOPb_ORr_V4 :
- case Hexagon::MemOPb_SETBITi_V4:
- case Hexagon::MemOPh_SETBITi_V4:
- case Hexagon::MemOPw_SETBITi_V4:
- case Hexagon::MemOPb_CLRBITi_V4:
- case Hexagon::MemOPh_CLRBITi_V4:
- case Hexagon::MemOPw_CLRBITi_V4:
+ default: return false;
+ case Hexagon::L4_iadd_memopw_io:
+ case Hexagon::L4_isub_memopw_io:
+ case Hexagon::L4_add_memopw_io:
+ case Hexagon::L4_sub_memopw_io:
+ case Hexagon::L4_and_memopw_io:
+ case Hexagon::L4_or_memopw_io:
+ case Hexagon::L4_iadd_memoph_io:
+ case Hexagon::L4_isub_memoph_io:
+ case Hexagon::L4_add_memoph_io:
+ case Hexagon::L4_sub_memoph_io:
+ case Hexagon::L4_and_memoph_io:
+ case Hexagon::L4_or_memoph_io:
+ case Hexagon::L4_iadd_memopb_io:
+ case Hexagon::L4_isub_memopb_io:
+ case Hexagon::L4_add_memopb_io:
+ case Hexagon::L4_sub_memopb_io:
+ case Hexagon::L4_and_memopb_io:
+ case Hexagon::L4_or_memopb_io:
+ case Hexagon::L4_ior_memopb_io:
+ case Hexagon::L4_ior_memoph_io:
+ case Hexagon::L4_ior_memopw_io:
+ case Hexagon::L4_iand_memopb_io:
+ case Hexagon::L4_iand_memoph_io:
+ case Hexagon::L4_iand_memopw_io:
return true;
}
return false;
@@ -1264,12 +1250,12 @@ isSpillPredRegOp(const MachineInstr *MI) const {
bool HexagonInstrInfo::isNewValueJumpCandidate(const MachineInstr *MI) const {
switch (MI->getOpcode()) {
default: return false;
- case Hexagon::CMPEQrr:
- case Hexagon::CMPEQri:
- case Hexagon::CMPGTrr:
- case Hexagon::CMPGTri:
- case Hexagon::CMPGTUrr:
- case Hexagon::CMPGTUri:
+ case Hexagon::C2_cmpeq:
+ case Hexagon::C2_cmpeqi:
+ case Hexagon::C2_cmpgt:
+ case Hexagon::C2_cmpgti:
+ case Hexagon::C2_cmpgtu:
+ case Hexagon::C2_cmpgtui:
return true;
}
}
@@ -1278,51 +1264,71 @@ bool HexagonInstrInfo::
isConditionalTransfer (const MachineInstr *MI) const {
switch (MI->getOpcode()) {
default: return false;
- case Hexagon::TFR_cPt:
- case Hexagon::TFR_cNotPt:
- case Hexagon::TFRI_cPt:
- case Hexagon::TFRI_cNotPt:
- case Hexagon::TFR_cdnPt:
- case Hexagon::TFR_cdnNotPt:
- case Hexagon::TFRI_cdnPt:
- case Hexagon::TFRI_cdnNotPt:
+ case Hexagon::A2_tfrt:
+ case Hexagon::A2_tfrf:
+ case Hexagon::C2_cmoveit:
+ case Hexagon::C2_cmoveif:
+ case Hexagon::A2_tfrtnew:
+ case Hexagon::A2_tfrfnew:
+ case Hexagon::C2_cmovenewit:
+ case Hexagon::C2_cmovenewif:
return true;
}
}
bool HexagonInstrInfo::isConditionalALU32 (const MachineInstr* MI) const {
- const HexagonRegisterInfo& QRI = getRegisterInfo();
switch (MI->getOpcode())
{
default: return false;
+ case Hexagon::A2_paddf:
+ case Hexagon::A2_paddfnew:
+ case Hexagon::A2_paddt:
+ case Hexagon::A2_paddtnew:
+ case Hexagon::A2_pandf:
+ case Hexagon::A2_pandfnew:
+ case Hexagon::A2_pandt:
+ case Hexagon::A2_pandtnew:
+ case Hexagon::A4_paslhf:
+ case Hexagon::A4_paslhfnew:
+ case Hexagon::A4_paslht:
+ case Hexagon::A4_paslhtnew:
+ case Hexagon::A4_pasrhf:
+ case Hexagon::A4_pasrhfnew:
+ case Hexagon::A4_pasrht:
+ case Hexagon::A4_pasrhtnew:
+ case Hexagon::A2_porf:
+ case Hexagon::A2_porfnew:
+ case Hexagon::A2_port:
+ case Hexagon::A2_portnew:
+ case Hexagon::A2_psubf:
+ case Hexagon::A2_psubfnew:
+ case Hexagon::A2_psubt:
+ case Hexagon::A2_psubtnew:
+ case Hexagon::A2_pxorf:
+ case Hexagon::A2_pxorfnew:
+ case Hexagon::A2_pxort:
+ case Hexagon::A2_pxortnew:
+ case Hexagon::A4_psxthf:
+ case Hexagon::A4_psxthfnew:
+ case Hexagon::A4_psxtht:
+ case Hexagon::A4_psxthtnew:
+ case Hexagon::A4_psxtbf:
+ case Hexagon::A4_psxtbfnew:
+ case Hexagon::A4_psxtbt:
+ case Hexagon::A4_psxtbtnew:
+ case Hexagon::A4_pzxtbf:
+ case Hexagon::A4_pzxtbfnew:
+ case Hexagon::A4_pzxtbt:
+ case Hexagon::A4_pzxtbtnew:
+ case Hexagon::A4_pzxthf:
+ case Hexagon::A4_pzxthfnew:
+ case Hexagon::A4_pzxtht:
+ case Hexagon::A4_pzxthtnew:
case Hexagon::ADD_ri_cPt:
case Hexagon::ADD_ri_cNotPt:
- case Hexagon::ADD_rr_cPt:
- case Hexagon::ADD_rr_cNotPt:
- case Hexagon::XOR_rr_cPt:
- case Hexagon::XOR_rr_cNotPt:
- case Hexagon::AND_rr_cPt:
- case Hexagon::AND_rr_cNotPt:
- case Hexagon::OR_rr_cPt:
- case Hexagon::OR_rr_cNotPt:
- case Hexagon::SUB_rr_cPt:
- case Hexagon::SUB_rr_cNotPt:
- case Hexagon::COMBINE_rr_cPt:
- case Hexagon::COMBINE_rr_cNotPt:
+ case Hexagon::C2_ccombinewt:
+ case Hexagon::C2_ccombinewf:
return true;
- case Hexagon::ASLH_cPt_V4:
- case Hexagon::ASLH_cNotPt_V4:
- case Hexagon::ASRH_cPt_V4:
- case Hexagon::ASRH_cNotPt_V4:
- case Hexagon::SXTB_cPt_V4:
- case Hexagon::SXTB_cNotPt_V4:
- case Hexagon::SXTH_cPt_V4:
- case Hexagon::SXTH_cNotPt_V4:
- case Hexagon::ZXTB_cPt_V4:
- case Hexagon::ZXTB_cNotPt_V4:
- case Hexagon::ZXTH_cPt_V4:
- case Hexagon::ZXTH_cNotPt_V4:
- return QRI.Subtarget.hasV4TOps();
}
}
@@ -1332,56 +1338,44 @@ isConditionalLoad (const MachineInstr* MI) const {
switch (MI->getOpcode())
{
default: return false;
- case Hexagon::LDrid_cPt :
- case Hexagon::LDrid_cNotPt :
- case Hexagon::LDrid_indexed_cPt :
- case Hexagon::LDrid_indexed_cNotPt :
- case Hexagon::LDriw_cPt :
- case Hexagon::LDriw_cNotPt :
- case Hexagon::LDriw_indexed_cPt :
- case Hexagon::LDriw_indexed_cNotPt :
- case Hexagon::LDrih_cPt :
- case Hexagon::LDrih_cNotPt :
- case Hexagon::LDrih_indexed_cPt :
- case Hexagon::LDrih_indexed_cNotPt :
- case Hexagon::LDrib_cPt :
- case Hexagon::LDrib_cNotPt :
- case Hexagon::LDrib_indexed_cPt :
- case Hexagon::LDrib_indexed_cNotPt :
- case Hexagon::LDriuh_cPt :
- case Hexagon::LDriuh_cNotPt :
- case Hexagon::LDriuh_indexed_cPt :
- case Hexagon::LDriuh_indexed_cNotPt :
- case Hexagon::LDriub_cPt :
- case Hexagon::LDriub_cNotPt :
- case Hexagon::LDriub_indexed_cPt :
- case Hexagon::LDriub_indexed_cNotPt :
+ case Hexagon::L2_ploadrdt_io :
+ case Hexagon::L2_ploadrdf_io:
+ case Hexagon::L2_ploadrit_io:
+ case Hexagon::L2_ploadrif_io:
+ case Hexagon::L2_ploadrht_io:
+ case Hexagon::L2_ploadrhf_io:
+ case Hexagon::L2_ploadrbt_io:
+ case Hexagon::L2_ploadrbf_io:
+ case Hexagon::L2_ploadruht_io:
+ case Hexagon::L2_ploadruhf_io:
+ case Hexagon::L2_ploadrubt_io:
+ case Hexagon::L2_ploadrubf_io:
return true;
- case Hexagon::POST_LDrid_cPt :
- case Hexagon::POST_LDrid_cNotPt :
- case Hexagon::POST_LDriw_cPt :
- case Hexagon::POST_LDriw_cNotPt :
- case Hexagon::POST_LDrih_cPt :
- case Hexagon::POST_LDrih_cNotPt :
- case Hexagon::POST_LDrib_cPt :
- case Hexagon::POST_LDrib_cNotPt :
- case Hexagon::POST_LDriuh_cPt :
- case Hexagon::POST_LDriuh_cNotPt :
- case Hexagon::POST_LDriub_cPt :
- case Hexagon::POST_LDriub_cNotPt :
+ case Hexagon::L2_ploadrdt_pi:
+ case Hexagon::L2_ploadrdf_pi:
+ case Hexagon::L2_ploadrit_pi:
+ case Hexagon::L2_ploadrif_pi:
+ case Hexagon::L2_ploadrht_pi:
+ case Hexagon::L2_ploadrhf_pi:
+ case Hexagon::L2_ploadrbt_pi:
+ case Hexagon::L2_ploadrbf_pi:
+ case Hexagon::L2_ploadruht_pi:
+ case Hexagon::L2_ploadruhf_pi:
+ case Hexagon::L2_ploadrubt_pi:
+ case Hexagon::L2_ploadrubf_pi:
return QRI.Subtarget.hasV4TOps();
- case Hexagon::LDrid_indexed_shl_cPt_V4 :
- case Hexagon::LDrid_indexed_shl_cNotPt_V4 :
- case Hexagon::LDrib_indexed_shl_cPt_V4 :
- case Hexagon::LDrib_indexed_shl_cNotPt_V4 :
- case Hexagon::LDriub_indexed_shl_cPt_V4 :
- case Hexagon::LDriub_indexed_shl_cNotPt_V4 :
- case Hexagon::LDrih_indexed_shl_cPt_V4 :
- case Hexagon::LDrih_indexed_shl_cNotPt_V4 :
- case Hexagon::LDriuh_indexed_shl_cPt_V4 :
- case Hexagon::LDriuh_indexed_shl_cNotPt_V4 :
- case Hexagon::LDriw_indexed_shl_cPt_V4 :
- case Hexagon::LDriw_indexed_shl_cNotPt_V4 :
+ case Hexagon::L4_ploadrdt_rr:
+ case Hexagon::L4_ploadrdf_rr:
+ case Hexagon::L4_ploadrbt_rr:
+ case Hexagon::L4_ploadrbf_rr:
+ case Hexagon::L4_ploadrubt_rr:
+ case Hexagon::L4_ploadrubf_rr:
+ case Hexagon::L4_ploadrht_rr:
+ case Hexagon::L4_ploadrhf_rr:
+ case Hexagon::L4_ploadruht_rr:
+ case Hexagon::L4_ploadruhf_rr:
+ case Hexagon::L4_ploadrit_rr:
+ case Hexagon::L4_ploadrif_rr:
return QRI.Subtarget.hasV4TOps();
}
}
@@ -1426,50 +1420,47 @@ isConditionalStore (const MachineInstr* MI) const {
switch (MI->getOpcode())
{
default: return false;
- case Hexagon::STrib_imm_cPt_V4 :
- case Hexagon::STrib_imm_cNotPt_V4 :
- case Hexagon::STrib_indexed_shl_cPt_V4 :
- case Hexagon::STrib_indexed_shl_cNotPt_V4 :
- case Hexagon::STrib_cPt :
- case Hexagon::STrib_cNotPt :
- case Hexagon::POST_STbri_cPt :
- case Hexagon::POST_STbri_cNotPt :
- case Hexagon::STrid_indexed_cPt :
- case Hexagon::STrid_indexed_cNotPt :
- case Hexagon::STrid_indexed_shl_cPt_V4 :
- case Hexagon::POST_STdri_cPt :
- case Hexagon::POST_STdri_cNotPt :
- case Hexagon::STrih_cPt :
- case Hexagon::STrih_cNotPt :
- case Hexagon::STrih_indexed_cPt :
- case Hexagon::STrih_indexed_cNotPt :
- case Hexagon::STrih_imm_cPt_V4 :
- case Hexagon::STrih_imm_cNotPt_V4 :
- case Hexagon::STrih_indexed_shl_cPt_V4 :
- case Hexagon::STrih_indexed_shl_cNotPt_V4 :
- case Hexagon::POST_SThri_cPt :
- case Hexagon::POST_SThri_cNotPt :
- case Hexagon::STriw_cPt :
- case Hexagon::STriw_cNotPt :
- case Hexagon::STriw_indexed_cPt :
- case Hexagon::STriw_indexed_cNotPt :
- case Hexagon::STriw_imm_cPt_V4 :
- case Hexagon::STriw_imm_cNotPt_V4 :
- case Hexagon::STriw_indexed_shl_cPt_V4 :
- case Hexagon::STriw_indexed_shl_cNotPt_V4 :
- case Hexagon::POST_STwri_cPt :
- case Hexagon::POST_STwri_cNotPt :
+ case Hexagon::S4_storeirbt_io:
+ case Hexagon::S4_storeirbf_io:
+ case Hexagon::S4_pstorerbt_rr:
+ case Hexagon::S4_pstorerbf_rr:
+ case Hexagon::S2_pstorerbt_io:
+ case Hexagon::S2_pstorerbf_io:
+ case Hexagon::S2_pstorerbt_pi:
+ case Hexagon::S2_pstorerbf_pi:
+ case Hexagon::S2_pstorerdt_io:
+ case Hexagon::S2_pstorerdf_io:
+ case Hexagon::S4_pstorerdt_rr:
+ case Hexagon::S4_pstorerdf_rr:
+ case Hexagon::S2_pstorerdt_pi:
+ case Hexagon::S2_pstorerdf_pi:
+ case Hexagon::S2_pstorerht_io:
+ case Hexagon::S2_pstorerhf_io:
+ case Hexagon::S4_storeirht_io:
+ case Hexagon::S4_storeirhf_io:
+ case Hexagon::S4_pstorerht_rr:
+ case Hexagon::S4_pstorerhf_rr:
+ case Hexagon::S2_pstorerht_pi:
+ case Hexagon::S2_pstorerhf_pi:
+ case Hexagon::S2_pstorerit_io:
+ case Hexagon::S2_pstorerif_io:
+ case Hexagon::S4_storeirit_io:
+ case Hexagon::S4_storeirif_io:
+ case Hexagon::S4_pstorerit_rr:
+ case Hexagon::S4_pstorerif_rr:
+ case Hexagon::S2_pstorerit_pi:
+ case Hexagon::S2_pstorerif_pi:
return QRI.Subtarget.hasV4TOps();
// V4 global address store before promoting to dot new.
- case Hexagon::STd_GP_cPt_V4 :
- case Hexagon::STd_GP_cNotPt_V4 :
- case Hexagon::STb_GP_cPt_V4 :
- case Hexagon::STb_GP_cNotPt_V4 :
- case Hexagon::STh_GP_cPt_V4 :
- case Hexagon::STh_GP_cNotPt_V4 :
- case Hexagon::STw_GP_cPt_V4 :
- case Hexagon::STw_GP_cNotPt_V4 :
+ case Hexagon::S4_pstorerdt_abs:
+ case Hexagon::S4_pstorerdf_abs:
+ case Hexagon::S4_pstorerbt_abs:
+ case Hexagon::S4_pstorerbf_abs:
+ case Hexagon::S4_pstorerht_abs:
+ case Hexagon::S4_pstorerhf_abs:
+ case Hexagon::S4_pstorerit_abs:
+ case Hexagon::S4_pstorerif_abs:
return QRI.Subtarget.hasV4TOps();
// Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded
@@ -1565,10 +1556,10 @@ int HexagonInstrInfo::GetDotNewOp(const MachineInstr* MI) const {
return Hexagon::STrih_shl_nv_V4;
case Hexagon::STriw_f:
- return Hexagon::STriw_nv_V4;
+ return Hexagon::S2_storerinew_io;
case Hexagon::STriw_indexed_f:
- return Hexagon::STriw_indexed_nv_V4;
+ return Hexagon::S4_storerinew_rr;
case Hexagon::STriw_shl_V4:
return Hexagon::STriw_shl_nv_V4;
@@ -1589,28 +1580,28 @@ int HexagonInstrInfo::GetDotNewPredOp(MachineInstr *MI,
switch (MI->getOpcode()) {
default: llvm_unreachable("Unknown .new type");
// Condtional Jumps
- case Hexagon::JMP_t:
- case Hexagon::JMP_f:
+ case Hexagon::J2_jumpt:
+ case Hexagon::J2_jumpf:
return getDotNewPredJumpOp(MI, MBPI);
- case Hexagon::JMPR_t:
- return Hexagon::JMPR_tnew_tV3;
+ case Hexagon::J2_jumprt:
+ return Hexagon::J2_jumptnewpt;
- case Hexagon::JMPR_f:
- return Hexagon::JMPR_fnew_tV3;
+ case Hexagon::J2_jumprf:
+ return Hexagon::J2_jumprfnewpt;
- case Hexagon::JMPret_t:
- return Hexagon::JMPret_tnew_tV3;
+ case Hexagon::JMPrett:
+ return Hexagon::J2_jumprtnewpt;
- case Hexagon::JMPret_f:
- return Hexagon::JMPret_fnew_tV3;
+ case Hexagon::JMPretf:
+ return Hexagon::J2_jumprfnewpt;
// Conditional combine
- case Hexagon::COMBINE_rr_cPt :
- return Hexagon::COMBINE_rr_cdnPt;
- case Hexagon::COMBINE_rr_cNotPt :
- return Hexagon::COMBINE_rr_cdnNotPt;
+ case Hexagon::C2_ccombinewt:
+ return Hexagon::C2_ccombinewnewt;
+ case Hexagon::C2_ccombinewf:
+ return Hexagon::C2_ccombinewnewf;
}
}
@@ -1636,11 +1627,10 @@ void HexagonInstrInfo::immediateExtend(MachineInstr *MI) const {
MO.addTargetFlag(HexagonII::HMOTF_ConstExtended);
}
-DFAPacketizer *HexagonInstrInfo::
-CreateTargetScheduleState(const TargetMachine *TM,
- const ScheduleDAG *DAG) const {
- const InstrItineraryData *II = TM->getInstrItineraryData();
- return TM->getSubtarget<HexagonGenSubtargetInfo>().createDFAPacketizer(II);
+DFAPacketizer *HexagonInstrInfo::CreateTargetScheduleState(
+ const TargetSubtargetInfo &STI) const {
+ const InstrItineraryData *II = STI.getInstrItineraryData();
+ return static_cast<const HexagonSubtarget &>(STI).createDFAPacketizer(II);
}
bool HexagonInstrInfo::isSchedulingBoundary(const MachineInstr *MI,
@@ -1728,10 +1718,10 @@ HexagonInstrInfo::getDotNewPredJumpOp(MachineInstr *MI,
taken = true;
switch (MI->getOpcode()) {
- case Hexagon::JMP_t:
- return taken ? Hexagon::JMP_tnew_t : Hexagon::JMP_tnew_nt;
- case Hexagon::JMP_f:
- return taken ? Hexagon::JMP_fnew_t : Hexagon::JMP_fnew_nt;
+ case Hexagon::J2_jumpt:
+ return taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew;
+ case Hexagon::J2_jumpf:
+ return taken ? Hexagon::J2_jumpfnewpt : Hexagon::J2_jumpfnew;
default:
llvm_unreachable("Unexpected jump instruction.");
@@ -1765,7 +1755,7 @@ int HexagonInstrInfo::getMinValue(const MachineInstr *MI) const {
& HexagonII::ExtentBitsMask;
if (isSigned) // if value is signed
- return -1 << (bits - 1);
+ return -1U << (bits - 1);
else
return 0;
}
@@ -1779,9 +1769,9 @@ int HexagonInstrInfo::getMaxValue(const MachineInstr *MI) const {
& HexagonII::ExtentBitsMask;
if (isSigned) // if value is signed
- return ~(-1 << (bits - 1));
+ return ~(-1U << (bits - 1));
else
- return ~(-1 << bits);
+ return ~(-1U << bits);
}
// Returns true if an instruction can be converted into a non-extended
@@ -1843,16 +1833,16 @@ short HexagonInstrInfo::getNonExtOpcode (const MachineInstr *MI) const {
}
bool HexagonInstrInfo::PredOpcodeHasJMP_c(Opcode_t Opcode) const {
- return (Opcode == Hexagon::JMP_t) ||
- (Opcode == Hexagon::JMP_f) ||
- (Opcode == Hexagon::JMP_tnew_t) ||
- (Opcode == Hexagon::JMP_fnew_t) ||
- (Opcode == Hexagon::JMP_tnew_nt) ||
- (Opcode == Hexagon::JMP_fnew_nt);
+ return (Opcode == Hexagon::J2_jumpt) ||
+ (Opcode == Hexagon::J2_jumpf) ||
+ (Opcode == Hexagon::J2_jumptnewpt) ||
+ (Opcode == Hexagon::J2_jumpfnewpt) ||
+ (Opcode == Hexagon::J2_jumpt) ||
+ (Opcode == Hexagon::J2_jumpf);
}
bool HexagonInstrInfo::PredOpcodeHasNot(Opcode_t Opcode) const {
- return (Opcode == Hexagon::JMP_f) ||
- (Opcode == Hexagon::JMP_fnew_t) ||
- (Opcode == Hexagon::JMP_fnew_nt);
+ return (Opcode == Hexagon::J2_jumpf) ||
+ (Opcode == Hexagon::J2_jumpfnewpt) ||
+ (Opcode == Hexagon::J2_jumpfnew);
}
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.h b/lib/Target/Hexagon/HexagonInstrInfo.h
index 6b032c95e74a..6acfbec24709 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.h
+++ b/lib/Target/Hexagon/HexagonInstrInfo.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef HexagonINSTRUCTIONINFO_H
-#define HexagonINSTRUCTIONINFO_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONINSTRINFO_H
+#define LLVM_LIB_TARGET_HEXAGON_HEXAGONINSTRINFO_H
#include "HexagonRegisterInfo.h"
#include "MCTargetDesc/HexagonBaseInfo.h"
@@ -148,9 +148,8 @@ public:
bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles,
const BranchProbability &Probability) const override;
- DFAPacketizer*
- CreateTargetScheduleState(const TargetMachine *TM,
- const ScheduleDAG *DAG) const override;
+ DFAPacketizer *
+ CreateTargetScheduleState(const TargetSubtargetInfo &STI) const override;
bool isSchedulingBoundary(const MachineInstr *MI,
const MachineBasicBlock *MBB,
diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td
index 4dcf101ea3ad..7ce65f345cab 100644
--- a/lib/Target/Hexagon/HexagonInstrInfo.td
+++ b/lib/Target/Hexagon/HexagonInstrInfo.td
@@ -14,367 +14,606 @@
include "HexagonInstrFormats.td"
include "HexagonOperands.td"
+// Pattern fragment that combines the value type and the register class
+// into a single parameter.
+// The pat frags in the definitions below need to have a named register,
+// otherwise i32 will be assumed regardless of the register class. The
+// name of the register does not matter.
+def I1 : PatLeaf<(i1 PredRegs:$R)>;
+def I32 : PatLeaf<(i32 IntRegs:$R)>;
+def I64 : PatLeaf<(i64 DoubleRegs:$R)>;
+def F32 : PatLeaf<(f32 IntRegs:$R)>;
+def F64 : PatLeaf<(f64 DoubleRegs:$R)>;
+
+// Pattern fragments to extract the low and high subregisters from a
+// 64-bit value.
+def LoReg: OutPatFrag<(ops node:$Rs),
+ (EXTRACT_SUBREG (i64 $Rs), subreg_loreg)>;
+
//===----------------------------------------------------------------------===//
-// Multi-class for logical operators.
-multiclass ALU32_rr_ri<string OpcStr, SDNode OpNode> {
- def rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
- !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
- [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$b),
- (i32 IntRegs:$c)))]>;
- def ri : ALU32_ri<(outs IntRegs:$dst), (ins s10Imm:$b, IntRegs:$c),
- !strconcat("$dst = ", !strconcat(OpcStr, "(#$b, $c)")),
- [(set (i32 IntRegs:$dst), (OpNode s10Imm:$b,
- (i32 IntRegs:$c)))]>;
-}
+//===----------------------------------------------------------------------===//
+// Compare
+//===----------------------------------------------------------------------===//
+let hasSideEffects = 0, isCompare = 1, InputType = "imm", isExtendable = 1,
+ opExtendable = 2 in
+class T_CMP <string mnemonic, bits<2> MajOp, bit isNot, Operand ImmOp>
+ : ALU32Inst <(outs PredRegs:$dst),
+ (ins IntRegs:$src1, ImmOp:$src2),
+ "$dst = "#!if(isNot, "!","")#mnemonic#"($src1, #$src2)",
+ [], "",ALU32_2op_tc_2early_SLOT0123 >, ImmRegRel {
+ bits<2> dst;
+ bits<5> src1;
+ bits<10> src2;
+ let CextOpcode = mnemonic;
+ let opExtentBits = !if(!eq(mnemonic, "cmp.gtu"), 9, 10);
+ let isExtentSigned = !if(!eq(mnemonic, "cmp.gtu"), 0, 1);
+
+ let IClass = 0b0111;
+
+ let Inst{27-24} = 0b0101;
+ let Inst{23-22} = MajOp;
+ let Inst{21} = !if(!eq(mnemonic, "cmp.gtu"), 0, src2{9});
+ let Inst{20-16} = src1;
+ let Inst{13-5} = src2{8-0};
+ let Inst{4} = isNot;
+ let Inst{3-2} = 0b00;
+ let Inst{1-0} = dst;
+ }
-// Multi-class for compare ops.
-let isCompare = 1 in {
-multiclass CMP64_rr<string OpcStr, PatFrag OpNode> {
- def rr : ALU64_rr<(outs PredRegs:$dst), (ins DoubleRegs:$b, DoubleRegs:$c),
- !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
- [(set (i1 PredRegs:$dst),
- (OpNode (i64 DoubleRegs:$b), (i64 DoubleRegs:$c)))]>;
-}
+def C2_cmpeqi : T_CMP <"cmp.eq", 0b00, 0, s10Ext>;
+def C2_cmpgti : T_CMP <"cmp.gt", 0b01, 0, s10Ext>;
+def C2_cmpgtui : T_CMP <"cmp.gtu", 0b10, 0, u9Ext>;
-multiclass CMP32_rr_ri_s10<string OpcStr, string CextOp, PatFrag OpNode> {
- let CextOpcode = CextOp in {
- let InputType = "reg" in
- def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
- !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
- [(set (i1 PredRegs:$dst),
- (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>;
+class T_CMP_pat <InstHexagon MI, PatFrag OpNode, PatLeaf ImmPred>
+ : Pat<(i1 (OpNode (i32 IntRegs:$src1), ImmPred:$src2)),
+ (MI IntRegs:$src1, ImmPred:$src2)>;
- let isExtendable = 1, opExtendable = 2, isExtentSigned = 1,
- opExtentBits = 10, InputType = "imm" in
- def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s10Ext:$c),
- !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
- [(set (i1 PredRegs:$dst),
- (OpNode (i32 IntRegs:$b), s10ExtPred:$c))]>;
- }
-}
+def : T_CMP_pat <C2_cmpeqi, seteq, s10ImmPred>;
+def : T_CMP_pat <C2_cmpgti, setgt, s10ImmPred>;
+def : T_CMP_pat <C2_cmpgtui, setugt, u9ImmPred>;
-multiclass CMP32_rr_ri_u9<string OpcStr, string CextOp, PatFrag OpNode> {
- let CextOpcode = CextOp in {
- let InputType = "reg" in
- def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
- !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
- [(set (i1 PredRegs:$dst),
- (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>;
+//===----------------------------------------------------------------------===//
+// ALU32/ALU +
+//===----------------------------------------------------------------------===//
+def SDTHexagonI64I32I32 : SDTypeProfile<1, 2,
+ [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
- let isExtendable = 1, opExtendable = 2, isExtentSigned = 0,
- opExtentBits = 9, InputType = "imm" in
- def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u9Ext:$c),
- !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
- [(set (i1 PredRegs:$dst),
- (OpNode (i32 IntRegs:$b), u9ExtPred:$c))]>;
- }
+def HexagonCOMBINE : SDNode<"HexagonISD::COMBINE", SDTHexagonI64I32I32>;
+
+let hasSideEffects = 0, hasNewValue = 1, InputType = "reg" in
+class T_ALU32_3op<string mnemonic, bits<3> MajOp, bits<3> MinOp, bit OpsRev,
+ bit IsComm>
+ : ALU32_rr<(outs IntRegs:$Rd), (ins IntRegs:$Rs, IntRegs:$Rt),
+ "$Rd = "#mnemonic#"($Rs, $Rt)",
+ [], "", ALU32_3op_tc_1_SLOT0123>, ImmRegRel, PredRel {
+ let isCommutable = IsComm;
+ let BaseOpcode = mnemonic#_rr;
+ let CextOpcode = mnemonic;
+
+ bits<5> Rs;
+ bits<5> Rt;
+ bits<5> Rd;
+
+ let IClass = 0b1111;
+ let Inst{27} = 0b0;
+ let Inst{26-24} = MajOp;
+ let Inst{23-21} = MinOp;
+ let Inst{20-16} = !if(OpsRev,Rt,Rs);
+ let Inst{12-8} = !if(OpsRev,Rs,Rt);
+ let Inst{4-0} = Rd;
}
-multiclass CMP32_ri_s8<string OpcStr, PatFrag OpNode> {
-let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in
- def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s8Ext:$c),
- !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
- [(set (i1 PredRegs:$dst), (OpNode (i32 IntRegs:$b),
- s8ExtPred:$c))]>;
+let hasSideEffects = 0, hasNewValue = 1 in
+class T_ALU32_3op_pred<string mnemonic, bits<3> MajOp, bits<3> MinOp,
+ bit OpsRev, bit PredNot, bit PredNew>
+ : ALU32_rr<(outs IntRegs:$Rd), (ins PredRegs:$Pu, IntRegs:$Rs, IntRegs:$Rt),
+ "if ("#!if(PredNot,"!","")#"$Pu"#!if(PredNew,".new","")#") "#
+ "$Rd = "#mnemonic#"($Rs, $Rt)",
+ [], "", ALU32_3op_tc_1_SLOT0123>, ImmRegRel, PredNewRel {
+ let isPredicated = 1;
+ let isPredicatedFalse = PredNot;
+ let isPredicatedNew = PredNew;
+ let BaseOpcode = mnemonic#_rr;
+ let CextOpcode = mnemonic;
+
+ bits<2> Pu;
+ bits<5> Rs;
+ bits<5> Rt;
+ bits<5> Rd;
+
+ let IClass = 0b1111;
+ let Inst{27} = 0b1;
+ let Inst{26-24} = MajOp;
+ let Inst{23-21} = MinOp;
+ let Inst{20-16} = !if(OpsRev,Rt,Rs);
+ let Inst{13} = PredNew;
+ let Inst{12-8} = !if(OpsRev,Rs,Rt);
+ let Inst{7} = PredNot;
+ let Inst{6-5} = Pu;
+ let Inst{4-0} = Rd;
}
+
+class T_ALU32_combineh<string Op1, string Op2, bits<3> MajOp, bits<3> MinOp,
+ bit OpsRev>
+ : T_ALU32_3op<"", MajOp, MinOp, OpsRev, 0> {
+ let AsmString = "$Rd = combine($Rs"#Op1#", $Rt"#Op2#")";
}
-//===----------------------------------------------------------------------===//
-// ALU32/ALU (Instructions with register-register form)
-//===----------------------------------------------------------------------===//
-def SDTHexagonI64I32I32 : SDTypeProfile<1, 2,
- [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>;
+let isCodeGenOnly = 0 in {
+def A2_combine_hh : T_ALU32_combineh<".h", ".h", 0b011, 0b100, 1>;
+def A2_combine_hl : T_ALU32_combineh<".h", ".l", 0b011, 0b101, 1>;
+def A2_combine_lh : T_ALU32_combineh<".l", ".h", 0b011, 0b110, 1>;
+def A2_combine_ll : T_ALU32_combineh<".l", ".l", 0b011, 0b111, 1>;
+}
-def HexagonWrapperCombineII :
- SDNode<"HexagonISD::WrapperCombineII", SDTHexagonI64I32I32>;
+class T_ALU32_3op_sfx<string mnemonic, string suffix, bits<3> MajOp,
+ bits<3> MinOp, bit OpsRev, bit IsComm>
+ : T_ALU32_3op<"", MajOp, MinOp, OpsRev, IsComm> {
+ let AsmString = "$Rd = "#mnemonic#"($Rs, $Rt)"#suffix;
+}
-def HexagonWrapperCombineRR :
- SDNode<"HexagonISD::WrapperCombineRR", SDTHexagonI64I32I32>;
+let Defs = [USR_OVF], Itinerary = ALU32_3op_tc_2_SLOT0123,
+ isCodeGenOnly = 0 in {
+ def A2_addsat : T_ALU32_3op_sfx<"add", ":sat", 0b110, 0b010, 0, 1>;
+ def A2_subsat : T_ALU32_3op_sfx<"sub", ":sat", 0b110, 0b110, 1, 0>;
+}
-multiclass ALU32_Pbase<string mnemonic, RegisterClass RC, bit isNot,
- bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME : ALU32_rr<(outs RC:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs: $src3),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ",
- ") $dst = ")#mnemonic#"($src2, $src3)",
- []>;
+multiclass T_ALU32_3op_p<string mnemonic, bits<3> MajOp, bits<3> MinOp,
+ bit OpsRev> {
+ def t : T_ALU32_3op_pred<mnemonic, MajOp, MinOp, OpsRev, 0, 0>;
+ def f : T_ALU32_3op_pred<mnemonic, MajOp, MinOp, OpsRev, 1, 0>;
+ def tnew : T_ALU32_3op_pred<mnemonic, MajOp, MinOp, OpsRev, 0, 1>;
+ def fnew : T_ALU32_3op_pred<mnemonic, MajOp, MinOp, OpsRev, 1, 1>;
}
-multiclass ALU32_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : ALU32_Pbase<mnemonic, RC, PredNot, 0>;
- // Predicate new
- defm _cdn#NAME : ALU32_Pbase<mnemonic, RC, PredNot, 1>;
- }
+multiclass T_ALU32_3op_A2<string mnemonic, bits<3> MajOp, bits<3> MinOp,
+ bit OpsRev, bit IsComm> {
+ let isPredicable = 1 in
+ def A2_#NAME : T_ALU32_3op <mnemonic, MajOp, MinOp, OpsRev, IsComm>;
+ defm A2_p#NAME : T_ALU32_3op_p<mnemonic, MajOp, MinOp, OpsRev>;
}
-let InputType = "reg" in
-multiclass ALU32_base<string mnemonic, string CextOp, SDNode OpNode> {
- let CextOpcode = CextOp, BaseOpcode = CextOp#_rr in {
- let isPredicable = 1 in
- def NAME : ALU32_rr<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = "#mnemonic#"($src1, $src2)",
- [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$src1),
- (i32 IntRegs:$src2)))]>;
-
- let neverHasSideEffects = 1, isPredicated = 1 in {
- defm Pt : ALU32_Pred<mnemonic, IntRegs, 0>;
- defm NotPt : ALU32_Pred<mnemonic, IntRegs, 1>;
- }
- }
+let isCodeGenOnly = 0 in {
+defm add : T_ALU32_3op_A2<"add", 0b011, 0b000, 0, 1>;
+defm and : T_ALU32_3op_A2<"and", 0b001, 0b000, 0, 1>;
+defm or : T_ALU32_3op_A2<"or", 0b001, 0b001, 0, 1>;
+defm sub : T_ALU32_3op_A2<"sub", 0b011, 0b001, 1, 0>;
+defm xor : T_ALU32_3op_A2<"xor", 0b001, 0b011, 0, 1>;
}
-let isCommutable = 1 in {
- defm ADD_rr : ALU32_base<"add", "ADD", add>, ImmRegRel, PredNewRel;
- defm AND_rr : ALU32_base<"and", "AND", and>, ImmRegRel, PredNewRel;
- defm XOR_rr : ALU32_base<"xor", "XOR", xor>, ImmRegRel, PredNewRel;
- defm OR_rr : ALU32_base<"or", "OR", or>, ImmRegRel, PredNewRel;
+// Pats for instruction selection.
+class BinOp32_pat<SDNode Op, InstHexagon MI, ValueType ResT>
+ : Pat<(ResT (Op (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))),
+ (ResT (MI IntRegs:$Rs, IntRegs:$Rt))>;
+
+def: BinOp32_pat<add, A2_add, i32>;
+def: BinOp32_pat<and, A2_and, i32>;
+def: BinOp32_pat<or, A2_or, i32>;
+def: BinOp32_pat<sub, A2_sub, i32>;
+def: BinOp32_pat<xor, A2_xor, i32>;
+
+// A few special cases producing register pairs:
+let OutOperandList = (outs DoubleRegs:$Rd), hasNewValue = 0,
+ isCodeGenOnly = 0 in {
+ def S2_packhl : T_ALU32_3op <"packhl", 0b101, 0b100, 0, 0>;
+
+ let isPredicable = 1 in
+ def A2_combinew : T_ALU32_3op <"combine", 0b101, 0b000, 0, 0>;
+
+ // Conditional combinew uses "newt/f" instead of "t/fnew".
+ def C2_ccombinewt : T_ALU32_3op_pred<"combine", 0b101, 0b000, 0, 0, 0>;
+ def C2_ccombinewf : T_ALU32_3op_pred<"combine", 0b101, 0b000, 0, 1, 0>;
+ def C2_ccombinewnewt : T_ALU32_3op_pred<"combine", 0b101, 0b000, 0, 0, 1>;
+ def C2_ccombinewnewf : T_ALU32_3op_pred<"combine", 0b101, 0b000, 0, 1, 1>;
}
-defm SUB_rr : ALU32_base<"sub", "SUB", sub>, ImmRegRel, PredNewRel;
+let hasSideEffects = 0, hasNewValue = 1, isCompare = 1, InputType = "reg" in
+class T_ALU32_3op_cmp<string mnemonic, bits<2> MinOp, bit IsNeg, bit IsComm>
+ : ALU32_rr<(outs PredRegs:$Pd), (ins IntRegs:$Rs, IntRegs:$Rt),
+ "$Pd = "#mnemonic#"($Rs, $Rt)",
+ [], "", ALU32_3op_tc_1_SLOT0123>, ImmRegRel {
+ let CextOpcode = mnemonic;
+ let isCommutable = IsComm;
+ bits<5> Rs;
+ bits<5> Rt;
+ bits<2> Pd;
+
+ let IClass = 0b1111;
+ let Inst{27-24} = 0b0010;
+ let Inst{22-21} = MinOp;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ let Inst{4} = IsNeg;
+ let Inst{3-2} = 0b00;
+ let Inst{1-0} = Pd;
+}
-// Combines the two integer registers SRC1 and SRC2 into a double register.
-let isPredicable = 1 in
-class T_Combine : ALU32_rr<(outs DoubleRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = combine($src1, $src2)",
- [(set (i64 DoubleRegs:$dst),
- (i64 (HexagonWrapperCombineRR (i32 IntRegs:$src1),
- (i32 IntRegs:$src2))))]>;
-
-multiclass Combine_base {
- let BaseOpcode = "combine" in {
- def NAME : T_Combine;
- let neverHasSideEffects = 1, isPredicated = 1 in {
- defm Pt : ALU32_Pred<"combine", DoubleRegs, 0>;
- defm NotPt : ALU32_Pred<"combine", DoubleRegs, 1>;
- }
- }
+let Itinerary = ALU32_3op_tc_2early_SLOT0123, isCodeGenOnly = 0 in {
+ def C2_cmpeq : T_ALU32_3op_cmp< "cmp.eq", 0b00, 0, 1>;
+ def C2_cmpgt : T_ALU32_3op_cmp< "cmp.gt", 0b10, 0, 0>;
+ def C2_cmpgtu : T_ALU32_3op_cmp< "cmp.gtu", 0b11, 0, 0>;
}
-defm COMBINE_rr : Combine_base, PredNewRel;
+// Patfrag to convert the usual comparison patfrags (e.g. setlt) to ones
+// that reverse the order of the operands.
+class RevCmp<PatFrag F> : PatFrag<(ops node:$rhs, node:$lhs), F.Fragment>;
+
+// Pats for compares. They use PatFrags as operands, not SDNodes,
+// since seteq/setgt/etc. are defined as ParFrags.
+class T_cmp32_rr_pat<InstHexagon MI, PatFrag Op, ValueType VT>
+ : Pat<(VT (Op (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))),
+ (VT (MI IntRegs:$Rs, IntRegs:$Rt))>;
+
+def: T_cmp32_rr_pat<C2_cmpeq, seteq, i1>;
+def: T_cmp32_rr_pat<C2_cmpgt, setgt, i1>;
+def: T_cmp32_rr_pat<C2_cmpgtu, setugt, i1>;
+
+def: T_cmp32_rr_pat<C2_cmpgt, RevCmp<setlt>, i1>;
+def: T_cmp32_rr_pat<C2_cmpgtu, RevCmp<setult>, i1>;
+
+let CextOpcode = "MUX", InputType = "reg", hasNewValue = 1,
+ isCodeGenOnly = 0 in
+def C2_mux: ALU32_rr<(outs IntRegs:$Rd),
+ (ins PredRegs:$Pu, IntRegs:$Rs, IntRegs:$Rt),
+ "$Rd = mux($Pu, $Rs, $Rt)", [], "", ALU32_3op_tc_1_SLOT0123>, ImmRegRel {
+ bits<5> Rd;
+ bits<2> Pu;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let CextOpcode = "mux";
+ let InputType = "reg";
+ let hasSideEffects = 0;
+ let IClass = 0b1111;
+
+ let Inst{27-24} = 0b0100;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ let Inst{6-5} = Pu;
+ let Inst{4-0} = Rd;
+}
-// Combines the two immediates SRC1 and SRC2 into a double register.
-class COMBINE_imm<Operand imm1, Operand imm2, PatLeaf pat1, PatLeaf pat2> :
- ALU32_ii<(outs DoubleRegs:$dst), (ins imm1:$src1, imm2:$src2),
- "$dst = combine(#$src1, #$src2)",
- [(set (i64 DoubleRegs:$dst),
- (i64 (HexagonWrapperCombineII (i32 pat1:$src1), (i32 pat2:$src2))))]>;
+def: Pat<(i32 (select (i1 PredRegs:$Pu), (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))),
+ (C2_mux PredRegs:$Pu, IntRegs:$Rs, IntRegs:$Rt)>;
+
+// Combines the two immediates into a double register.
+// Increase complexity to make it greater than any complexity of a combine
+// that involves a register.
+
+let isReMaterializable = 1, isMoveImm = 1, isAsCheapAsAMove = 1,
+ isExtentSigned = 1, isExtendable = 1, opExtentBits = 8, opExtendable = 1,
+ AddedComplexity = 75, isCodeGenOnly = 0 in
+def A2_combineii: ALU32Inst <(outs DoubleRegs:$Rdd), (ins s8Ext:$s8, s8Imm:$S8),
+ "$Rdd = combine(#$s8, #$S8)",
+ [(set (i64 DoubleRegs:$Rdd),
+ (i64 (HexagonCOMBINE(i32 s8ExtPred:$s8), (i32 s8ImmPred:$S8))))]> {
+ bits<5> Rdd;
+ bits<8> s8;
+ bits<8> S8;
+
+ let IClass = 0b0111;
+ let Inst{27-23} = 0b11000;
+ let Inst{22-16} = S8{7-1};
+ let Inst{13} = S8{0};
+ let Inst{12-5} = s8;
+ let Inst{4-0} = Rdd;
+ }
-let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8 in
-def COMBINE_Ii : COMBINE_imm<s8Ext, s8Imm, s8ExtPred, s8ImmPred>;
+//===----------------------------------------------------------------------===//
+// Template class for predicated ADD of a reg and an Immediate value.
+//===----------------------------------------------------------------------===//
+let hasNewValue = 1 in
+class T_Addri_Pred <bit PredNot, bit PredNew>
+ : ALU32_ri <(outs IntRegs:$Rd),
+ (ins PredRegs:$Pu, IntRegs:$Rs, s8Ext:$s8),
+ !if(PredNot, "if (!$Pu", "if ($Pu")#!if(PredNew,".new) $Rd = ",
+ ") $Rd = ")#"add($Rs, #$s8)"> {
+ bits<5> Rd;
+ bits<2> Pu;
+ bits<5> Rs;
+ bits<8> s8;
+
+ let isPredicatedNew = PredNew;
+ let IClass = 0b0111;
+
+ let Inst{27-24} = 0b0100;
+ let Inst{23} = PredNot;
+ let Inst{22-21} = Pu;
+ let Inst{20-16} = Rs;
+ let Inst{13} = PredNew;
+ let Inst{12-5} = s8;
+ let Inst{4-0} = Rd;
+ }
//===----------------------------------------------------------------------===//
-// ALU32/ALU (ADD with register-immediate form)
+// A2_addi: Add a signed immediate to a register.
//===----------------------------------------------------------------------===//
-multiclass ALU32ri_Pbase<string mnemonic, bit isNot, bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME : ALU32_ri<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, s8Ext: $src3),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ",
- ") $dst = ")#mnemonic#"($src2, #$src3)",
- []>;
-}
+let hasNewValue = 1 in
+class T_Addri <Operand immOp, list<dag> pattern = [] >
+ : ALU32_ri <(outs IntRegs:$Rd),
+ (ins IntRegs:$Rs, immOp:$s16),
+ "$Rd = add($Rs, #$s16)", pattern,
+ //[(set (i32 IntRegs:$Rd), (add (i32 IntRegs:$Rs), (s16ExtPred:$s16)))],
+ "", ALU32_ADDI_tc_1_SLOT0123> {
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<16> s16;
+
+ let IClass = 0b1011;
+
+ let Inst{27-21} = s16{15-9};
+ let Inst{20-16} = Rs;
+ let Inst{13-5} = s16{8-0};
+ let Inst{4-0} = Rd;
+ }
-multiclass ALU32ri_Pred<string mnemonic, bit PredNot> {
+//===----------------------------------------------------------------------===//
+// Multiclass for ADD of a register and an immediate value.
+//===----------------------------------------------------------------------===//
+multiclass Addri_Pred<string mnemonic, bit PredNot> {
let isPredicatedFalse = PredNot in {
- defm _c#NAME : ALU32ri_Pbase<mnemonic, PredNot, 0>;
+ def _c#NAME : T_Addri_Pred<PredNot, 0>;
// Predicate new
- defm _cdn#NAME : ALU32ri_Pbase<mnemonic, PredNot, 1>;
+ def _cdn#NAME : T_Addri_Pred<PredNot, 1>;
}
}
let isExtendable = 1, InputType = "imm" in
-multiclass ALU32ri_base<string mnemonic, string CextOp, SDNode OpNode> {
- let CextOpcode = CextOp, BaseOpcode = CextOp#_ri in {
+multiclass Addri_base<string mnemonic, SDNode OpNode> {
+ let CextOpcode = mnemonic, BaseOpcode = mnemonic#_ri in {
let opExtendable = 2, isExtentSigned = 1, opExtentBits = 16,
isPredicable = 1 in
- def NAME : ALU32_ri<(outs IntRegs:$dst),
- (ins IntRegs:$src1, s16Ext:$src2),
- "$dst = "#mnemonic#"($src1, #$src2)",
- [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$src1),
- (s16ExtPred:$src2)))]>;
+ def NAME : T_Addri< s16Ext, // Rd=add(Rs,#s16)
+ [(set (i32 IntRegs:$Rd),
+ (add IntRegs:$Rs, s16ExtPred:$s16))]>;
let opExtendable = 3, isExtentSigned = 1, opExtentBits = 8,
- neverHasSideEffects = 1, isPredicated = 1 in {
- defm Pt : ALU32ri_Pred<mnemonic, 0>;
- defm NotPt : ALU32ri_Pred<mnemonic, 1>;
+ hasSideEffects = 0, isPredicated = 1 in {
+ defm Pt : Addri_Pred<mnemonic, 0>;
+ defm NotPt : Addri_Pred<mnemonic, 1>;
}
}
}
-defm ADD_ri : ALU32ri_base<"add", "ADD", add>, ImmRegRel, PredNewRel;
-
-let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 10,
-CextOpcode = "OR", InputType = "imm" in
-def OR_ri : ALU32_ri<(outs IntRegs:$dst),
- (ins IntRegs:$src1, s10Ext:$src2),
- "$dst = or($src1, #$src2)",
- [(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1),
- s10ExtPred:$src2))]>, ImmRegRel;
+let isCodeGenOnly = 0 in
+defm ADD_ri : Addri_base<"add", add>, ImmRegRel, PredNewRel;
+//===----------------------------------------------------------------------===//
+// Template class used for the following ALU32 instructions.
+// Rd=and(Rs,#s10)
+// Rd=or(Rs,#s10)
+//===----------------------------------------------------------------------===//
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 10,
-InputType = "imm", CextOpcode = "AND" in
-def AND_ri : ALU32_ri<(outs IntRegs:$dst),
- (ins IntRegs:$src1, s10Ext:$src2),
- "$dst = and($src1, #$src2)",
- [(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1),
- s10ExtPred:$src2))]>, ImmRegRel;
+InputType = "imm", hasNewValue = 1 in
+class T_ALU32ri_logical <string mnemonic, SDNode OpNode, bits<2> MinOp>
+ : ALU32_ri <(outs IntRegs:$Rd),
+ (ins IntRegs:$Rs, s10Ext:$s10),
+ "$Rd = "#mnemonic#"($Rs, #$s10)" ,
+ [(set (i32 IntRegs:$Rd), (OpNode (i32 IntRegs:$Rs), s10ExtPred:$s10))]> {
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<10> s10;
+ let CextOpcode = mnemonic;
+
+ let IClass = 0b0111;
+
+ let Inst{27-24} = 0b0110;
+ let Inst{23-22} = MinOp;
+ let Inst{21} = s10{9};
+ let Inst{20-16} = Rs;
+ let Inst{13-5} = s10{8-0};
+ let Inst{4-0} = Rd;
+ }
-// Nop.
-let neverHasSideEffects = 1 in
-def NOP : ALU32_rr<(outs), (ins),
- "nop",
- []>;
+let isCodeGenOnly = 0 in {
+def OR_ri : T_ALU32ri_logical<"or", or, 0b10>, ImmRegRel;
+def AND_ri : T_ALU32ri_logical<"and", and, 0b00>, ImmRegRel;
+}
+// Subtract register from immediate
// Rd32=sub(#s10,Rs32)
let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 10,
-CextOpcode = "SUB", InputType = "imm" in
-def SUB_ri : ALU32_ri<(outs IntRegs:$dst),
- (ins s10Ext:$src1, IntRegs:$src2),
- "$dst = sub(#$src1, $src2)",
- [(set IntRegs:$dst, (sub s10ExtPred:$src1, IntRegs:$src2))]>,
- ImmRegRel;
+CextOpcode = "sub", InputType = "imm", hasNewValue = 1, isCodeGenOnly = 0 in
+def SUB_ri: ALU32_ri <(outs IntRegs:$Rd), (ins s10Ext:$s10, IntRegs:$Rs),
+ "$Rd = sub(#$s10, $Rs)" ,
+ [(set IntRegs:$Rd, (sub s10ExtPred:$s10, IntRegs:$Rs))] > ,
+ ImmRegRel {
+ bits<5> Rd;
+ bits<10> s10;
+ bits<5> Rs;
+
+ let IClass = 0b0111;
+
+ let Inst{27-22} = 0b011001;
+ let Inst{21} = s10{9};
+ let Inst{20-16} = Rs;
+ let Inst{13-5} = s10{8-0};
+ let Inst{4-0} = Rd;
+ }
+// Nop.
+let hasSideEffects = 0, isCodeGenOnly = 0 in
+def A2_nop: ALU32Inst <(outs), (ins), "nop" > {
+ let IClass = 0b0111;
+ let Inst{27-24} = 0b1111;
+}
// Rd = not(Rs) gets mapped to Rd=sub(#-1, Rs).
def : Pat<(not (i32 IntRegs:$src1)),
(SUB_ri -1, (i32 IntRegs:$src1))>;
-// Rd = neg(Rs) gets mapped to Rd=sub(#0, Rs).
-// Pattern definition for 'neg' was not necessary.
-
-multiclass TFR_Pred<bit PredNot> {
- let isPredicatedFalse = PredNot in {
- def _c#NAME : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- !if(PredNot, "if (!$src1", "if ($src1")#") $dst = $src2",
- []>;
- // Predicate new
- let isPredicatedNew = 1 in
- def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- !if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = $src2",
- []>;
+let hasSideEffects = 0, hasNewValue = 1 in
+class T_tfr16<bit isHi>
+ : ALU32Inst <(outs IntRegs:$Rx), (ins IntRegs:$src1, u16Imm:$u16),
+ "$Rx"#!if(isHi, ".h", ".l")#" = #$u16",
+ [], "$src1 = $Rx" > {
+ bits<5> Rx;
+ bits<16> u16;
+
+ let IClass = 0b0111;
+ let Inst{27-26} = 0b00;
+ let Inst{25-24} = !if(isHi, 0b10, 0b01);
+ let Inst{23-22} = u16{15-14};
+ let Inst{21} = 0b1;
+ let Inst{20-16} = Rx;
+ let Inst{13-0} = u16{13-0};
}
-}
-
-let InputType = "reg", neverHasSideEffects = 1 in
-multiclass TFR_base<string CextOp> {
- let CextOpcode = CextOp, BaseOpcode = CextOp in {
- let isPredicable = 1 in
- def NAME : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = $src1",
- []>;
- let isPredicated = 1 in {
- defm Pt : TFR_Pred<0>;
- defm NotPt : TFR_Pred<1>;
- }
- }
+let isCodeGenOnly = 0 in {
+def A2_tfril: T_tfr16<0>;
+def A2_tfrih: T_tfr16<1>;
}
-class T_TFR64_Pred<bit PredNot, bit isPredNew>
- : ALU32_rr<(outs DoubleRegs:$dst),
- (ins PredRegs:$src1, DoubleRegs:$src2),
- !if(PredNot, "if (!$src1", "if ($src1")#
- !if(isPredNew, ".new) ", ") ")#"$dst = $src2", []>
-{
+// Conditional transfer is an alias to conditional "Rd = add(Rs, #0)".
+let isPredicated = 1, hasNewValue = 1, opNewValue = 0 in
+class T_tfr_pred<bit isPredNot, bit isPredNew>
+ : ALU32Inst<(outs IntRegs:$dst),
+ (ins PredRegs:$src1, IntRegs:$src2),
+ "if ("#!if(isPredNot, "!", "")#
+ "$src1"#!if(isPredNew, ".new", "")#
+ ") $dst = $src2"> {
bits<5> dst;
bits<2> src1;
bits<5> src2;
- let IClass = 0b1111;
- let Inst{27-24} = 0b1101;
+ let isPredicatedFalse = isPredNot;
+ let isPredicatedNew = isPredNew;
+ let IClass = 0b0111;
+
+ let Inst{27-24} = 0b0100;
+ let Inst{23} = isPredNot;
let Inst{13} = isPredNew;
- let Inst{7} = PredNot;
+ let Inst{12-5} = 0;
let Inst{4-0} = dst;
- let Inst{6-5} = src1;
- let Inst{20-17} = src2{4-1};
- let Inst{16} = 0b1;
- let Inst{12-9} = src2{4-1};
- let Inst{8} = 0b0;
-}
+ let Inst{22-21} = src1;
+ let Inst{20-16} = src2;
+ }
-multiclass TFR64_Pred<bit PredNot> {
- let isPredicatedFalse = PredNot in {
- def _c#NAME : T_TFR64_Pred<PredNot, 0>;
+let isPredicable = 1 in
+class T_tfr : ALU32Inst<(outs IntRegs:$dst), (ins IntRegs:$src),
+ "$dst = $src"> {
+ bits<5> dst;
+ bits<5> src;
- let isPredicatedNew = 1 in
- def _cdn#NAME : T_TFR64_Pred<PredNot, 1>; // Predicate new
+ let IClass = 0b0111;
+
+ let Inst{27-21} = 0b0000011;
+ let Inst{20-16} = src;
+ let Inst{13} = 0b0;
+ let Inst{4-0} = dst;
}
-}
-let neverHasSideEffects = 1 in
-multiclass TFR64_base<string BaseName> {
- let BaseOpcode = BaseName in {
- let isPredicable = 1 in
- def NAME : ALU32Inst <(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1),
- "$dst = $src1" > {
- bits<5> dst;
- bits<5> src1;
-
- let IClass = 0b1111;
- let Inst{27-23} = 0b01010;
- let Inst{4-0} = dst;
- let Inst{20-17} = src1{4-1};
- let Inst{16} = 0b1;
- let Inst{12-9} = src1{4-1};
- let Inst{8} = 0b0;
- }
+let InputType = "reg", hasNewValue = 1, hasSideEffects = 0 in
+multiclass tfr_base<string CextOp> {
+ let CextOpcode = CextOp, BaseOpcode = CextOp in {
+ def NAME : T_tfr;
- let isPredicated = 1 in {
- defm Pt : TFR64_Pred<0>;
- defm NotPt : TFR64_Pred<1>;
- }
+ // Predicate
+ def t : T_tfr_pred<0, 0>;
+ def f : T_tfr_pred<1, 0>;
+ // Predicate new
+ def tnew : T_tfr_pred<0, 1>;
+ def fnew : T_tfr_pred<1, 1>;
}
}
-multiclass TFRI_Pred<bit PredNot> {
- let isMoveImm = 1, isPredicatedFalse = PredNot in {
- def _c#NAME : ALU32_ri<(outs IntRegs:$dst),
- (ins PredRegs:$src1, s12Ext:$src2),
- !if(PredNot, "if (!$src1", "if ($src1")#") $dst = #$src2",
- []>;
+// Assembler mapped to C2_ccombinew[t|f|newt|newf].
+// Please don't add bits to this instruction as it'll be converted into
+// 'combine' before object code emission.
+let isPredicated = 1 in
+class T_tfrp_pred<bit PredNot, bit PredNew>
+ : ALU32_rr <(outs DoubleRegs:$dst),
+ (ins PredRegs:$src1, DoubleRegs:$src2),
+ "if ("#!if(PredNot, "!", "")#"$src1"
+ #!if(PredNew, ".new", "")#") $dst = $src2" > {
+ let isPredicatedFalse = PredNot;
+ let isPredicatedNew = PredNew;
+ }
+// Assembler mapped to A2_combinew.
+// Please don't add bits to this instruction as it'll be converted into
+// 'combine' before object code emission.
+class T_tfrp : ALU32Inst <(outs DoubleRegs:$dst),
+ (ins DoubleRegs:$src),
+ "$dst = $src">;
+
+let hasSideEffects = 0 in
+multiclass TFR64_base<string BaseName> {
+ let BaseOpcode = BaseName in {
+ let isPredicable = 1 in
+ def NAME : T_tfrp;
+ // Predicate
+ def t : T_tfrp_pred <0, 0>;
+ def f : T_tfrp_pred <1, 0>;
// Predicate new
- let isPredicatedNew = 1 in
- def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst),
- (ins PredRegs:$src1, s12Ext:$src2),
- !if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = #$src2",
- []>;
+ def tnew : T_tfrp_pred <0, 1>;
+ def fnew : T_tfrp_pred <1, 1>;
}
}
-let InputType = "imm", isExtendable = 1, isExtentSigned = 1 in
-multiclass TFRI_base<string CextOp> {
- let CextOpcode = CextOp, BaseOpcode = CextOp#I in {
- let isAsCheapAsAMove = 1 , opExtendable = 1, opExtentBits = 16,
- isMoveImm = 1, isPredicable = 1, isReMaterializable = 1 in
- def NAME : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1),
- "$dst = #$src1",
- [(set (i32 IntRegs:$dst), s16ExtPred:$src1)]>;
+let InputType = "imm", isExtendable = 1, isExtentSigned = 1, opExtentBits = 12,
+ isMoveImm = 1, opExtendable = 2, BaseOpcode = "TFRI", CextOpcode = "TFR",
+ hasSideEffects = 0, isPredicated = 1, hasNewValue = 1 in
+class T_TFRI_Pred<bit PredNot, bit PredNew>
+ : ALU32_ri<(outs IntRegs:$Rd), (ins PredRegs:$Pu, s12Ext:$s12),
+ "if ("#!if(PredNot,"!","")#"$Pu"#!if(PredNew,".new","")#") $Rd = #$s12",
+ [], "", ALU32_2op_tc_1_SLOT0123>, ImmRegRel, PredNewRel {
+ let isPredicatedFalse = PredNot;
+ let isPredicatedNew = PredNew;
+
+ bits<5> Rd;
+ bits<2> Pu;
+ bits<12> s12;
+
+ let IClass = 0b0111;
+ let Inst{27-24} = 0b1110;
+ let Inst{23} = PredNot;
+ let Inst{22-21} = Pu;
+ let Inst{20} = 0b0;
+ let Inst{19-16,12-5} = s12;
+ let Inst{13} = PredNew;
+ let Inst{4-0} = Rd;
+}
- let opExtendable = 2, opExtentBits = 12, neverHasSideEffects = 1,
- isPredicated = 1 in {
- defm Pt : TFRI_Pred<0>;
- defm NotPt : TFRI_Pred<1>;
- }
- }
+let isCodeGenOnly = 0 in {
+def C2_cmoveit : T_TFRI_Pred<0, 0>;
+def C2_cmoveif : T_TFRI_Pred<1, 0>;
+def C2_cmovenewit : T_TFRI_Pred<0, 1>;
+def C2_cmovenewif : T_TFRI_Pred<1, 1>;
}
-defm TFRI : TFRI_base<"TFR">, ImmRegRel, PredNewRel;
-defm TFR : TFR_base<"TFR">, ImmRegRel, PredNewRel;
-defm TFR64 : TFR64_base<"TFR64">, PredNewRel;
+let InputType = "imm", isExtendable = 1, isExtentSigned = 1,
+ CextOpcode = "TFR", BaseOpcode = "TFRI", hasNewValue = 1, opNewValue = 0,
+ isAsCheapAsAMove = 1 , opExtendable = 1, opExtentBits = 16, isMoveImm = 1,
+ isPredicated = 0, isPredicable = 1, isReMaterializable = 1,
+ isCodeGenOnly = 0 in
+def A2_tfrsi : ALU32Inst<(outs IntRegs:$Rd), (ins s16Ext:$s16), "$Rd = #$s16",
+ [(set (i32 IntRegs:$Rd), s16ExtPred:$s16)], "", ALU32_2op_tc_1_SLOT0123>,
+ ImmRegRel, PredRel {
+ bits<5> Rd;
+ bits<16> s16;
+
+ let IClass = 0b0111;
+ let Inst{27-24} = 0b1000;
+ let Inst{23-22,20-16,13-5} = s16;
+ let Inst{4-0} = Rd;
+}
+
+let isCodeGenOnly = 0 in
+defm A2_tfr : tfr_base<"TFR">, ImmRegRel, PredNewRel;
+defm A2_tfrp : TFR64_base<"TFR64">, PredNewRel;
+
+// Assembler mapped
+let isReMaterializable = 1, isMoveImm = 1, isAsCheapAsAMove = 1 in
+def A2_tfrpi : ALU64_rr<(outs DoubleRegs:$dst), (ins s8Imm64:$src1),
+ "$dst = #$src1",
+ [(set (i64 DoubleRegs:$dst), s8Imm64Pred:$src1)]>;
+
+// TODO: see if this instruction can be deleted..
+let isExtendable = 1, opExtendable = 1, opExtentBits = 6 in
+def TFRI64_V4 : ALU64_rr<(outs DoubleRegs:$dst), (ins u6Ext:$src1),
+ "$dst = #$src1">;
-// Transfer control register.
-let neverHasSideEffects = 1 in
-def TFCR : CRInst<(outs CRRegs:$dst), (ins IntRegs:$src1),
- "$dst = $src1",
- []>;
//===----------------------------------------------------------------------===//
// ALU32/ALU -
//===----------------------------------------------------------------------===//
@@ -383,105 +622,190 @@ def TFCR : CRInst<(outs CRRegs:$dst), (ins IntRegs:$src1),
//===----------------------------------------------------------------------===//
// ALU32/PERM +
//===----------------------------------------------------------------------===//
+// Scalar mux register immediate.
+let hasSideEffects = 0, isExtentSigned = 1, CextOpcode = "MUX",
+ InputType = "imm", hasNewValue = 1, isExtendable = 1, opExtentBits = 8 in
+class T_MUX1 <bit MajOp, dag ins, string AsmStr>
+ : ALU32Inst <(outs IntRegs:$Rd), ins, AsmStr>, ImmRegRel {
+ bits<5> Rd;
+ bits<2> Pu;
+ bits<8> s8;
+ bits<5> Rs;
+
+ let IClass = 0b0111;
+ let Inst{27-24} = 0b0011;
+ let Inst{23} = MajOp;
+ let Inst{22-21} = Pu;
+ let Inst{20-16} = Rs;
+ let Inst{13} = 0b0;
+ let Inst{12-5} = s8;
+ let Inst{4-0} = Rd;
+}
-let neverHasSideEffects = 1 in
-def COMBINE_ii : ALU32_ii<(outs DoubleRegs:$dst),
- (ins s8Imm:$src1, s8Imm:$src2),
- "$dst = combine(#$src1, #$src2)",
- []>;
+let opExtendable = 2, isCodeGenOnly = 0 in
+def C2_muxri : T_MUX1<0b1, (ins PredRegs:$Pu, s8Ext:$s8, IntRegs:$Rs),
+ "$Rd = mux($Pu, #$s8, $Rs)">;
+
+let opExtendable = 3, isCodeGenOnly = 0 in
+def C2_muxir : T_MUX1<0b0, (ins PredRegs:$Pu, IntRegs:$Rs, s8Ext:$s8),
+ "$Rd = mux($Pu, $Rs, #$s8)">;
+
+def : Pat<(i32 (select I1:$Pu, s8ExtPred:$s8, I32:$Rs)),
+ (C2_muxri I1:$Pu, s8ExtPred:$s8, I32:$Rs)>;
+
+def : Pat<(i32 (select I1:$Pu, I32:$Rs, s8ExtPred:$s8)),
+ (C2_muxir I1:$Pu, I32:$Rs, s8ExtPred:$s8)>;
+
+// C2_muxii: Scalar mux immediates.
+let isExtentSigned = 1, hasNewValue = 1, isExtendable = 1,
+ opExtentBits = 8, opExtendable = 2, isCodeGenOnly = 0 in
+def C2_muxii: ALU32Inst <(outs IntRegs:$Rd),
+ (ins PredRegs:$Pu, s8Ext:$s8, s8Imm:$S8),
+ "$Rd = mux($Pu, #$s8, #$S8)" ,
+ [(set (i32 IntRegs:$Rd),
+ (i32 (select I1:$Pu, s8ExtPred:$s8, s8ImmPred:$S8)))] > {
+ bits<5> Rd;
+ bits<2> Pu;
+ bits<8> s8;
+ bits<8> S8;
+
+ let IClass = 0b0111;
+
+ let Inst{27-25} = 0b101;
+ let Inst{24-23} = Pu;
+ let Inst{22-16} = S8{7-1};
+ let Inst{13} = S8{0};
+ let Inst{12-5} = s8;
+ let Inst{4-0} = Rd;
+ }
-// Mux.
-def VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1,
- DoubleRegs:$src2,
- DoubleRegs:$src3),
- "$dst = vmux($src1, $src2, $src3)",
- []>;
+//===----------------------------------------------------------------------===//
+// template class for non-predicated alu32_2op instructions
+// - aslh, asrh, sxtb, sxth, zxth
+//===----------------------------------------------------------------------===//
+let hasNewValue = 1, opNewValue = 0 in
+class T_ALU32_2op <string mnemonic, bits<3> minOp> :
+ ALU32Inst < (outs IntRegs:$Rd), (ins IntRegs:$Rs),
+ "$Rd = "#mnemonic#"($Rs)", [] > {
+ bits<5> Rd;
+ bits<5> Rs;
+
+ let IClass = 0b0111;
+
+ let Inst{27-24} = 0b0000;
+ let Inst{23-21} = minOp;
+ let Inst{13} = 0b0;
+ let Inst{4-0} = Rd;
+ let Inst{20-16} = Rs;
+}
+
+//===----------------------------------------------------------------------===//
+// template class for predicated alu32_2op instructions
+// - aslh, asrh, sxtb, sxth, zxtb, zxth
+//===----------------------------------------------------------------------===//
+let hasSideEffects = 0, validSubTargets = HasV4SubT,
+ hasNewValue = 1, opNewValue = 0 in
+class T_ALU32_2op_Pred <string mnemonic, bits<3> minOp, bit isPredNot,
+ bit isPredNew > :
+ ALU32Inst <(outs IntRegs:$Rd), (ins PredRegs:$Pu, IntRegs:$Rs),
+ !if(isPredNot, "if (!$Pu", "if ($Pu")
+ #!if(isPredNew, ".new) ",") ")#"$Rd = "#mnemonic#"($Rs)"> {
+ bits<5> Rd;
+ bits<2> Pu;
+ bits<5> Rs;
+
+ let IClass = 0b0111;
+
+ let Inst{27-24} = 0b0000;
+ let Inst{23-21} = minOp;
+ let Inst{13} = 0b1;
+ let Inst{11} = isPredNot;
+ let Inst{10} = isPredNew;
+ let Inst{4-0} = Rd;
+ let Inst{9-8} = Pu;
+ let Inst{20-16} = Rs;
+}
-let CextOpcode = "MUX", InputType = "reg" in
-def MUX_rr : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1,
- IntRegs:$src2, IntRegs:$src3),
- "$dst = mux($src1, $src2, $src3)",
- [(set (i32 IntRegs:$dst),
- (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2),
- (i32 IntRegs:$src3))))]>, ImmRegRel;
-
-let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
-CextOpcode = "MUX", InputType = "imm" in
-def MUX_ir : ALU32_ir<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Ext:$src2,
- IntRegs:$src3),
- "$dst = mux($src1, #$src2, $src3)",
- [(set (i32 IntRegs:$dst),
- (i32 (select (i1 PredRegs:$src1), s8ExtPred:$src2,
- (i32 IntRegs:$src3))))]>, ImmRegRel;
-
-let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8,
-CextOpcode = "MUX", InputType = "imm" in
-def MUX_ri : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2,
- s8Ext:$src3),
- "$dst = mux($src1, $src2, #$src3)",
- [(set (i32 IntRegs:$dst),
- (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2),
- s8ExtPred:$src3)))]>, ImmRegRel;
-
-let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in
-def MUX_ii : ALU32_ii<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Ext:$src2,
- s8Imm:$src3),
- "$dst = mux($src1, #$src2, #$src3)",
- [(set (i32 IntRegs:$dst), (i32 (select (i1 PredRegs:$src1),
- s8ExtPred:$src2,
- s8ImmPred:$src3)))]>;
-
-// ALU32 - aslh, asrh, sxtb, sxth, zxtb, zxth
-multiclass ALU32_2op_Pbase<string mnemonic, bit isNot, bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME : ALU32Inst<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ",
- ") $dst = ")#mnemonic#"($src2)">,
- Requires<[HasV4T]>;
-}
-
-multiclass ALU32_2op_Pred<string mnemonic, bit PredNot> {
+multiclass ALU32_2op_Pred<string mnemonic, bits<3> minOp, bit PredNot> {
let isPredicatedFalse = PredNot in {
- defm _c#NAME : ALU32_2op_Pbase<mnemonic, PredNot, 0>;
+ def NAME : T_ALU32_2op_Pred<mnemonic, minOp, PredNot, 0>;
+
// Predicate new
- defm _cdn#NAME : ALU32_2op_Pbase<mnemonic, PredNot, 1>;
+ let isPredicatedNew = 1 in
+ def NAME#new : T_ALU32_2op_Pred<mnemonic, minOp, PredNot, 1>;
}
}
-multiclass ALU32_2op_base<string mnemonic> {
+multiclass ALU32_2op_base<string mnemonic, bits<3> minOp> {
let BaseOpcode = mnemonic in {
- let isPredicable = 1, neverHasSideEffects = 1 in
- def NAME : ALU32Inst<(outs IntRegs:$dst),
- (ins IntRegs:$src1),
- "$dst = "#mnemonic#"($src1)">;
-
- let Predicates = [HasV4T], validSubTargets = HasV4SubT, isPredicated = 1,
- neverHasSideEffects = 1 in {
- defm Pt_V4 : ALU32_2op_Pred<mnemonic, 0>;
- defm NotPt_V4 : ALU32_2op_Pred<mnemonic, 1>;
+ let isPredicable = 1, hasSideEffects = 0 in
+ def A2_#NAME : T_ALU32_2op<mnemonic, minOp>;
+
+ let validSubTargets = HasV4SubT, isPredicated = 1, hasSideEffects = 0 in {
+ defm A4_p#NAME#t : ALU32_2op_Pred<mnemonic, minOp, 0>;
+ defm A4_p#NAME#f : ALU32_2op_Pred<mnemonic, minOp, 1>;
}
}
}
-defm ASLH : ALU32_2op_base<"aslh">, PredNewRel;
-defm ASRH : ALU32_2op_base<"asrh">, PredNewRel;
-defm SXTB : ALU32_2op_base<"sxtb">, PredNewRel;
-defm SXTH : ALU32_2op_base<"sxth">, PredNewRel;
-defm ZXTB : ALU32_2op_base<"zxtb">, PredNewRel;
-defm ZXTH : ALU32_2op_base<"zxth">, PredNewRel;
+let isCodeGenOnly = 0 in {
+defm aslh : ALU32_2op_base<"aslh", 0b000>, PredNewRel;
+defm asrh : ALU32_2op_base<"asrh", 0b001>, PredNewRel;
+defm sxtb : ALU32_2op_base<"sxtb", 0b101>, PredNewRel;
+defm sxth : ALU32_2op_base<"sxth", 0b111>, PredNewRel;
+defm zxth : ALU32_2op_base<"zxth", 0b110>, PredNewRel;
+}
-def : Pat <(shl (i32 IntRegs:$src1), (i32 16)),
- (ASLH IntRegs:$src1)>;
+// Rd=zxtb(Rs): assembler mapped to Rd=and(Rs,#255).
+// Compiler would want to generate 'zxtb' instead of 'and' becuase 'zxtb' has
+// predicated forms while 'and' doesn't. Since integrated assembler can't
+// handle 'mapped' instructions, we need to encode 'zxtb' same as 'and' where
+// immediate operand is set to '255'.
+
+let hasNewValue = 1, opNewValue = 0 in
+class T_ZXTB: ALU32Inst < (outs IntRegs:$Rd), (ins IntRegs:$Rs),
+ "$Rd = zxtb($Rs)", [] > { // Rd = and(Rs,255)
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<10> s10 = 255;
+
+ let IClass = 0b0111;
+
+ let Inst{27-22} = 0b011000;
+ let Inst{4-0} = Rd;
+ let Inst{20-16} = Rs;
+ let Inst{21} = s10{9};
+ let Inst{13-5} = s10{8-0};
+}
-def : Pat <(sra (i32 IntRegs:$src1), (i32 16)),
- (ASRH IntRegs:$src1)>;
+//Rd=zxtb(Rs): assembler mapped to "Rd=and(Rs,#255)
+multiclass ZXTB_base <string mnemonic, bits<3> minOp> {
+ let BaseOpcode = mnemonic in {
+ let isPredicable = 1, hasSideEffects = 0 in
+ def A2_#NAME : T_ZXTB;
-def : Pat <(sext_inreg (i32 IntRegs:$src1), i8),
- (SXTB IntRegs:$src1)>;
+ let validSubTargets = HasV4SubT, isPredicated = 1, hasSideEffects = 0 in {
+ defm A4_p#NAME#t : ALU32_2op_Pred<mnemonic, minOp, 0>;
+ defm A4_p#NAME#f : ALU32_2op_Pred<mnemonic, minOp, 1>;
+ }
+ }
+}
+
+let isCodeGenOnly=0 in
+defm zxtb : ZXTB_base<"zxtb",0b100>, PredNewRel;
+
+def: Pat<(shl I32:$src1, (i32 16)), (A2_aslh I32:$src1)>;
+def: Pat<(sra I32:$src1, (i32 16)), (A2_asrh I32:$src1)>;
+def: Pat<(sext_inreg I32:$src1, i8), (A2_sxtb I32:$src1)>;
+def: Pat<(sext_inreg I32:$src1, i16), (A2_sxth I32:$src1)>;
+
+// Mux.
+def VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1,
+ DoubleRegs:$src2,
+ DoubleRegs:$src3),
+ "$dst = vmux($src1, $src2, $src3)",
+ []>;
-def : Pat <(sext_inreg (i32 IntRegs:$src1), i16),
- (SXTH IntRegs:$src1)>;
//===----------------------------------------------------------------------===//
// ALU32/PERM -
@@ -492,11 +816,6 @@ def : Pat <(sext_inreg (i32 IntRegs:$src1), i16),
// ALU32/PRED +
//===----------------------------------------------------------------------===//
-// Compare.
-defm CMPGTU : CMP32_rr_ri_u9<"cmp.gtu", "CMPGTU", setugt>, ImmRegRel;
-defm CMPGT : CMP32_rr_ri_s10<"cmp.gt", "CMPGT", setgt>, ImmRegRel;
-defm CMPEQ : CMP32_rr_ri_s10<"cmp.eq", "CMPEQ", seteq>, ImmRegRel;
-
// SDNode for converting immediate C to C-1.
def DEC_CONST_SIGNED : SDNodeXForm<imm, [{
// Return the byte immediate const-1 as an SDNode.
@@ -511,14 +830,6 @@ def DEC_CONST_UNSIGNED : SDNodeXForm<imm, [{
return XformUToUM1Imm(imm);
}]>;
-def CTLZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = cl0($src1)",
- [(set (i32 IntRegs:$dst), (ctlz (i32 IntRegs:$src1)))]>;
-
-def CTTZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1),
- "$dst = ct0($src1)",
- [(set (i32 IntRegs:$dst), (cttz (i32 IntRegs:$src1)))]>;
-
def CTLZ64_rr : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1),
"$dst = cl0($src1)",
[(set (i32 IntRegs:$dst), (i32 (trunc (ctlz (i64 DoubleRegs:$src1)))))]>;
@@ -527,16 +838,6 @@ def CTTZ64_rr : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1),
"$dst = ct0($src1)",
[(set (i32 IntRegs:$dst), (i32 (trunc (cttz (i64 DoubleRegs:$src1)))))]>;
-def TSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = tstbit($src1, $src2)",
- [(set (i1 PredRegs:$dst),
- (setne (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>;
-
-def TSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
- "$dst = tstbit($src1, $src2)",
- [(set (i1 PredRegs:$dst),
- (setne (and (shl 1, (u5ImmPred:$src2)), (i32 IntRegs:$src1)), 0))]>;
-
//===----------------------------------------------------------------------===//
// ALU32/PRED -
//===----------------------------------------------------------------------===//
@@ -544,114 +845,279 @@ def TSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
//===----------------------------------------------------------------------===//
// ALU64/ALU +
+//===----------------------------------------------------------------------===//// Add.
+//===----------------------------------------------------------------------===//
+// Template Class
+// Add/Subtract halfword
+// Rd=add(Rt.L,Rs.[HL])[:sat]
+// Rd=sub(Rt.L,Rs.[HL])[:sat]
+// Rd=add(Rt.[LH],Rs.[HL])[:sat][:<16]
+// Rd=sub(Rt.[LH],Rs.[HL])[:sat][:<16]
//===----------------------------------------------------------------------===//
-// Add.
-def ADD64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
- DoubleRegs:$src2),
- "$dst = add($src1, $src2)",
- [(set (i64 DoubleRegs:$dst), (add (i64 DoubleRegs:$src1),
- (i64 DoubleRegs:$src2)))]>;
-// Add halfword.
+let hasNewValue = 1, opNewValue = 0 in
+class T_XTYPE_ADD_SUB <bits<2> LHbits, bit isSat, bit hasShift, bit isSub>
+ : ALU64Inst <(outs IntRegs:$Rd), (ins IntRegs:$Rt, IntRegs:$Rs),
+ "$Rd = "#!if(isSub,"sub","add")#"($Rt."
+ #!if(hasShift, !if(LHbits{1},"h","l"),"l") #", $Rs."
+ #!if(hasShift, !if(LHbits{0},"h)","l)"), !if(LHbits{1},"h)","l)"))
+ #!if(isSat,":sat","")
+ #!if(hasShift,":<<16",""), [], "", ALU64_tc_1_SLOT23> {
+ bits<5> Rd;
+ bits<5> Rt;
+ bits<5> Rs;
+ let IClass = 0b1101;
+
+ let Inst{27-23} = 0b01010;
+ let Inst{22} = hasShift;
+ let Inst{21} = isSub;
+ let Inst{7} = isSat;
+ let Inst{6-5} = LHbits;
+ let Inst{4-0} = Rd;
+ let Inst{12-8} = Rt;
+ let Inst{20-16} = Rs;
+ }
-// Compare.
-defm CMPEHexagon4 : CMP64_rr<"cmp.eq", seteq>;
-defm CMPGT64 : CMP64_rr<"cmp.gt", setgt>;
-defm CMPGTU64 : CMP64_rr<"cmp.gtu", setugt>;
-
-// Logical operations.
-def AND_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
- DoubleRegs:$src2),
- "$dst = and($src1, $src2)",
- [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1),
- (i64 DoubleRegs:$src2)))]>;
-
-def OR_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
- DoubleRegs:$src2),
- "$dst = or($src1, $src2)",
- [(set (i64 DoubleRegs:$dst), (or (i64 DoubleRegs:$src1),
- (i64 DoubleRegs:$src2)))]>;
-
-def XOR_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
- DoubleRegs:$src2),
- "$dst = xor($src1, $src2)",
- [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1),
- (i64 DoubleRegs:$src2)))]>;
-
-// Maximum.
-def MAXw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = max($src2, $src1)",
- [(set (i32 IntRegs:$dst),
- (i32 (select (i1 (setlt (i32 IntRegs:$src2),
- (i32 IntRegs:$src1))),
- (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>;
+//Rd=sub(Rt.L,Rs.[LH])
+let isCodeGenOnly = 0 in {
+def A2_subh_l16_ll : T_XTYPE_ADD_SUB <0b00, 0, 0, 1>;
+def A2_subh_l16_hl : T_XTYPE_ADD_SUB <0b10, 0, 0, 1>;
+}
-def MAXUw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = maxu($src2, $src1)",
- [(set (i32 IntRegs:$dst),
- (i32 (select (i1 (setult (i32 IntRegs:$src2),
- (i32 IntRegs:$src1))),
- (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>;
-
-def MAXd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
- DoubleRegs:$src2),
- "$dst = max($src2, $src1)",
- [(set (i64 DoubleRegs:$dst),
- (i64 (select (i1 (setlt (i64 DoubleRegs:$src2),
- (i64 DoubleRegs:$src1))),
- (i64 DoubleRegs:$src1),
- (i64 DoubleRegs:$src2))))]>;
-
-def MAXUd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
- DoubleRegs:$src2),
- "$dst = maxu($src2, $src1)",
- [(set (i64 DoubleRegs:$dst),
- (i64 (select (i1 (setult (i64 DoubleRegs:$src2),
- (i64 DoubleRegs:$src1))),
- (i64 DoubleRegs:$src1),
- (i64 DoubleRegs:$src2))))]>;
-
-// Minimum.
-def MINw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = min($src2, $src1)",
- [(set (i32 IntRegs:$dst),
- (i32 (select (i1 (setgt (i32 IntRegs:$src2),
- (i32 IntRegs:$src1))),
- (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>;
+let isCodeGenOnly = 0 in {
+//Rd=add(Rt.L,Rs.[LH])
+def A2_addh_l16_ll : T_XTYPE_ADD_SUB <0b00, 0, 0, 0>;
+def A2_addh_l16_hl : T_XTYPE_ADD_SUB <0b10, 0, 0, 0>;
+}
-def MINUw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = minu($src2, $src1)",
- [(set (i32 IntRegs:$dst),
- (i32 (select (i1 (setugt (i32 IntRegs:$src2),
- (i32 IntRegs:$src1))),
- (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>;
-
-def MINd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
- DoubleRegs:$src2),
- "$dst = min($src2, $src1)",
- [(set (i64 DoubleRegs:$dst),
- (i64 (select (i1 (setgt (i64 DoubleRegs:$src2),
- (i64 DoubleRegs:$src1))),
- (i64 DoubleRegs:$src1),
- (i64 DoubleRegs:$src2))))]>;
-
-def MINUd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
- DoubleRegs:$src2),
- "$dst = minu($src2, $src1)",
- [(set (i64 DoubleRegs:$dst),
- (i64 (select (i1 (setugt (i64 DoubleRegs:$src2),
- (i64 DoubleRegs:$src1))),
- (i64 DoubleRegs:$src1),
- (i64 DoubleRegs:$src2))))]>;
-
-// Subtract.
-def SUB64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
- DoubleRegs:$src2),
- "$dst = sub($src1, $src2)",
- [(set (i64 DoubleRegs:$dst), (sub (i64 DoubleRegs:$src1),
- (i64 DoubleRegs:$src2)))]>;
+let Itinerary = ALU64_tc_2_SLOT23, Defs = [USR_OVF], isCodeGenOnly = 0 in {
+ //Rd=sub(Rt.L,Rs.[LH]):sat
+ def A2_subh_l16_sat_ll : T_XTYPE_ADD_SUB <0b00, 1, 0, 1>;
+ def A2_subh_l16_sat_hl : T_XTYPE_ADD_SUB <0b10, 1, 0, 1>;
+
+ //Rd=add(Rt.L,Rs.[LH]):sat
+ def A2_addh_l16_sat_ll : T_XTYPE_ADD_SUB <0b00, 1, 0, 0>;
+ def A2_addh_l16_sat_hl : T_XTYPE_ADD_SUB <0b10, 1, 0, 0>;
+}
+
+//Rd=sub(Rt.[LH],Rs.[LH]):<<16
+let isCodeGenOnly = 0 in {
+def A2_subh_h16_ll : T_XTYPE_ADD_SUB <0b00, 0, 1, 1>;
+def A2_subh_h16_lh : T_XTYPE_ADD_SUB <0b01, 0, 1, 1>;
+def A2_subh_h16_hl : T_XTYPE_ADD_SUB <0b10, 0, 1, 1>;
+def A2_subh_h16_hh : T_XTYPE_ADD_SUB <0b11, 0, 1, 1>;
+}
+
+//Rd=add(Rt.[LH],Rs.[LH]):<<16
+let isCodeGenOnly = 0 in {
+def A2_addh_h16_ll : T_XTYPE_ADD_SUB <0b00, 0, 1, 0>;
+def A2_addh_h16_lh : T_XTYPE_ADD_SUB <0b01, 0, 1, 0>;
+def A2_addh_h16_hl : T_XTYPE_ADD_SUB <0b10, 0, 1, 0>;
+def A2_addh_h16_hh : T_XTYPE_ADD_SUB <0b11, 0, 1, 0>;
+}
+
+let Itinerary = ALU64_tc_2_SLOT23, Defs = [USR_OVF], isCodeGenOnly = 0 in {
+ //Rd=sub(Rt.[LH],Rs.[LH]):sat:<<16
+ def A2_subh_h16_sat_ll : T_XTYPE_ADD_SUB <0b00, 1, 1, 1>;
+ def A2_subh_h16_sat_lh : T_XTYPE_ADD_SUB <0b01, 1, 1, 1>;
+ def A2_subh_h16_sat_hl : T_XTYPE_ADD_SUB <0b10, 1, 1, 1>;
+ def A2_subh_h16_sat_hh : T_XTYPE_ADD_SUB <0b11, 1, 1, 1>;
+
+ //Rd=add(Rt.[LH],Rs.[LH]):sat:<<16
+ def A2_addh_h16_sat_ll : T_XTYPE_ADD_SUB <0b00, 1, 1, 0>;
+ def A2_addh_h16_sat_lh : T_XTYPE_ADD_SUB <0b01, 1, 1, 0>;
+ def A2_addh_h16_sat_hl : T_XTYPE_ADD_SUB <0b10, 1, 1, 0>;
+ def A2_addh_h16_sat_hh : T_XTYPE_ADD_SUB <0b11, 1, 1, 0>;
+}
+
+// Add halfword.
+def: Pat<(sext_inreg (add I32:$src1, I32:$src2), i16),
+ (A2_addh_l16_ll I32:$src1, I32:$src2)>;
+
+def: Pat<(sra (add (shl I32:$src1, (i32 16)), I32:$src2), (i32 16)),
+ (A2_addh_l16_hl I32:$src1, I32:$src2)>;
+
+def: Pat<(shl (add I32:$src1, I32:$src2), (i32 16)),
+ (A2_addh_h16_ll I32:$src1, I32:$src2)>;
// Subtract halfword.
+def: Pat<(sext_inreg (sub I32:$src1, I32:$src2), i16),
+ (A2_subh_l16_ll I32:$src1, I32:$src2)>;
+
+def: Pat<(shl (sub I32:$src1, I32:$src2), (i32 16)),
+ (A2_subh_h16_ll I32:$src1, I32:$src2)>;
+
+let hasSideEffects = 0, hasNewValue = 1, isCodeGenOnly = 0 in
+def S2_parityp: ALU64Inst<(outs IntRegs:$Rd),
+ (ins DoubleRegs:$Rs, DoubleRegs:$Rt),
+ "$Rd = parity($Rs, $Rt)", [], "", ALU64_tc_2_SLOT23> {
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1101;
+ let Inst{27-24} = 0b0000;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ let Inst{4-0} = Rd;
+}
+
+let hasNewValue = 1, opNewValue = 0, hasSideEffects = 0 in
+class T_XTYPE_MIN_MAX < bit isMax, bit isUnsigned >
+ : ALU64Inst < (outs IntRegs:$Rd), (ins IntRegs:$Rt, IntRegs:$Rs),
+ "$Rd = "#!if(isMax,"max","min")#!if(isUnsigned,"u","")
+ #"($Rt, $Rs)", [], "", ALU64_tc_2_SLOT23> {
+ bits<5> Rd;
+ bits<5> Rt;
+ bits<5> Rs;
+
+ let IClass = 0b1101;
+
+ let Inst{27-23} = 0b01011;
+ let Inst{22-21} = !if(isMax, 0b10, 0b01);
+ let Inst{7} = isUnsigned;
+ let Inst{4-0} = Rd;
+ let Inst{12-8} = !if(isMax, Rs, Rt);
+ let Inst{20-16} = !if(isMax, Rt, Rs);
+ }
+
+let isCodeGenOnly = 0 in {
+def A2_min : T_XTYPE_MIN_MAX < 0, 0 >;
+def A2_minu : T_XTYPE_MIN_MAX < 0, 1 >;
+def A2_max : T_XTYPE_MIN_MAX < 1, 0 >;
+def A2_maxu : T_XTYPE_MIN_MAX < 1, 1 >;
+}
+
+// Here, depending on the operand being selected, we'll either generate a
+// min or max instruction.
+// Ex:
+// (a>b)?a:b --> max(a,b) => Here check performed is '>' and the value selected
+// is the larger of two. So, the corresponding HexagonInst is passed in 'Inst'.
+// (a>b)?b:a --> min(a,b) => Here check performed is '>' but the smaller value
+// is selected and the corresponding HexagonInst is passed in 'SwapInst'.
+
+multiclass T_MinMax_pats <PatFrag Op, RegisterClass RC, ValueType VT,
+ InstHexagon Inst, InstHexagon SwapInst> {
+ def: Pat<(select (i1 (Op (VT RC:$src1), (VT RC:$src2))),
+ (VT RC:$src1), (VT RC:$src2)),
+ (Inst RC:$src1, RC:$src2)>;
+ def: Pat<(select (i1 (Op (VT RC:$src1), (VT RC:$src2))),
+ (VT RC:$src2), (VT RC:$src1)),
+ (SwapInst RC:$src1, RC:$src2)>;
+}
+
+
+multiclass MinMax_pats <PatFrag Op, InstHexagon Inst, InstHexagon SwapInst> {
+ defm: T_MinMax_pats<Op, IntRegs, i32, Inst, SwapInst>;
+
+ def: Pat<(sext_inreg (i32 (select (i1 (Op (i32 PositiveHalfWord:$src1),
+ (i32 PositiveHalfWord:$src2))),
+ (i32 PositiveHalfWord:$src1),
+ (i32 PositiveHalfWord:$src2))), i16),
+ (Inst IntRegs:$src1, IntRegs:$src2)>;
+
+ def: Pat<(sext_inreg (i32 (select (i1 (Op (i32 PositiveHalfWord:$src1),
+ (i32 PositiveHalfWord:$src2))),
+ (i32 PositiveHalfWord:$src2),
+ (i32 PositiveHalfWord:$src1))), i16),
+ (SwapInst IntRegs:$src1, IntRegs:$src2)>;
+}
+
+let AddedComplexity = 200 in {
+ defm: MinMax_pats<setge, A2_max, A2_min>;
+ defm: MinMax_pats<setgt, A2_max, A2_min>;
+ defm: MinMax_pats<setle, A2_min, A2_max>;
+ defm: MinMax_pats<setlt, A2_min, A2_max>;
+ defm: MinMax_pats<setuge, A2_maxu, A2_minu>;
+ defm: MinMax_pats<setugt, A2_maxu, A2_minu>;
+ defm: MinMax_pats<setule, A2_minu, A2_maxu>;
+ defm: MinMax_pats<setult, A2_minu, A2_maxu>;
+}
+
+class T_cmp64_rr<string mnemonic, bits<3> MinOp, bit IsComm>
+ : ALU64_rr<(outs PredRegs:$Pd), (ins DoubleRegs:$Rs, DoubleRegs:$Rt),
+ "$Pd = "#mnemonic#"($Rs, $Rt)", [], "", ALU64_tc_2early_SLOT23> {
+ let isCompare = 1;
+ let isCommutable = IsComm;
+ let hasSideEffects = 0;
+
+ bits<2> Pd;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1101;
+ let Inst{27-21} = 0b0010100;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ let Inst{7-5} = MinOp;
+ let Inst{1-0} = Pd;
+}
+
+let isCodeGenOnly = 0 in {
+def C2_cmpeqp : T_cmp64_rr<"cmp.eq", 0b000, 1>;
+def C2_cmpgtp : T_cmp64_rr<"cmp.gt", 0b010, 0>;
+def C2_cmpgtup : T_cmp64_rr<"cmp.gtu", 0b100, 0>;
+}
+
+class T_cmp64_rr_pat<InstHexagon MI, PatFrag CmpOp>
+ : Pat<(i1 (CmpOp (i64 DoubleRegs:$Rs), (i64 DoubleRegs:$Rt))),
+ (i1 (MI DoubleRegs:$Rs, DoubleRegs:$Rt))>;
+
+def: T_cmp64_rr_pat<C2_cmpeqp, seteq>;
+def: T_cmp64_rr_pat<C2_cmpgtp, setgt>;
+def: T_cmp64_rr_pat<C2_cmpgtup, setugt>;
+def: T_cmp64_rr_pat<C2_cmpgtp, RevCmp<setlt>>;
+def: T_cmp64_rr_pat<C2_cmpgtup, RevCmp<setult>>;
+
+class T_ALU64_rr<string mnemonic, string suffix, bits<4> RegType,
+ bits<3> MajOp, bits<3> MinOp, bit OpsRev, bit IsComm,
+ string Op2Pfx>
+ : ALU64_rr<(outs DoubleRegs:$Rd), (ins DoubleRegs:$Rs, DoubleRegs:$Rt),
+ "$Rd = " #mnemonic# "($Rs, " #Op2Pfx# "$Rt)" #suffix, [],
+ "", ALU64_tc_1_SLOT23> {
+ let hasSideEffects = 0;
+ let isCommutable = IsComm;
+
+ bits<5> Rs;
+ bits<5> Rt;
+ bits<5> Rd;
+
+ let IClass = 0b1101;
+ let Inst{27-24} = RegType;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = !if (OpsRev,Rt,Rs);
+ let Inst{12-8} = !if (OpsRev,Rs,Rt);
+ let Inst{7-5} = MinOp;
+ let Inst{4-0} = Rd;
+}
+
+class T_ALU64_arith<string mnemonic, bits<3> MajOp, bits<3> MinOp, bit IsSat,
+ bit OpsRev, bit IsComm>
+ : T_ALU64_rr<mnemonic, !if(IsSat,":sat",""), 0b0011, MajOp, MinOp, OpsRev,
+ IsComm, "">;
+
+let isCodeGenOnly = 0 in {
+def A2_addp : T_ALU64_arith<"add", 0b000, 0b111, 0, 0, 1>;
+def A2_subp : T_ALU64_arith<"sub", 0b001, 0b111, 0, 1, 0>;
+}
+
+def: Pat<(i64 (add I64:$Rs, I64:$Rt)), (A2_addp I64:$Rs, I64:$Rt)>;
+def: Pat<(i64 (sub I64:$Rs, I64:$Rt)), (A2_subp I64:$Rs, I64:$Rt)>;
+
+class T_ALU64_logical<string mnemonic, bits<3> MinOp, bit OpsRev, bit IsComm,
+ bit IsNeg>
+ : T_ALU64_rr<mnemonic, "", 0b0011, 0b111, MinOp, OpsRev, IsComm,
+ !if(IsNeg,"~","")>;
+
+let isCodeGenOnly = 0 in {
+def A2_andp : T_ALU64_logical<"and", 0b000, 0, 1, 0>;
+def A2_orp : T_ALU64_logical<"or", 0b010, 0, 1, 0>;
+def A2_xorp : T_ALU64_logical<"xor", 0b100, 0, 1, 0>;
+}
+
+def: Pat<(i64 (and I64:$Rs, I64:$Rt)), (A2_andp I64:$Rs, I64:$Rt)>;
+def: Pat<(i64 (or I64:$Rs, I64:$Rt)), (A2_orp I64:$Rs, I64:$Rt)>;
+def: Pat<(i64 (xor I64:$Rs, I64:$Rt)), (A2_xorp I64:$Rs, I64:$Rt)>;
//===----------------------------------------------------------------------===//
// ALU64/ALU -
@@ -683,29 +1149,90 @@ def SUB64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
// Pipelined looping instructions.
// Logical operations on predicates.
-def AND_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2),
- "$dst = and($src1, $src2)",
- [(set (i1 PredRegs:$dst), (and (i1 PredRegs:$src1),
- (i1 PredRegs:$src2)))]>;
-
-let neverHasSideEffects = 1 in
-def AND_pnotp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1,
- PredRegs:$src2),
- "$dst = and($src1, !$src2)",
- []>;
-
-def ANY_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1),
- "$dst = any8($src1)",
- []>;
+let hasSideEffects = 0 in
+class T_LOGICAL_1OP<string MnOp, bits<2> OpBits>
+ : CRInst<(outs PredRegs:$Pd), (ins PredRegs:$Ps),
+ "$Pd = " # MnOp # "($Ps)", [], "", CR_tc_2early_SLOT23> {
+ bits<2> Pd;
+ bits<2> Ps;
+
+ let IClass = 0b0110;
+ let Inst{27-23} = 0b10111;
+ let Inst{22-21} = OpBits;
+ let Inst{20} = 0b0;
+ let Inst{17-16} = Ps;
+ let Inst{13} = 0b0;
+ let Inst{1-0} = Pd;
+}
-def ALL_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1),
- "$dst = all8($src1)",
- []>;
+let isCodeGenOnly = 0 in {
+def C2_any8 : T_LOGICAL_1OP<"any8", 0b00>;
+def C2_all8 : T_LOGICAL_1OP<"all8", 0b01>;
+def C2_not : T_LOGICAL_1OP<"not", 0b10>;
+}
-def VITPACK_pp : SInst<(outs IntRegs:$dst), (ins PredRegs:$src1,
- PredRegs:$src2),
- "$dst = vitpack($src1, $src2)",
- []>;
+def: Pat<(i1 (not (i1 PredRegs:$Ps))),
+ (C2_not PredRegs:$Ps)>;
+
+let hasSideEffects = 0 in
+class T_LOGICAL_2OP<string MnOp, bits<3> OpBits, bit IsNeg, bit Rev>
+ : CRInst<(outs PredRegs:$Pd), (ins PredRegs:$Ps, PredRegs:$Pt),
+ "$Pd = " # MnOp # "($Ps, " # !if (IsNeg,"!","") # "$Pt)",
+ [], "", CR_tc_2early_SLOT23> {
+ bits<2> Pd;
+ bits<2> Ps;
+ bits<2> Pt;
+
+ let IClass = 0b0110;
+ let Inst{27-24} = 0b1011;
+ let Inst{23-21} = OpBits;
+ let Inst{20} = 0b0;
+ let Inst{17-16} = !if(Rev,Pt,Ps); // Rs and Rt are reversed for some
+ let Inst{13} = 0b0; // instructions.
+ let Inst{9-8} = !if(Rev,Ps,Pt);
+ let Inst{1-0} = Pd;
+}
+
+let isCodeGenOnly = 0 in {
+def C2_and : T_LOGICAL_2OP<"and", 0b000, 0, 1>;
+def C2_or : T_LOGICAL_2OP<"or", 0b001, 0, 1>;
+def C2_xor : T_LOGICAL_2OP<"xor", 0b010, 0, 0>;
+def C2_andn : T_LOGICAL_2OP<"and", 0b011, 1, 1>;
+def C2_orn : T_LOGICAL_2OP<"or", 0b111, 1, 1>;
+}
+
+def: Pat<(i1 (and I1:$Ps, I1:$Pt)), (C2_and I1:$Ps, I1:$Pt)>;
+def: Pat<(i1 (or I1:$Ps, I1:$Pt)), (C2_or I1:$Ps, I1:$Pt)>;
+def: Pat<(i1 (xor I1:$Ps, I1:$Pt)), (C2_xor I1:$Ps, I1:$Pt)>;
+def: Pat<(i1 (and I1:$Ps, (not I1:$Pt))), (C2_andn I1:$Ps, I1:$Pt)>;
+def: Pat<(i1 (or I1:$Ps, (not I1:$Pt))), (C2_orn I1:$Ps, I1:$Pt)>;
+
+let hasSideEffects = 0, hasNewValue = 1, isCodeGenOnly = 0 in
+def C2_vitpack : SInst<(outs IntRegs:$Rd), (ins PredRegs:$Ps, PredRegs:$Pt),
+ "$Rd = vitpack($Ps, $Pt)", [], "", S_2op_tc_1_SLOT23> {
+ bits<5> Rd;
+ bits<2> Ps;
+ bits<2> Pt;
+
+ let IClass = 0b1000;
+ let Inst{27-24} = 0b1001;
+ let Inst{22-21} = 0b00;
+ let Inst{17-16} = Ps;
+ let Inst{9-8} = Pt;
+ let Inst{4-0} = Rd;
+}
+
+let hasSideEffects = 0, isCodeGenOnly = 0 in
+def C2_mask : SInst<(outs DoubleRegs:$Rd), (ins PredRegs:$Pt),
+ "$Rd = mask($Pt)", [], "", S_2op_tc_1_SLOT23> {
+ bits<5> Rd;
+ bits<2> Pt;
+
+ let IClass = 0b1000;
+ let Inst{27-24} = 0b0110;
+ let Inst{9-8} = Pt;
+ let Inst{4-0} = Rd;
+}
def VALIGN_rrp : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
DoubleRegs:$src2,
@@ -719,46 +1246,38 @@ def VSPLICE_rrp : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
"$dst = vspliceb($src1, $src2, $src3)",
[]>;
-def MASK_p : SInst<(outs DoubleRegs:$dst), (ins PredRegs:$src1),
- "$dst = mask($src1)",
- []>;
-
-def NOT_p : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1),
- "$dst = not($src1)",
- [(set (i1 PredRegs:$dst), (not (i1 PredRegs:$src1)))]>;
-
-def OR_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2),
- "$dst = or($src1, $src2)",
- [(set (i1 PredRegs:$dst), (or (i1 PredRegs:$src1),
- (i1 PredRegs:$src2)))]>;
-
-def XOR_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2),
- "$dst = xor($src1, $src2)",
- [(set (i1 PredRegs:$dst), (xor (i1 PredRegs:$src1),
- (i1 PredRegs:$src2)))]>;
-
-
// User control register transfer.
//===----------------------------------------------------------------------===//
// CR -
//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+// JR +
+//===----------------------------------------------------------------------===//
+
def retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone,
[SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
-def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone,
- [SDNPHasChain]>;
+def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone, [SDNPHasChain]>;
def SDHexagonBR_JT: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
def HexagonBR_JT: SDNode<"HexagonISD::BR_JT", SDHexagonBR_JT, [SDNPHasChain]>;
-let InputType = "imm", isBarrier = 1, isPredicable = 1,
-Defs = [PC], isExtendable = 1, opExtendable = 0, isExtentSigned = 1,
-opExtentBits = 24 in
-class T_JMP <dag InsDag, list<dag> JumpList = []>
- : JInst<(outs), InsDag,
- "jump $dst" , JumpList> {
- bits<24> dst;
+class CondStr<string CReg, bit True, bit New> {
+ string S = "if (" # !if(True,"","!") # CReg # !if(New,".new","") # ") ";
+}
+class JumpOpcStr<string Mnemonic, bit New, bit Taken> {
+ string S = Mnemonic # !if(New, !if(Taken,":t",":nt"), "");
+}
+let isBranch = 1, isBarrier = 1, Defs = [PC], hasSideEffects = 0,
+ isPredicable = 1,
+ isExtendable = 1, opExtendable = 0, isExtentSigned = 1,
+ opExtentBits = 24, opExtentAlign = 2, InputType = "imm" in
+class T_JMP<string ExtStr>
+ : JInst<(outs), (ins brtarget:$dst),
+ "jump " # ExtStr # "$dst",
+ [], "", J_tc_2early_SLOT23> {
+ bits<24> dst;
let IClass = 0b0101;
let Inst{27-25} = 0b100;
@@ -766,16 +1285,16 @@ class T_JMP <dag InsDag, list<dag> JumpList = []>
let Inst{13-1} = dst{14-2};
}
-let InputType = "imm", isExtendable = 1, opExtendable = 1, isExtentSigned = 1,
-Defs = [PC], isPredicated = 1, opExtentBits = 17 in
-class T_JMP_c <bit PredNot, bit isPredNew, bit isTak>:
- JInst<(outs ), (ins PredRegs:$src, brtarget:$dst),
- !if(PredNot, "if (!$src", "if ($src")#
- !if(isPredNew, ".new) ", ") ")#"jump"#
- !if(isPredNew, !if(isTak, ":t ", ":nt "), " ")#"$dst"> {
-
+let isBranch = 1, Defs = [PC], hasSideEffects = 0, isPredicated = 1,
+ isExtendable = 1, opExtendable = 1, isExtentSigned = 1,
+ opExtentBits = 17, opExtentAlign = 2, InputType = "imm" in
+class T_JMP_c<bit PredNot, bit isPredNew, bit isTak, string ExtStr>
+ : JInst<(outs), (ins PredRegs:$src, brtarget:$dst),
+ CondStr<"$src", !if(PredNot,0,1), isPredNew>.S #
+ JumpOpcStr<"jump", isPredNew, isTak>.S # " " #
+ ExtStr # "$dst",
+ [], "", J_tc_2early_SLOT23>, ImmRegRel {
let isTaken = isTak;
- let isBrTaken = !if(isPredNew, !if(isTaken, "true", "false"), "");
let isPredicatedFalse = PredNot;
let isPredicatedNew = isPredNew;
bits<2> src;
@@ -794,11 +1313,28 @@ class T_JMP_c <bit PredNot, bit isPredNew, bit isTak>:
let Inst{7-1} = dst{8-2};
}
-let isBarrier = 1, Defs = [PC], isPredicable = 1, InputType = "reg" in
-class T_JMPr<dag InsDag = (ins IntRegs:$dst)>
- : JRInst<(outs ), InsDag,
- "jumpr $dst" ,
- []> {
+multiclass JMP_Pred<bit PredNot, string ExtStr> {
+ def NAME : T_JMP_c<PredNot, 0, 0, ExtStr>;
+ // Predicate new
+ def NAME#newpt : T_JMP_c<PredNot, 1, 1, ExtStr>; // taken
+ def NAME#new : T_JMP_c<PredNot, 1, 0, ExtStr>; // not taken
+}
+
+multiclass JMP_base<string BaseOp, string ExtStr> {
+ let BaseOpcode = BaseOp in {
+ def NAME : T_JMP<ExtStr>;
+ defm t : JMP_Pred<0, ExtStr>;
+ defm f : JMP_Pred<1, ExtStr>;
+ }
+}
+
+// Jumps to address stored in a register, JUMPR_MISC
+// if ([[!]P[.new]]) jumpr[:t/nt] Rs
+let isBranch = 1, isIndirectBranch = 1, isBarrier = 1, Defs = [PC],
+ isPredicable = 1, hasSideEffects = 0, InputType = "reg" in
+class T_JMPr
+ : JRInst<(outs), (ins IntRegs:$dst),
+ "jumpr $dst", [], "", J_tc_2early_SLOT2> {
bits<5> dst;
let IClass = 0b0101;
@@ -806,15 +1342,15 @@ class T_JMPr<dag InsDag = (ins IntRegs:$dst)>
let Inst{20-16} = dst;
}
-let Defs = [PC], isPredicated = 1, InputType = "reg" in
-class T_JMPr_c <bit PredNot, bit isPredNew, bit isTak>:
- JRInst <(outs ), (ins PredRegs:$src, IntRegs:$dst),
- !if(PredNot, "if (!$src", "if ($src")#
- !if(isPredNew, ".new) ", ") ")#"jumpr"#
- !if(isPredNew, !if(isTak, ":t ", ":nt "), " ")#"$dst"> {
+let isBranch = 1, isIndirectBranch = 1, Defs = [PC], isPredicated = 1,
+ hasSideEffects = 0, InputType = "reg" in
+class T_JMPr_c <bit PredNot, bit isPredNew, bit isTak>
+ : JRInst <(outs), (ins PredRegs:$src, IntRegs:$dst),
+ CondStr<"$src", !if(PredNot,0,1), isPredNew>.S #
+ JumpOpcStr<"jumpr", isPredNew, isTak>.S # " $dst", [],
+ "", J_tc_2early_SLOT2> {
let isTaken = isTak;
- let isBrTaken = !if(isPredNew, !if(isTaken, "true", "false"), "");
let isPredicatedFalse = PredNot;
let isPredicatedNew = isPredNew;
bits<2> src;
@@ -828,70 +1364,85 @@ class T_JMPr_c <bit PredNot, bit isPredNew, bit isTak>:
let Inst{12} = !if(isPredNew, isTak, zero);
let Inst{11} = isPredNew;
let Inst{9-8} = src;
- let Predicates = !if(isPredNew, [HasV3T], [HasV2T]);
- let validSubTargets = !if(isPredNew, HasV3SubT, HasV2SubT);
-}
-
-multiclass JMP_Pred<bit PredNot> {
- def _#NAME : T_JMP_c<PredNot, 0, 0>;
- // Predicate new
- def _#NAME#new_t : T_JMP_c<PredNot, 1, 1>; // taken
- def _#NAME#new_nt : T_JMP_c<PredNot, 1, 0>; // not taken
-}
-
-multiclass JMP_base<string BaseOp> {
- let BaseOpcode = BaseOp in {
- def NAME : T_JMP<(ins brtarget:$dst), [(br bb:$dst)]>;
- defm t : JMP_Pred<0>;
- defm f : JMP_Pred<1>;
- }
}
multiclass JMPR_Pred<bit PredNot> {
def NAME: T_JMPr_c<PredNot, 0, 0>;
// Predicate new
- def NAME#new_tV3 : T_JMPr_c<PredNot, 1, 1>; // taken
- def NAME#new_ntV3 : T_JMPr_c<PredNot, 1, 0>; // not taken
+ def NAME#newpt : T_JMPr_c<PredNot, 1, 1>; // taken
+ def NAME#new : T_JMPr_c<PredNot, 1, 0>; // not taken
}
multiclass JMPR_base<string BaseOp> {
let BaseOpcode = BaseOp in {
def NAME : T_JMPr;
- defm _t : JMPR_Pred<0>;
- defm _f : JMPR_Pred<1>;
+ defm t : JMPR_Pred<0>;
+ defm f : JMPR_Pred<1>;
}
}
-let isTerminator = 1, neverHasSideEffects = 1 in {
-let isBranch = 1 in
-defm JMP : JMP_base<"JMP">, PredNewRel;
+let isCall = 1, hasSideEffects = 1 in
+class JUMPR_MISC_CALLR<bit isPred, bit isPredNot,
+ dag InputDag = (ins IntRegs:$Rs)>
+ : JRInst<(outs), InputDag,
+ !if(isPred, !if(isPredNot, "if (!$Pu) callr $Rs",
+ "if ($Pu) callr $Rs"),
+ "callr $Rs"),
+ [], "", J_tc_2early_SLOT2> {
+ bits<5> Rs;
+ bits<2> Pu;
+ let isPredicated = isPred;
+ let isPredicatedFalse = isPredNot;
-let isBranch = 1, isIndirectBranch = 1 in
-defm JMPR : JMPR_base<"JMPr">, PredNewRel;
+ let IClass = 0b0101;
+ let Inst{27-25} = 0b000;
+ let Inst{24-23} = !if (isPred, 0b10, 0b01);
+ let Inst{22} = 0;
+ let Inst{21} = isPredNot;
+ let Inst{9-8} = !if (isPred, Pu, 0b00);
+ let Inst{20-16} = Rs;
-let isReturn = 1, isCodeGenOnly = 1 in
-defm JMPret : JMPR_base<"JMPret">, PredNewRel;
+ }
+
+let Defs = VolatileV3.Regs, isCodeGenOnly = 0 in {
+ def J2_callrt : JUMPR_MISC_CALLR<1, 0, (ins PredRegs:$Pu, IntRegs:$Rs)>;
+ def J2_callrf : JUMPR_MISC_CALLR<1, 1, (ins PredRegs:$Pu, IntRegs:$Rs)>;
}
-def : Pat<(retflag),
- (JMPret (i32 R31))>;
+let isTerminator = 1, hasSideEffects = 0, isCodeGenOnly = 0 in {
+ defm J2_jump : JMP_base<"JMP", "">, PredNewRel;
-def : Pat <(brcond (i1 PredRegs:$src1), bb:$offset),
- (JMP_t (i1 PredRegs:$src1), bb:$offset)>;
+ // Deal with explicit assembly
+ // - never extened a jump #, always extend a jump ##
+ let isAsmParserOnly = 1 in {
+ defm J2_jump_ext : JMP_base<"JMP", "##">;
+ defm J2_jump_noext : JMP_base<"JMP", "#">;
+ }
-// A return through builtin_eh_return.
-let isReturn = 1, isTerminator = 1, isBarrier = 1, neverHasSideEffects = 1,
-isCodeGenOnly = 1, Defs = [PC], Uses = [R28], isPredicable = 0 in
-def EH_RETURN_JMPR : T_JMPr;
+ defm J2_jumpr : JMPR_base<"JMPr">, PredNewRel;
+
+ let isReturn = 1, isCodeGenOnly = 1 in
+ defm JMPret : JMPR_base<"JMPret">, PredNewRel;
+}
-def : Pat<(eh_return),
- (EH_RETURN_JMPR (i32 R31))>;
+def: Pat<(br bb:$dst),
+ (J2_jump brtarget:$dst)>;
+def: Pat<(retflag),
+ (JMPret (i32 R31))>;
+def: Pat<(brcond (i1 PredRegs:$src1), bb:$offset),
+ (J2_jumpt PredRegs:$src1, bb:$offset)>;
-def : Pat<(HexagonBR_JT (i32 IntRegs:$dst)),
- (JMPR (i32 IntRegs:$dst))>;
+// A return through builtin_eh_return.
+let isReturn = 1, isTerminator = 1, isBarrier = 1, hasSideEffects = 0,
+ isCodeGenOnly = 1, Defs = [PC], Uses = [R28], isPredicable = 0 in
+def EH_RETURN_JMPR : T_JMPr;
-def : Pat<(brind (i32 IntRegs:$dst)),
- (JMPR (i32 IntRegs:$dst))>;
+def: Pat<(eh_return),
+ (EH_RETURN_JMPR (i32 R31))>;
+def: Pat<(HexagonBR_JT (i32 IntRegs:$dst)),
+ (J2_jumpr IntRegs:$dst)>;
+def: Pat<(brind (i32 IntRegs:$dst)),
+ (J2_jumpr IntRegs:$dst)>;
//===----------------------------------------------------------------------===//
// JR -
@@ -900,265 +1451,502 @@ def : Pat<(brind (i32 IntRegs:$dst)),
//===----------------------------------------------------------------------===//
// LD +
//===----------------------------------------------------------------------===//
-///
-// Load -- MEMri operand
-multiclass LD_MEMri_Pbase<string mnemonic, RegisterClass RC,
- bit isNot, bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME : LDInst2<(outs RC:$dst),
- (ins PredRegs:$src1, MEMri:$addr),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#"$dst = "#mnemonic#"($addr)",
- []>;
-}
+let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, AddedComplexity = 20 in
+class T_load_io <string mnemonic, RegisterClass RC, bits<4> MajOp,
+ Operand ImmOp>
+ : LDInst<(outs RC:$dst), (ins IntRegs:$src1, ImmOp:$offset),
+ "$dst = "#mnemonic#"($src1 + #$offset)", []>, AddrModeRel {
+ bits<4> name;
+ bits<5> dst;
+ bits<5> src1;
+ bits<14> offset;
+ bits<11> offsetBits;
+
+ string ImmOpStr = !cast<string>(ImmOp);
+ let offsetBits = !if (!eq(ImmOpStr, "s11_3Ext"), offset{13-3},
+ !if (!eq(ImmOpStr, "s11_2Ext"), offset{12-2},
+ !if (!eq(ImmOpStr, "s11_1Ext"), offset{11-1},
+ /* s11_0Ext */ offset{10-0})));
+ let opExtentBits = !if (!eq(ImmOpStr, "s11_3Ext"), 14,
+ !if (!eq(ImmOpStr, "s11_2Ext"), 13,
+ !if (!eq(ImmOpStr, "s11_1Ext"), 12,
+ /* s11_0Ext */ 11)));
+ let hasNewValue = !if (!eq(ImmOpStr, "s11_3Ext"), 0, 1);
+
+ let IClass = 0b1001;
+
+ let Inst{27} = 0b0;
+ let Inst{26-25} = offsetBits{10-9};
+ let Inst{24-21} = MajOp;
+ let Inst{20-16} = src1;
+ let Inst{13-5} = offsetBits{8-0};
+ let Inst{4-0} = dst;
+ }
-multiclass LD_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 0>;
- // Predicate new
- defm _cdn#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 1>;
+let opExtendable = 3, isExtentSigned = 0, isPredicated = 1 in
+class T_pload_io <string mnemonic, RegisterClass RC, bits<4>MajOp,
+ Operand ImmOp, bit isNot, bit isPredNew>
+ : LDInst<(outs RC:$dst),
+ (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset),
+ "if ("#!if(isNot, "!$src1", "$src1")
+ #!if(isPredNew, ".new", "")
+ #") $dst = "#mnemonic#"($src2 + #$offset)",
+ [],"", V2LDST_tc_ld_SLOT01> , AddrModeRel {
+ bits<5> dst;
+ bits<2> src1;
+ bits<5> src2;
+ bits<9> offset;
+ bits<6> offsetBits;
+ string ImmOpStr = !cast<string>(ImmOp);
+
+ let offsetBits = !if (!eq(ImmOpStr, "u6_3Ext"), offset{8-3},
+ !if (!eq(ImmOpStr, "u6_2Ext"), offset{7-2},
+ !if (!eq(ImmOpStr, "u6_1Ext"), offset{6-1},
+ /* u6_0Ext */ offset{5-0})));
+ let opExtentBits = !if (!eq(ImmOpStr, "u6_3Ext"), 9,
+ !if (!eq(ImmOpStr, "u6_2Ext"), 8,
+ !if (!eq(ImmOpStr, "u6_1Ext"), 7,
+ /* u6_0Ext */ 6)));
+ let hasNewValue = !if (!eq(ImmOpStr, "u6_3Ext"), 0, 1);
+ let isPredicatedNew = isPredNew;
+ let isPredicatedFalse = isNot;
+
+ let IClass = 0b0100;
+
+ let Inst{27} = 0b0;
+ let Inst{27} = 0b0;
+ let Inst{26} = isNot;
+ let Inst{25} = isPredNew;
+ let Inst{24-21} = MajOp;
+ let Inst{20-16} = src2;
+ let Inst{13} = 0b0;
+ let Inst{12-11} = src1;
+ let Inst{10-5} = offsetBits;
+ let Inst{4-0} = dst;
}
-}
-let isExtendable = 1, neverHasSideEffects = 1 in
-multiclass LD_MEMri<string mnemonic, string CextOp, RegisterClass RC,
- bits<5> ImmBits, bits<5> PredImmBits> {
+let isExtendable = 1, hasSideEffects = 0, addrMode = BaseImmOffset in
+multiclass LD_Idxd<string mnemonic, string CextOp, RegisterClass RC,
+ Operand ImmOp, Operand predImmOp, bits<4>MajOp> {
+ let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
+ let isPredicable = 1 in
+ def L2_#NAME#_io : T_load_io <mnemonic, RC, MajOp, ImmOp>;
- let CextOpcode = CextOp, BaseOpcode = CextOp in {
- let opExtendable = 2, isExtentSigned = 1, opExtentBits = ImmBits,
- isPredicable = 1 in
- def NAME : LDInst2<(outs RC:$dst), (ins MEMri:$addr),
- "$dst = "#mnemonic#"($addr)",
- []>;
-
- let opExtendable = 3, isExtentSigned = 0, opExtentBits = PredImmBits,
- isPredicated = 1 in {
- defm Pt : LD_MEMri_Pred<mnemonic, RC, 0 >;
- defm NotPt : LD_MEMri_Pred<mnemonic, RC, 1 >;
- }
+ // Predicated
+ def L2_p#NAME#t_io : T_pload_io <mnemonic, RC, MajOp, predImmOp, 0, 0>;
+ def L2_p#NAME#f_io : T_pload_io <mnemonic, RC, MajOp, predImmOp, 1, 0>;
+
+ // Predicated new
+ def L2_p#NAME#tnew_io : T_pload_io <mnemonic, RC, MajOp, predImmOp, 0, 1>;
+ def L2_p#NAME#fnew_io : T_pload_io <mnemonic, RC, MajOp, predImmOp, 1, 1>;
}
}
-let addrMode = BaseImmOffset, isMEMri = "true" in {
- let accessSize = ByteAccess in {
- defm LDrib: LD_MEMri < "memb", "LDrib", IntRegs, 11, 6>, AddrModeRel;
- defm LDriub: LD_MEMri < "memub" , "LDriub", IntRegs, 11, 6>, AddrModeRel;
- }
+let accessSize = ByteAccess, isCodeGenOnly = 0 in {
+ defm loadrb: LD_Idxd <"memb", "LDrib", IntRegs, s11_0Ext, u6_0Ext, 0b1000>;
+ defm loadrub: LD_Idxd <"memub", "LDriub", IntRegs, s11_0Ext, u6_0Ext, 0b1001>;
+}
- let accessSize = HalfWordAccess in {
- defm LDrih: LD_MEMri < "memh", "LDrih", IntRegs, 12, 7>, AddrModeRel;
- defm LDriuh: LD_MEMri < "memuh", "LDriuh", IntRegs, 12, 7>, AddrModeRel;
- }
+let accessSize = HalfWordAccess, opExtentAlign = 1, isCodeGenOnly = 0 in {
+ defm loadrh: LD_Idxd <"memh", "LDrih", IntRegs, s11_1Ext, u6_1Ext, 0b1010>;
+ defm loadruh: LD_Idxd <"memuh", "LDriuh", IntRegs, s11_1Ext, u6_1Ext, 0b1011>;
+}
- let accessSize = WordAccess in
- defm LDriw: LD_MEMri < "memw", "LDriw", IntRegs, 13, 8>, AddrModeRel;
+let accessSize = WordAccess, opExtentAlign = 2, isCodeGenOnly = 0 in
+defm loadri: LD_Idxd <"memw", "LDriw", IntRegs, s11_2Ext, u6_2Ext, 0b1100>;
- let accessSize = DoubleWordAccess in
- defm LDrid: LD_MEMri < "memd", "LDrid", DoubleRegs, 14, 9>, AddrModeRel;
-}
+let accessSize = DoubleWordAccess, opExtentAlign = 3, isCodeGenOnly = 0 in
+defm loadrd: LD_Idxd <"memd", "LDrid", DoubleRegs, s11_3Ext, u6_3Ext, 0b1110>;
def : Pat < (i32 (sextloadi8 ADDRriS11_0:$addr)),
- (LDrib ADDRriS11_0:$addr) >;
+ (L2_loadrb_io AddrFI:$addr, 0) >;
def : Pat < (i32 (zextloadi8 ADDRriS11_0:$addr)),
- (LDriub ADDRriS11_0:$addr) >;
+ (L2_loadrub_io AddrFI:$addr, 0) >;
def : Pat < (i32 (sextloadi16 ADDRriS11_1:$addr)),
- (LDrih ADDRriS11_1:$addr) >;
+ (L2_loadrh_io AddrFI:$addr, 0) >;
def : Pat < (i32 (zextloadi16 ADDRriS11_1:$addr)),
- (LDriuh ADDRriS11_1:$addr) >;
+ (L2_loadruh_io AddrFI:$addr, 0) >;
def : Pat < (i32 (load ADDRriS11_2:$addr)),
- (LDriw ADDRriS11_2:$addr) >;
+ (L2_loadri_io AddrFI:$addr, 0) >;
def : Pat < (i64 (load ADDRriS11_3:$addr)),
- (LDrid ADDRriS11_3:$addr) >;
-
-
-// Load - Base with Immediate offset addressing mode
-multiclass LD_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp,
- bit isNot, bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME : LDInst2<(outs RC:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#"$dst = "#mnemonic#"($src2+#$src3)",
- []>;
-}
-
-multiclass LD_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp,
- bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : LD_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 0>;
- // Predicate new
- defm _cdn#NAME : LD_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 1>;
- }
-}
-
-let isExtendable = 1, neverHasSideEffects = 1 in
-multiclass LD_Idxd<string mnemonic, string CextOp, RegisterClass RC,
- Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
- bits<5> PredImmBits> {
-
- let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
- let opExtendable = 2, isExtentSigned = 1, opExtentBits = ImmBits,
- isPredicable = 1, AddedComplexity = 20 in
- def NAME : LDInst2<(outs RC:$dst), (ins IntRegs:$src1, ImmOp:$offset),
- "$dst = "#mnemonic#"($src1+#$offset)",
- []>;
-
- let opExtendable = 3, isExtentSigned = 0, opExtentBits = PredImmBits,
- isPredicated = 1 in {
- defm Pt : LD_Idxd_Pred<mnemonic, RC, predImmOp, 0 >;
- defm NotPt : LD_Idxd_Pred<mnemonic, RC, predImmOp, 1 >;
- }
- }
-}
-
-let addrMode = BaseImmOffset in {
- let accessSize = ByteAccess in {
- defm LDrib_indexed: LD_Idxd <"memb", "LDrib", IntRegs, s11_0Ext, u6_0Ext,
- 11, 6>, AddrModeRel;
- defm LDriub_indexed: LD_Idxd <"memub" , "LDriub", IntRegs, s11_0Ext, u6_0Ext,
- 11, 6>, AddrModeRel;
- }
- let accessSize = HalfWordAccess in {
- defm LDrih_indexed: LD_Idxd <"memh", "LDrih", IntRegs, s11_1Ext, u6_1Ext,
- 12, 7>, AddrModeRel;
- defm LDriuh_indexed: LD_Idxd <"memuh", "LDriuh", IntRegs, s11_1Ext, u6_1Ext,
- 12, 7>, AddrModeRel;
- }
- let accessSize = WordAccess in
- defm LDriw_indexed: LD_Idxd <"memw", "LDriw", IntRegs, s11_2Ext, u6_2Ext,
- 13, 8>, AddrModeRel;
-
- let accessSize = DoubleWordAccess in
- defm LDrid_indexed: LD_Idxd <"memd", "LDrid", DoubleRegs, s11_3Ext, u6_3Ext,
- 14, 9>, AddrModeRel;
-}
+ (L2_loadrd_io AddrFI:$addr, 0) >;
let AddedComplexity = 20 in {
def : Pat < (i32 (sextloadi8 (add IntRegs:$src1, s11_0ExtPred:$offset))),
- (LDrib_indexed IntRegs:$src1, s11_0ExtPred:$offset) >;
+ (L2_loadrb_io IntRegs:$src1, s11_0ExtPred:$offset) >;
def : Pat < (i32 (zextloadi8 (add IntRegs:$src1, s11_0ExtPred:$offset))),
- (LDriub_indexed IntRegs:$src1, s11_0ExtPred:$offset) >;
+ (L2_loadrub_io IntRegs:$src1, s11_0ExtPred:$offset) >;
def : Pat < (i32 (sextloadi16 (add IntRegs:$src1, s11_1ExtPred:$offset))),
- (LDrih_indexed IntRegs:$src1, s11_1ExtPred:$offset) >;
+ (L2_loadrh_io IntRegs:$src1, s11_1ExtPred:$offset) >;
def : Pat < (i32 (zextloadi16 (add IntRegs:$src1, s11_1ExtPred:$offset))),
- (LDriuh_indexed IntRegs:$src1, s11_1ExtPred:$offset) >;
+ (L2_loadruh_io IntRegs:$src1, s11_1ExtPred:$offset) >;
def : Pat < (i32 (load (add IntRegs:$src1, s11_2ExtPred:$offset))),
- (LDriw_indexed IntRegs:$src1, s11_2ExtPred:$offset) >;
+ (L2_loadri_io IntRegs:$src1, s11_2ExtPred:$offset) >;
def : Pat < (i64 (load (add IntRegs:$src1, s11_3ExtPred:$offset))),
- (LDrid_indexed IntRegs:$src1, s11_3ExtPred:$offset) >;
+ (L2_loadrd_io IntRegs:$src1, s11_3ExtPred:$offset) >;
}
//===----------------------------------------------------------------------===//
// Post increment load
//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+// Template class for non-predicated post increment loads with immediate offset.
+//===----------------------------------------------------------------------===//
+let hasSideEffects = 0, addrMode = PostInc in
+class T_load_pi <string mnemonic, RegisterClass RC, Operand ImmOp,
+ bits<4> MajOp >
+ : LDInstPI <(outs RC:$dst, IntRegs:$dst2),
+ (ins IntRegs:$src1, ImmOp:$offset),
+ "$dst = "#mnemonic#"($src1++#$offset)" ,
+ [],
+ "$src1 = $dst2" > ,
+ PredNewRel {
+ bits<5> dst;
+ bits<5> src1;
+ bits<7> offset;
+ bits<4> offsetBits;
+
+ string ImmOpStr = !cast<string>(ImmOp);
+ let offsetBits = !if (!eq(ImmOpStr, "s4_3Imm"), offset{6-3},
+ !if (!eq(ImmOpStr, "s4_2Imm"), offset{5-2},
+ !if (!eq(ImmOpStr, "s4_1Imm"), offset{4-1},
+ /* s4_0Imm */ offset{3-0})));
+ let hasNewValue = !if (!eq(ImmOpStr, "s4_3Imm"), 0, 1);
+
+ let IClass = 0b1001;
+
+ let Inst{27-25} = 0b101;
+ let Inst{24-21} = MajOp;
+ let Inst{20-16} = src1;
+ let Inst{13-12} = 0b00;
+ let Inst{8-5} = offsetBits;
+ let Inst{4-0} = dst;
+ }
-multiclass LD_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
- bit isNot, bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME : LDInst2PI<(outs RC:$dst, IntRegs:$dst2),
- (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#"$dst = "#mnemonic#"($src2++#$offset)",
- [],
- "$src2 = $dst2">;
-}
+//===----------------------------------------------------------------------===//
+// Template class for predicated post increment loads with immediate offset.
+//===----------------------------------------------------------------------===//
+let isPredicated = 1, hasSideEffects = 0, addrMode = PostInc in
+class T_pload_pi <string mnemonic, RegisterClass RC, Operand ImmOp,
+ bits<4> MajOp, bit isPredNot, bit isPredNew >
+ : LDInst <(outs RC:$dst, IntRegs:$dst2),
+ (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset),
+ !if(isPredNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#"$dst = "#mnemonic#"($src2++#$offset)",
+ [] ,
+ "$src2 = $dst2" > ,
+ PredNewRel {
+ bits<5> dst;
+ bits<2> src1;
+ bits<5> src2;
+ bits<7> offset;
+ bits<4> offsetBits;
-multiclass LD_PostInc_Pred<string mnemonic, RegisterClass RC,
- Operand ImmOp, bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>;
- // Predicate new
- let Predicates = [HasV4T], validSubTargets = HasV4SubT in
- defm _cdn#NAME#_V4 : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 1>;
+ let isPredicatedNew = isPredNew;
+ let isPredicatedFalse = isPredNot;
+
+ string ImmOpStr = !cast<string>(ImmOp);
+ let offsetBits = !if (!eq(ImmOpStr, "s4_3Imm"), offset{6-3},
+ !if (!eq(ImmOpStr, "s4_2Imm"), offset{5-2},
+ !if (!eq(ImmOpStr, "s4_1Imm"), offset{4-1},
+ /* s4_0Imm */ offset{3-0})));
+ let hasNewValue = !if (!eq(ImmOpStr, "s4_3Imm"), 0, 1);
+
+ let IClass = 0b1001;
+
+ let Inst{27-25} = 0b101;
+ let Inst{24-21} = MajOp;
+ let Inst{20-16} = src2;
+ let Inst{13} = 0b1;
+ let Inst{12} = isPredNew;
+ let Inst{11} = isPredNot;
+ let Inst{10-9} = src1;
+ let Inst{8-5} = offsetBits;
+ let Inst{4-0} = dst;
}
-}
-multiclass LD_PostInc<string mnemonic, string BaseOp, RegisterClass RC,
- Operand ImmOp> {
+//===----------------------------------------------------------------------===//
+// Multiclass for post increment loads with immediate offset.
+//===----------------------------------------------------------------------===//
+multiclass LD_PostInc <string mnemonic, string BaseOp, RegisterClass RC,
+ Operand ImmOp, bits<4> MajOp> {
let BaseOpcode = "POST_"#BaseOp in {
let isPredicable = 1 in
- def NAME : LDInst2PI<(outs RC:$dst, IntRegs:$dst2),
- (ins IntRegs:$src1, ImmOp:$offset),
- "$dst = "#mnemonic#"($src1++#$offset)",
- [],
- "$src1 = $dst2">;
-
- let isPredicated = 1 in {
- defm Pt : LD_PostInc_Pred<mnemonic, RC, ImmOp, 0 >;
- defm NotPt : LD_PostInc_Pred<mnemonic, RC, ImmOp, 1 >;
- }
+ def L2_#NAME#_pi : T_load_pi < mnemonic, RC, ImmOp, MajOp>;
+
+ // Predicated
+ def L2_p#NAME#t_pi : T_pload_pi < mnemonic, RC, ImmOp, MajOp, 0, 0>;
+ def L2_p#NAME#f_pi : T_pload_pi < mnemonic, RC, ImmOp, MajOp, 1, 0>;
+
+ // Predicated new
+ def L2_p#NAME#tnew_pi : T_pload_pi < mnemonic, RC, ImmOp, MajOp, 0, 1>;
+ def L2_p#NAME#fnew_pi : T_pload_pi < mnemonic, RC, ImmOp, MajOp, 1, 1>;
}
}
-let hasCtrlDep = 1, neverHasSideEffects = 1, addrMode = PostInc in {
- defm POST_LDrib : LD_PostInc<"memb", "LDrib", IntRegs, s4_0Imm>,
- PredNewRel;
- defm POST_LDriub : LD_PostInc<"memub", "LDriub", IntRegs, s4_0Imm>,
- PredNewRel;
- defm POST_LDrih : LD_PostInc<"memh", "LDrih", IntRegs, s4_1Imm>,
- PredNewRel;
- defm POST_LDriuh : LD_PostInc<"memuh", "LDriuh", IntRegs, s4_1Imm>,
- PredNewRel;
- defm POST_LDriw : LD_PostInc<"memw", "LDriw", IntRegs, s4_2Imm>,
- PredNewRel;
- defm POST_LDrid : LD_PostInc<"memd", "LDrid", DoubleRegs, s4_3Imm>,
- PredNewRel;
+// post increment byte loads with immediate offset
+let accessSize = ByteAccess, isCodeGenOnly = 0 in {
+ defm loadrb : LD_PostInc <"memb", "LDrib", IntRegs, s4_0Imm, 0b1000>;
+ defm loadrub : LD_PostInc <"memub", "LDriub", IntRegs, s4_0Imm, 0b1001>;
}
+// post increment halfword loads with immediate offset
+let accessSize = HalfWordAccess, opExtentAlign = 1, isCodeGenOnly = 0 in {
+ defm loadrh : LD_PostInc <"memh", "LDrih", IntRegs, s4_1Imm, 0b1010>;
+ defm loadruh : LD_PostInc <"memuh", "LDriuh", IntRegs, s4_1Imm, 0b1011>;
+}
+
+// post increment word loads with immediate offset
+let accessSize = WordAccess, opExtentAlign = 2, isCodeGenOnly = 0 in
+defm loadri : LD_PostInc <"memw", "LDriw", IntRegs, s4_2Imm, 0b1100>;
+
+// post increment doubleword loads with immediate offset
+let accessSize = DoubleWordAccess, opExtentAlign = 3, isCodeGenOnly = 0 in
+defm loadrd : LD_PostInc <"memd", "LDrid", DoubleRegs, s4_3Imm, 0b1110>;
+
def : Pat< (i32 (extloadi1 ADDRriS11_0:$addr)),
- (i32 (LDrib ADDRriS11_0:$addr)) >;
+ (i32 (L2_loadrb_io AddrFI:$addr, 0)) >;
// Load byte any-extend.
def : Pat < (i32 (extloadi8 ADDRriS11_0:$addr)),
- (i32 (LDrib ADDRriS11_0:$addr)) >;
+ (i32 (L2_loadrb_io AddrFI:$addr, 0)) >;
// Indexed load byte any-extend.
let AddedComplexity = 20 in
def : Pat < (i32 (extloadi8 (add IntRegs:$src1, s11_0ImmPred:$offset))),
- (i32 (LDrib_indexed IntRegs:$src1, s11_0ImmPred:$offset)) >;
+ (i32 (L2_loadrb_io IntRegs:$src1, s11_0ImmPred:$offset)) >;
def : Pat < (i32 (extloadi16 ADDRriS11_1:$addr)),
- (i32 (LDrih ADDRriS11_1:$addr))>;
+ (i32 (L2_loadrh_io AddrFI:$addr, 0))>;
let AddedComplexity = 20 in
def : Pat < (i32 (extloadi16 (add IntRegs:$src1, s11_1ImmPred:$offset))),
- (i32 (LDrih_indexed IntRegs:$src1, s11_1ImmPred:$offset)) >;
+ (i32 (L2_loadrh_io IntRegs:$src1, s11_1ImmPred:$offset)) >;
let AddedComplexity = 10 in
def : Pat < (i32 (zextloadi1 ADDRriS11_0:$addr)),
- (i32 (LDriub ADDRriS11_0:$addr))>;
+ (i32 (L2_loadrub_io AddrFI:$addr, 0))>;
let AddedComplexity = 20 in
def : Pat < (i32 (zextloadi1 (add IntRegs:$src1, s11_0ImmPred:$offset))),
- (i32 (LDriub_indexed IntRegs:$src1, s11_0ImmPred:$offset))>;
+ (i32 (L2_loadrub_io IntRegs:$src1, s11_0ImmPred:$offset))>;
+
+//===----------------------------------------------------------------------===//
+// Template class for post increment loads with register offset.
+//===----------------------------------------------------------------------===//
+let hasSideEffects = 0, addrMode = PostInc in
+class T_load_pr <string mnemonic, RegisterClass RC, bits<4> MajOp,
+ MemAccessSize AccessSz>
+ : LDInstPI <(outs RC:$dst, IntRegs:$_dst_),
+ (ins IntRegs:$src1, ModRegs:$src2),
+ "$dst = "#mnemonic#"($src1++$src2)" ,
+ [], "$src1 = $_dst_" > {
+ bits<5> dst;
+ bits<5> src1;
+ bits<1> src2;
+
+ let accessSize = AccessSz;
+ let IClass = 0b1001;
+
+ let Inst{27-25} = 0b110;
+ let Inst{24-21} = MajOp;
+ let Inst{20-16} = src1;
+ let Inst{13} = src2;
+ let Inst{12} = 0b0;
+ let Inst{7} = 0b0;
+ let Inst{4-0} = dst;
+ }
+
+let hasNewValue = 1, isCodeGenOnly = 0 in {
+ def L2_loadrb_pr : T_load_pr <"memb", IntRegs, 0b1000, ByteAccess>;
+ def L2_loadrub_pr : T_load_pr <"memub", IntRegs, 0b1001, ByteAccess>;
+ def L2_loadrh_pr : T_load_pr <"memh", IntRegs, 0b1010, HalfWordAccess>;
+ def L2_loadruh_pr : T_load_pr <"memuh", IntRegs, 0b1011, HalfWordAccess>;
+ def L2_loadri_pr : T_load_pr <"memw", IntRegs, 0b1100, WordAccess>;
+}
+
+let isCodeGenOnly = 0 in
+def L2_loadrd_pr : T_load_pr <"memd", DoubleRegs, 0b1110, DoubleWordAccess>;
// Load predicate.
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13,
-isPseudo = 1, Defs = [R10,R11,D5], neverHasSideEffects = 1 in
+isPseudo = 1, Defs = [R10,R11,D5], hasSideEffects = 0 in
def LDriw_pred : LDInst2<(outs PredRegs:$dst),
(ins MEMri:$addr),
"Error; should not emit",
[]>;
-// Deallocate stack frame.
-let Defs = [R29, R30, R31], Uses = [R29], neverHasSideEffects = 1 in {
- def DEALLOCFRAME : LDInst2<(outs), (ins),
+let Defs = [R29, R30, R31], Uses = [R30], hasSideEffects = 0, isCodeGenOnly = 0 in
+ def L2_deallocframe : LDInst<(outs), (ins),
"deallocframe",
- []>;
+ []> {
+ let IClass = 0b1001;
+
+ let Inst{27-16} = 0b000000011110;
+ let Inst{13} = 0b0;
+ let Inst{4-0} = 0b11110;
+}
+
+// Load / Post increment circular addressing mode.
+let Uses = [CS], hasSideEffects = 0, hasNewValue = 1, opNewValue = 0 in
+class T_load_pcr<string mnemonic, RegisterClass RC, bits<4> MajOp>
+ : LDInst <(outs RC:$dst, IntRegs:$_dst_),
+ (ins IntRegs:$Rz, ModRegs:$Mu),
+ "$dst = "#mnemonic#"($Rz ++ I:circ($Mu))", [],
+ "$Rz = $_dst_" > {
+ bits<5> dst;
+ bits<5> Rz;
+ bit Mu;
+
+ let IClass = 0b1001;
+
+ let Inst{27-25} = 0b100;
+ let Inst{24-21} = MajOp;
+ let Inst{20-16} = Rz;
+ let Inst{13} = Mu;
+ let Inst{12} = 0b0;
+ let Inst{9} = 0b1;
+ let Inst{7} = 0b0;
+ let Inst{4-0} = dst;
+ }
+
+let accessSize = ByteAccess, isCodeGenOnly = 0 in {
+ def L2_loadrb_pcr : T_load_pcr <"memb", IntRegs, 0b1000>;
+ def L2_loadrub_pcr : T_load_pcr <"memub", IntRegs, 0b1001>;
+}
+
+let accessSize = HalfWordAccess, isCodeGenOnly = 0 in {
+ def L2_loadrh_pcr : T_load_pcr <"memh", IntRegs, 0b1010>;
+ def L2_loadruh_pcr : T_load_pcr <"memuh", IntRegs, 0b1011>;
+}
+
+let accessSize = WordAccess, isCodeGenOnly = 0 in {
+ def L2_loadri_pcr : T_load_pcr <"memw", IntRegs, 0b1100>;
}
-// Load and unpack bytes to halfwords.
+let accessSize = DoubleWordAccess, isCodeGenOnly = 0 in
+def L2_loadrd_pcr : T_load_pcr <"memd", DoubleRegs, 0b1110>;
+
+//===----------------------------------------------------------------------===//
+// Circular loads with immediate offset.
+//===----------------------------------------------------------------------===//
+let Uses = [CS], mayLoad = 1, hasSideEffects = 0, hasNewValue = 1 in
+class T_load_pci <string mnemonic, RegisterClass RC,
+ Operand ImmOp, bits<4> MajOp>
+ : LDInstPI<(outs RC:$dst, IntRegs:$_dst_),
+ (ins IntRegs:$Rz, ImmOp:$offset, ModRegs:$Mu),
+ "$dst = "#mnemonic#"($Rz ++ #$offset:circ($Mu))", [],
+ "$Rz = $_dst_"> {
+ bits<5> dst;
+ bits<5> Rz;
+ bits<1> Mu;
+ bits<7> offset;
+ bits<4> offsetBits;
+
+ string ImmOpStr = !cast<string>(ImmOp);
+ let offsetBits = !if (!eq(ImmOpStr, "s4_3Imm"), offset{6-3},
+ !if (!eq(ImmOpStr, "s4_2Imm"), offset{5-2},
+ !if (!eq(ImmOpStr, "s4_1Imm"), offset{4-1},
+ /* s4_0Imm */ offset{3-0})));
+ let IClass = 0b1001;
+ let Inst{27-25} = 0b100;
+ let Inst{24-21} = MajOp;
+ let Inst{20-16} = Rz;
+ let Inst{13} = Mu;
+ let Inst{12} = 0b0;
+ let Inst{9} = 0b0;
+ let Inst{8-5} = offsetBits;
+ let Inst{4-0} = dst;
+ }
+
+// Byte variants of circ load
+let accessSize = ByteAccess, isCodeGenOnly = 0 in {
+ def L2_loadrb_pci : T_load_pci <"memb", IntRegs, s4_0Imm, 0b1000>;
+ def L2_loadrub_pci : T_load_pci <"memub", IntRegs, s4_0Imm, 0b1001>;
+}
+
+// Half word variants of circ load
+let accessSize = HalfWordAccess, isCodeGenOnly = 0 in {
+ def L2_loadrh_pci : T_load_pci <"memh", IntRegs, s4_1Imm, 0b1010>;
+ def L2_loadruh_pci : T_load_pci <"memuh", IntRegs, s4_1Imm, 0b1011>;
+}
+
+// Word variants of circ load
+let accessSize = WordAccess, isCodeGenOnly = 0 in
+def L2_loadri_pci : T_load_pci <"memw", IntRegs, s4_2Imm, 0b1100>;
+
+let accessSize = DoubleWordAccess, hasNewValue = 0, isCodeGenOnly = 0 in
+def L2_loadrd_pci : T_load_pci <"memd", DoubleRegs, s4_3Imm, 0b1110>;
+
+// L[24]_load[wd]_locked: Load word/double with lock.
+let isSoloAX = 1 in
+class T_load_locked <string mnemonic, RegisterClass RC>
+ : LD0Inst <(outs RC:$dst),
+ (ins IntRegs:$src),
+ "$dst = "#mnemonic#"($src)"> {
+ bits<5> dst;
+ bits<5> src;
+ let IClass = 0b1001;
+ let Inst{27-21} = 0b0010000;
+ let Inst{20-16} = src;
+ let Inst{13-12} = !if (!eq(mnemonic, "memd_locked"), 0b01, 0b00);
+ let Inst{4-0} = dst;
+}
+let hasNewValue = 1, accessSize = WordAccess, opNewValue = 0, isCodeGenOnly = 0 in
+ def L2_loadw_locked : T_load_locked <"memw_locked", IntRegs>;
+let accessSize = DoubleWordAccess, isCodeGenOnly = 0 in
+ def L4_loadd_locked : T_load_locked <"memd_locked", DoubleRegs>;
+//===----------------------------------------------------------------------===//
+// Bit-reversed loads with auto-increment register
+//===----------------------------------------------------------------------===//
+let hasSideEffects = 0 in
+class T_load_pbr<string mnemonic, RegisterClass RC,
+ MemAccessSize addrSize, bits<4> majOp>
+ : LDInst
+ <(outs RC:$dst, IntRegs:$_dst_),
+ (ins IntRegs:$Rz, ModRegs:$Mu),
+ "$dst = "#mnemonic#"($Rz ++ $Mu:brev)" ,
+ [] , "$Rz = $_dst_" > {
+
+ let accessSize = addrSize;
+
+ bits<5> dst;
+ bits<5> Rz;
+ bits<1> Mu;
+
+ let IClass = 0b1001;
+
+ let Inst{27-25} = 0b111;
+ let Inst{24-21} = majOp;
+ let Inst{20-16} = Rz;
+ let Inst{13} = Mu;
+ let Inst{12} = 0b0;
+ let Inst{7} = 0b0;
+ let Inst{4-0} = dst;
+ }
+
+let hasNewValue =1, opNewValue = 0, isCodeGenOnly = 0 in {
+ def L2_loadrb_pbr : T_load_pbr <"memb", IntRegs, ByteAccess, 0b1000>;
+ def L2_loadrub_pbr : T_load_pbr <"memub", IntRegs, ByteAccess, 0b1001>;
+ def L2_loadrh_pbr : T_load_pbr <"memh", IntRegs, HalfWordAccess, 0b1010>;
+ def L2_loadruh_pbr : T_load_pbr <"memuh", IntRegs, HalfWordAccess, 0b1011>;
+ def L2_loadri_pbr : T_load_pbr <"memw", IntRegs, WordAccess, 0b1100>;
+}
+
+let isCodeGenOnly = 0 in
+def L2_loadrd_pbr : T_load_pbr <"memd", DoubleRegs, DoubleWordAccess, 0b1110>;
+
//===----------------------------------------------------------------------===//
// LD -
//===----------------------------------------------------------------------===//
@@ -1180,180 +1968,663 @@ let Defs = [R29, R30, R31], Uses = [R29], neverHasSideEffects = 1 in {
//===----------------------------------------------------------------------===//
// MTYPE/MPYH +
//===----------------------------------------------------------------------===//
-// Multiply and use lower result.
-// Rd=+mpyi(Rs,#u8)
-let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 8 in
-def MPYI_riu : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u8Ext:$src2),
- "$dst =+ mpyi($src1, #$src2)",
- [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1),
- u8ExtPred:$src2))]>;
-// Rd=-mpyi(Rs,#u8)
-def MPYI_rin : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u8Imm:$src2),
- "$dst =- mpyi($src1, #$src2)",
- [(set (i32 IntRegs:$dst), (ineg (mul (i32 IntRegs:$src1),
- u8ImmPred:$src2)))]>;
+//===----------------------------------------------------------------------===//
+// Template Class
+// MPYS / Multipy signed/unsigned halfwords
+//Rd=mpy[u](Rs.[H|L],Rt.[H|L])[:<<1][:rnd][:sat]
+//===----------------------------------------------------------------------===//
+
+let hasNewValue = 1, opNewValue = 0 in
+class T_M2_mpy < bits<2> LHbits, bit isSat, bit isRnd,
+ bit hasShift, bit isUnsigned>
+ : MInst < (outs IntRegs:$Rd), (ins IntRegs:$Rs, IntRegs:$Rt),
+ "$Rd = "#!if(isUnsigned,"mpyu","mpy")#"($Rs."#!if(LHbits{1},"h","l")
+ #", $Rt."#!if(LHbits{0},"h)","l)")
+ #!if(hasShift,":<<1","")
+ #!if(isRnd,":rnd","")
+ #!if(isSat,":sat",""),
+ [], "", M_tc_3x_SLOT23 > {
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1110;
+
+ let Inst{27-24} = 0b1100;
+ let Inst{23} = hasShift;
+ let Inst{22} = isUnsigned;
+ let Inst{21} = isRnd;
+ let Inst{7} = isSat;
+ let Inst{6-5} = LHbits;
+ let Inst{4-0} = Rd;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ }
+
+//Rd=mpy(Rs.[H|L],Rt.[H|L])[:<<1]
+let isCodeGenOnly = 0 in {
+def M2_mpy_ll_s1: T_M2_mpy<0b00, 0, 0, 1, 0>;
+def M2_mpy_ll_s0: T_M2_mpy<0b00, 0, 0, 0, 0>;
+def M2_mpy_lh_s1: T_M2_mpy<0b01, 0, 0, 1, 0>;
+def M2_mpy_lh_s0: T_M2_mpy<0b01, 0, 0, 0, 0>;
+def M2_mpy_hl_s1: T_M2_mpy<0b10, 0, 0, 1, 0>;
+def M2_mpy_hl_s0: T_M2_mpy<0b10, 0, 0, 0, 0>;
+def M2_mpy_hh_s1: T_M2_mpy<0b11, 0, 0, 1, 0>;
+def M2_mpy_hh_s0: T_M2_mpy<0b11, 0, 0, 0, 0>;
+}
+
+//Rd=mpyu(Rs.[H|L],Rt.[H|L])[:<<1]
+let isCodeGenOnly = 0 in {
+def M2_mpyu_ll_s1: T_M2_mpy<0b00, 0, 0, 1, 1>;
+def M2_mpyu_ll_s0: T_M2_mpy<0b00, 0, 0, 0, 1>;
+def M2_mpyu_lh_s1: T_M2_mpy<0b01, 0, 0, 1, 1>;
+def M2_mpyu_lh_s0: T_M2_mpy<0b01, 0, 0, 0, 1>;
+def M2_mpyu_hl_s1: T_M2_mpy<0b10, 0, 0, 1, 1>;
+def M2_mpyu_hl_s0: T_M2_mpy<0b10, 0, 0, 0, 1>;
+def M2_mpyu_hh_s1: T_M2_mpy<0b11, 0, 0, 1, 1>;
+def M2_mpyu_hh_s0: T_M2_mpy<0b11, 0, 0, 0, 1>;
+}
+
+//Rd=mpy(Rs.[H|L],Rt.[H|L])[:<<1]:rnd
+let isCodeGenOnly = 0 in {
+def M2_mpy_rnd_ll_s1: T_M2_mpy <0b00, 0, 1, 1, 0>;
+def M2_mpy_rnd_ll_s0: T_M2_mpy <0b00, 0, 1, 0, 0>;
+def M2_mpy_rnd_lh_s1: T_M2_mpy <0b01, 0, 1, 1, 0>;
+def M2_mpy_rnd_lh_s0: T_M2_mpy <0b01, 0, 1, 0, 0>;
+def M2_mpy_rnd_hl_s1: T_M2_mpy <0b10, 0, 1, 1, 0>;
+def M2_mpy_rnd_hl_s0: T_M2_mpy <0b10, 0, 1, 0, 0>;
+def M2_mpy_rnd_hh_s1: T_M2_mpy <0b11, 0, 1, 1, 0>;
+def M2_mpy_rnd_hh_s0: T_M2_mpy <0b11, 0, 1, 0, 0>;
+}
+
+//Rd=mpy(Rs.[H|L],Rt.[H|L])[:<<1][:sat]
+//Rd=mpy(Rs.[H|L],Rt.[H|L])[:<<1][:rnd][:sat]
+let Defs = [USR_OVF], isCodeGenOnly = 0 in {
+ def M2_mpy_sat_ll_s1: T_M2_mpy <0b00, 1, 0, 1, 0>;
+ def M2_mpy_sat_ll_s0: T_M2_mpy <0b00, 1, 0, 0, 0>;
+ def M2_mpy_sat_lh_s1: T_M2_mpy <0b01, 1, 0, 1, 0>;
+ def M2_mpy_sat_lh_s0: T_M2_mpy <0b01, 1, 0, 0, 0>;
+ def M2_mpy_sat_hl_s1: T_M2_mpy <0b10, 1, 0, 1, 0>;
+ def M2_mpy_sat_hl_s0: T_M2_mpy <0b10, 1, 0, 0, 0>;
+ def M2_mpy_sat_hh_s1: T_M2_mpy <0b11, 1, 0, 1, 0>;
+ def M2_mpy_sat_hh_s0: T_M2_mpy <0b11, 1, 0, 0, 0>;
+
+ def M2_mpy_sat_rnd_ll_s1: T_M2_mpy <0b00, 1, 1, 1, 0>;
+ def M2_mpy_sat_rnd_ll_s0: T_M2_mpy <0b00, 1, 1, 0, 0>;
+ def M2_mpy_sat_rnd_lh_s1: T_M2_mpy <0b01, 1, 1, 1, 0>;
+ def M2_mpy_sat_rnd_lh_s0: T_M2_mpy <0b01, 1, 1, 0, 0>;
+ def M2_mpy_sat_rnd_hl_s1: T_M2_mpy <0b10, 1, 1, 1, 0>;
+ def M2_mpy_sat_rnd_hl_s0: T_M2_mpy <0b10, 1, 1, 0, 0>;
+ def M2_mpy_sat_rnd_hh_s1: T_M2_mpy <0b11, 1, 1, 1, 0>;
+ def M2_mpy_sat_rnd_hh_s0: T_M2_mpy <0b11, 1, 1, 0, 0>;
+}
+
+//===----------------------------------------------------------------------===//
+// Template Class
+// MPYS / Multipy signed/unsigned halfwords and add/subtract the
+// result from the accumulator.
+//Rx [-+]= mpy[u](Rs.[H|L],Rt.[H|L])[:<<1][:sat]
+//===----------------------------------------------------------------------===//
+
+let hasNewValue = 1, opNewValue = 0 in
+class T_M2_mpy_acc < bits<2> LHbits, bit isSat, bit isNac,
+ bit hasShift, bit isUnsigned >
+ : MInst_acc<(outs IntRegs:$Rx), (ins IntRegs:$dst2, IntRegs:$Rs, IntRegs:$Rt),
+ "$Rx "#!if(isNac,"-= ","+= ")#!if(isUnsigned,"mpyu","mpy")
+ #"($Rs."#!if(LHbits{1},"h","l")
+ #", $Rt."#!if(LHbits{0},"h)","l)")
+ #!if(hasShift,":<<1","")
+ #!if(isSat,":sat",""),
+ [], "$dst2 = $Rx", M_tc_3x_SLOT23 > {
+ bits<5> Rx;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1110;
+ let Inst{27-24} = 0b1110;
+ let Inst{23} = hasShift;
+ let Inst{22} = isUnsigned;
+ let Inst{21} = isNac;
+ let Inst{7} = isSat;
+ let Inst{6-5} = LHbits;
+ let Inst{4-0} = Rx;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ }
+
+//Rx += mpy(Rs.[H|L],Rt.[H|L])[:<<1]
+let isCodeGenOnly = 0 in {
+def M2_mpy_acc_ll_s1: T_M2_mpy_acc <0b00, 0, 0, 1, 0>;
+def M2_mpy_acc_ll_s0: T_M2_mpy_acc <0b00, 0, 0, 0, 0>;
+def M2_mpy_acc_lh_s1: T_M2_mpy_acc <0b01, 0, 0, 1, 0>;
+def M2_mpy_acc_lh_s0: T_M2_mpy_acc <0b01, 0, 0, 0, 0>;
+def M2_mpy_acc_hl_s1: T_M2_mpy_acc <0b10, 0, 0, 1, 0>;
+def M2_mpy_acc_hl_s0: T_M2_mpy_acc <0b10, 0, 0, 0, 0>;
+def M2_mpy_acc_hh_s1: T_M2_mpy_acc <0b11, 0, 0, 1, 0>;
+def M2_mpy_acc_hh_s0: T_M2_mpy_acc <0b11, 0, 0, 0, 0>;
+}
+
+//Rx += mpyu(Rs.[H|L],Rt.[H|L])[:<<1]
+let isCodeGenOnly = 0 in {
+def M2_mpyu_acc_ll_s1: T_M2_mpy_acc <0b00, 0, 0, 1, 1>;
+def M2_mpyu_acc_ll_s0: T_M2_mpy_acc <0b00, 0, 0, 0, 1>;
+def M2_mpyu_acc_lh_s1: T_M2_mpy_acc <0b01, 0, 0, 1, 1>;
+def M2_mpyu_acc_lh_s0: T_M2_mpy_acc <0b01, 0, 0, 0, 1>;
+def M2_mpyu_acc_hl_s1: T_M2_mpy_acc <0b10, 0, 0, 1, 1>;
+def M2_mpyu_acc_hl_s0: T_M2_mpy_acc <0b10, 0, 0, 0, 1>;
+def M2_mpyu_acc_hh_s1: T_M2_mpy_acc <0b11, 0, 0, 1, 1>;
+def M2_mpyu_acc_hh_s0: T_M2_mpy_acc <0b11, 0, 0, 0, 1>;
+}
+
+//Rx -= mpy(Rs.[H|L],Rt.[H|L])[:<<1]
+let isCodeGenOnly = 0 in {
+def M2_mpy_nac_ll_s1: T_M2_mpy_acc <0b00, 0, 1, 1, 0>;
+def M2_mpy_nac_ll_s0: T_M2_mpy_acc <0b00, 0, 1, 0, 0>;
+def M2_mpy_nac_lh_s1: T_M2_mpy_acc <0b01, 0, 1, 1, 0>;
+def M2_mpy_nac_lh_s0: T_M2_mpy_acc <0b01, 0, 1, 0, 0>;
+def M2_mpy_nac_hl_s1: T_M2_mpy_acc <0b10, 0, 1, 1, 0>;
+def M2_mpy_nac_hl_s0: T_M2_mpy_acc <0b10, 0, 1, 0, 0>;
+def M2_mpy_nac_hh_s1: T_M2_mpy_acc <0b11, 0, 1, 1, 0>;
+def M2_mpy_nac_hh_s0: T_M2_mpy_acc <0b11, 0, 1, 0, 0>;
+}
+
+//Rx -= mpyu(Rs.[H|L],Rt.[H|L])[:<<1]
+let isCodeGenOnly = 0 in {
+def M2_mpyu_nac_ll_s1: T_M2_mpy_acc <0b00, 0, 1, 1, 1>;
+def M2_mpyu_nac_ll_s0: T_M2_mpy_acc <0b00, 0, 1, 0, 1>;
+def M2_mpyu_nac_lh_s1: T_M2_mpy_acc <0b01, 0, 1, 1, 1>;
+def M2_mpyu_nac_lh_s0: T_M2_mpy_acc <0b01, 0, 1, 0, 1>;
+def M2_mpyu_nac_hl_s1: T_M2_mpy_acc <0b10, 0, 1, 1, 1>;
+def M2_mpyu_nac_hl_s0: T_M2_mpy_acc <0b10, 0, 1, 0, 1>;
+def M2_mpyu_nac_hh_s1: T_M2_mpy_acc <0b11, 0, 1, 1, 1>;
+def M2_mpyu_nac_hh_s0: T_M2_mpy_acc <0b11, 0, 1, 0, 1>;
+}
+
+//Rx += mpy(Rs.[H|L],Rt.[H|L])[:<<1]:sat
+let isCodeGenOnly = 0 in {
+def M2_mpy_acc_sat_ll_s1: T_M2_mpy_acc <0b00, 1, 0, 1, 0>;
+def M2_mpy_acc_sat_ll_s0: T_M2_mpy_acc <0b00, 1, 0, 0, 0>;
+def M2_mpy_acc_sat_lh_s1: T_M2_mpy_acc <0b01, 1, 0, 1, 0>;
+def M2_mpy_acc_sat_lh_s0: T_M2_mpy_acc <0b01, 1, 0, 0, 0>;
+def M2_mpy_acc_sat_hl_s1: T_M2_mpy_acc <0b10, 1, 0, 1, 0>;
+def M2_mpy_acc_sat_hl_s0: T_M2_mpy_acc <0b10, 1, 0, 0, 0>;
+def M2_mpy_acc_sat_hh_s1: T_M2_mpy_acc <0b11, 1, 0, 1, 0>;
+def M2_mpy_acc_sat_hh_s0: T_M2_mpy_acc <0b11, 1, 0, 0, 0>;
+}
+
+//Rx -= mpy(Rs.[H|L],Rt.[H|L])[:<<1]:sat
+let isCodeGenOnly = 0 in {
+def M2_mpy_nac_sat_ll_s1: T_M2_mpy_acc <0b00, 1, 1, 1, 0>;
+def M2_mpy_nac_sat_ll_s0: T_M2_mpy_acc <0b00, 1, 1, 0, 0>;
+def M2_mpy_nac_sat_lh_s1: T_M2_mpy_acc <0b01, 1, 1, 1, 0>;
+def M2_mpy_nac_sat_lh_s0: T_M2_mpy_acc <0b01, 1, 1, 0, 0>;
+def M2_mpy_nac_sat_hl_s1: T_M2_mpy_acc <0b10, 1, 1, 1, 0>;
+def M2_mpy_nac_sat_hl_s0: T_M2_mpy_acc <0b10, 1, 1, 0, 0>;
+def M2_mpy_nac_sat_hh_s1: T_M2_mpy_acc <0b11, 1, 1, 1, 0>;
+def M2_mpy_nac_sat_hh_s0: T_M2_mpy_acc <0b11, 1, 1, 0, 0>;
+}
+
+//===----------------------------------------------------------------------===//
+// Template Class
+// MPYS / Multipy signed/unsigned halfwords and add/subtract the
+// result from the 64-bit destination register.
+//Rxx [-+]= mpy[u](Rs.[H|L],Rt.[H|L])[:<<1][:sat]
+//===----------------------------------------------------------------------===//
+
+class T_M2_mpyd_acc < bits<2> LHbits, bit isNac, bit hasShift, bit isUnsigned>
+ : MInst_acc<(outs DoubleRegs:$Rxx),
+ (ins DoubleRegs:$dst2, IntRegs:$Rs, IntRegs:$Rt),
+ "$Rxx "#!if(isNac,"-= ","+= ")#!if(isUnsigned,"mpyu","mpy")
+ #"($Rs."#!if(LHbits{1},"h","l")
+ #", $Rt."#!if(LHbits{0},"h)","l)")
+ #!if(hasShift,":<<1",""),
+ [], "$dst2 = $Rxx", M_tc_3x_SLOT23 > {
+ bits<5> Rxx;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1110;
+
+ let Inst{27-24} = 0b0110;
+ let Inst{23} = hasShift;
+ let Inst{22} = isUnsigned;
+ let Inst{21} = isNac;
+ let Inst{7} = 0;
+ let Inst{6-5} = LHbits;
+ let Inst{4-0} = Rxx;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ }
+
+let isCodeGenOnly = 0 in {
+def M2_mpyd_acc_hh_s0: T_M2_mpyd_acc <0b11, 0, 0, 0>;
+def M2_mpyd_acc_hl_s0: T_M2_mpyd_acc <0b10, 0, 0, 0>;
+def M2_mpyd_acc_lh_s0: T_M2_mpyd_acc <0b01, 0, 0, 0>;
+def M2_mpyd_acc_ll_s0: T_M2_mpyd_acc <0b00, 0, 0, 0>;
+
+def M2_mpyd_acc_hh_s1: T_M2_mpyd_acc <0b11, 0, 1, 0>;
+def M2_mpyd_acc_hl_s1: T_M2_mpyd_acc <0b10, 0, 1, 0>;
+def M2_mpyd_acc_lh_s1: T_M2_mpyd_acc <0b01, 0, 1, 0>;
+def M2_mpyd_acc_ll_s1: T_M2_mpyd_acc <0b00, 0, 1, 0>;
+
+def M2_mpyd_nac_hh_s0: T_M2_mpyd_acc <0b11, 1, 0, 0>;
+def M2_mpyd_nac_hl_s0: T_M2_mpyd_acc <0b10, 1, 0, 0>;
+def M2_mpyd_nac_lh_s0: T_M2_mpyd_acc <0b01, 1, 0, 0>;
+def M2_mpyd_nac_ll_s0: T_M2_mpyd_acc <0b00, 1, 0, 0>;
+
+def M2_mpyd_nac_hh_s1: T_M2_mpyd_acc <0b11, 1, 1, 0>;
+def M2_mpyd_nac_hl_s1: T_M2_mpyd_acc <0b10, 1, 1, 0>;
+def M2_mpyd_nac_lh_s1: T_M2_mpyd_acc <0b01, 1, 1, 0>;
+def M2_mpyd_nac_ll_s1: T_M2_mpyd_acc <0b00, 1, 1, 0>;
+
+def M2_mpyud_acc_hh_s0: T_M2_mpyd_acc <0b11, 0, 0, 1>;
+def M2_mpyud_acc_hl_s0: T_M2_mpyd_acc <0b10, 0, 0, 1>;
+def M2_mpyud_acc_lh_s0: T_M2_mpyd_acc <0b01, 0, 0, 1>;
+def M2_mpyud_acc_ll_s0: T_M2_mpyd_acc <0b00, 0, 0, 1>;
+
+def M2_mpyud_acc_hh_s1: T_M2_mpyd_acc <0b11, 0, 1, 1>;
+def M2_mpyud_acc_hl_s1: T_M2_mpyd_acc <0b10, 0, 1, 1>;
+def M2_mpyud_acc_lh_s1: T_M2_mpyd_acc <0b01, 0, 1, 1>;
+def M2_mpyud_acc_ll_s1: T_M2_mpyd_acc <0b00, 0, 1, 1>;
+
+def M2_mpyud_nac_hh_s0: T_M2_mpyd_acc <0b11, 1, 0, 1>;
+def M2_mpyud_nac_hl_s0: T_M2_mpyd_acc <0b10, 1, 0, 1>;
+def M2_mpyud_nac_lh_s0: T_M2_mpyd_acc <0b01, 1, 0, 1>;
+def M2_mpyud_nac_ll_s0: T_M2_mpyd_acc <0b00, 1, 0, 1>;
+
+def M2_mpyud_nac_hh_s1: T_M2_mpyd_acc <0b11, 1, 1, 1>;
+def M2_mpyud_nac_hl_s1: T_M2_mpyd_acc <0b10, 1, 1, 1>;
+def M2_mpyud_nac_lh_s1: T_M2_mpyd_acc <0b01, 1, 1, 1>;
+def M2_mpyud_nac_ll_s1: T_M2_mpyd_acc <0b00, 1, 1, 1>;
+}
+
+let hasNewValue = 1, opNewValue = 0 in
+class T_MType_mpy <string mnemonic, bits<4> RegTyBits, RegisterClass RC,
+ bits<3> MajOp, bits<3> MinOp, bit isSat = 0, bit isRnd = 0,
+ string op2Suffix = "", bit isRaw = 0, bit isHi = 0 >
+ : MInst <(outs IntRegs:$dst), (ins RC:$src1, RC:$src2),
+ "$dst = "#mnemonic
+ #"($src1, $src2"#op2Suffix#")"
+ #!if(MajOp{2}, ":<<1", "")
+ #!if(isRnd, ":rnd", "")
+ #!if(isSat, ":sat", "")
+ #!if(isRaw, !if(isHi, ":raw:hi", ":raw:lo"), ""), [] > {
+ bits<5> dst;
+ bits<5> src1;
+ bits<5> src2;
+
+ let IClass = 0b1110;
+
+ let Inst{27-24} = RegTyBits;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = src1;
+ let Inst{13} = 0b0;
+ let Inst{12-8} = src2;
+ let Inst{7-5} = MinOp;
+ let Inst{4-0} = dst;
+ }
+
+class T_MType_dd <string mnemonic, bits<3> MajOp, bits<3> MinOp,
+ bit isSat = 0, bit isRnd = 0 >
+ : T_MType_mpy <mnemonic, 0b1001, DoubleRegs, MajOp, MinOp, isSat, isRnd>;
+
+class T_MType_rr1 <string mnemonic, bits<3> MajOp, bits<3> MinOp,
+ bit isSat = 0, bit isRnd = 0 >
+ : T_MType_mpy<mnemonic, 0b1101, IntRegs, MajOp, MinOp, isSat, isRnd>;
+
+class T_MType_rr2 <string mnemonic, bits<3> MajOp, bits<3> MinOp,
+ bit isSat = 0, bit isRnd = 0, string op2str = "" >
+ : T_MType_mpy<mnemonic, 0b1101, IntRegs, MajOp, MinOp, isSat, isRnd, op2str>;
+
+let CextOpcode = "mpyi", InputType = "reg", isCodeGenOnly = 0 in
+def M2_mpyi : T_MType_rr1 <"mpyi", 0b000, 0b000>, ImmRegRel;
+
+let isCodeGenOnly = 0 in {
+def M2_mpy_up : T_MType_rr1 <"mpy", 0b000, 0b001>;
+def M2_mpyu_up : T_MType_rr1 <"mpyu", 0b010, 0b001>;
+}
+
+let isCodeGenOnly = 0 in
+def M2_dpmpyss_rnd_s0 : T_MType_rr1 <"mpy", 0b001, 0b001, 0, 1>;
+
+let isCodeGenOnly = 0 in {
+def M2_hmmpyh_rs1 : T_MType_rr2 <"mpy", 0b101, 0b100, 1, 1, ".h">;
+def M2_hmmpyl_rs1 : T_MType_rr2 <"mpy", 0b111, 0b100, 1, 1, ".l">;
+}
+
+// V4 Instructions
+let isCodeGenOnly = 0 in {
+def M2_mpysu_up : T_MType_rr1 <"mpysu", 0b011, 0b001, 0>;
+def M2_mpy_up_s1_sat : T_MType_rr1 <"mpy", 0b111, 0b000, 1>;
+
+def M2_hmmpyh_s1 : T_MType_rr2 <"mpy", 0b101, 0b000, 1, 0, ".h">;
+def M2_hmmpyl_s1 : T_MType_rr2 <"mpy", 0b101, 0b001, 1, 0, ".l">;
+}
+
+def: Pat<(i32 (mul I32:$src1, I32:$src2)), (M2_mpyi I32:$src1, I32:$src2)>;
+def: Pat<(i32 (mulhs I32:$src1, I32:$src2)), (M2_mpy_up I32:$src1, I32:$src2)>;
+def: Pat<(i32 (mulhu I32:$src1, I32:$src2)), (M2_mpyu_up I32:$src1, I32:$src2)>;
+
+let hasNewValue = 1, opNewValue = 0 in
+class T_MType_mpy_ri <bit isNeg, Operand ImmOp, list<dag> pattern>
+ : MInst < (outs IntRegs:$Rd), (ins IntRegs:$Rs, ImmOp:$u8),
+ "$Rd ="#!if(isNeg, "- ", "+ ")#"mpyi($Rs, #$u8)" ,
+ pattern, "", M_tc_3x_SLOT23> {
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<8> u8;
+
+ let IClass = 0b1110;
+
+ let Inst{27-24} = 0b0000;
+ let Inst{23} = isNeg;
+ let Inst{13} = 0b0;
+ let Inst{4-0} = Rd;
+ let Inst{20-16} = Rs;
+ let Inst{12-5} = u8;
+ }
+
+let isExtendable = 1, opExtentBits = 8, opExtendable = 2, isCodeGenOnly = 0 in
+def M2_mpysip : T_MType_mpy_ri <0, u8Ext,
+ [(set (i32 IntRegs:$Rd), (mul IntRegs:$Rs, u8ExtPred:$u8))]>;
+
+let isCodeGenOnly = 0 in
+def M2_mpysin : T_MType_mpy_ri <1, u8Imm,
+ [(set (i32 IntRegs:$Rd), (ineg (mul IntRegs:$Rs,
+ u8ImmPred:$u8)))]>;
+
+// Assember mapped to M2_mpyi
+let isAsmParserOnly = 1 in
+def M2_mpyui : MInst<(outs IntRegs:$dst),
+ (ins IntRegs:$src1, IntRegs:$src2),
+ "$dst = mpyui($src1, $src2)">;
// Rd=mpyi(Rs,#m9)
// s9 is NOT the same as m9 - but it works.. so far.
-// Assembler maps to either Rd=+mpyi(Rs,#u8 or Rd=-mpyi(Rs,#u8)
+// Assembler maps to either Rd=+mpyi(Rs,#u8) or Rd=-mpyi(Rs,#u8)
// depending on the value of m9. See Arch Spec.
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 9,
-CextOpcode = "MPYI", InputType = "imm" in
-def MPYI_ri : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, s9Ext:$src2),
- "$dst = mpyi($src1, #$src2)",
- [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1),
- s9ExtPred:$src2))]>, ImmRegRel;
-
-// Rd=mpyi(Rs,Rt)
-let CextOpcode = "MPYI", InputType = "reg" in
-def MPYI : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = mpyi($src1, $src2)",
- [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1),
- (i32 IntRegs:$src2)))]>, ImmRegRel;
-
-// Rx+=mpyi(Rs,#u8)
-let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 8,
-CextOpcode = "MPYI_acc", InputType = "imm" in
-def MPYI_acc_ri : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2, u8Ext:$src3),
- "$dst += mpyi($src2, #$src3)",
- [(set (i32 IntRegs:$dst),
- (add (mul (i32 IntRegs:$src2), u8ExtPred:$src3),
- (i32 IntRegs:$src1)))],
- "$src1 = $dst">, ImmRegRel;
+ CextOpcode = "mpyi", InputType = "imm", hasNewValue = 1 in
+def M2_mpysmi : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, s9Ext:$src2),
+ "$dst = mpyi($src1, #$src2)",
+ [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1),
+ s9ExtPred:$src2))]>, ImmRegRel;
+
+let hasNewValue = 1, isExtendable = 1, opExtentBits = 8, opExtendable = 3,
+ InputType = "imm" in
+class T_MType_acc_ri <string mnemonic, bits<3> MajOp, Operand ImmOp,
+ list<dag> pattern = []>
+ : MInst < (outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, ImmOp:$src3),
+ "$dst "#mnemonic#"($src2, #$src3)",
+ pattern, "$src1 = $dst", M_tc_2_SLOT23> {
+ bits<5> dst;
+ bits<5> src2;
+ bits<8> src3;
+
+ let IClass = 0b1110;
-// Rx+=mpyi(Rs,Rt)
-let CextOpcode = "MPYI_acc", InputType = "reg" in
-def MPYI_acc_rr : MInst_acc<(outs IntRegs:$dst),
+ let Inst{27-26} = 0b00;
+ let Inst{25-23} = MajOp;
+ let Inst{20-16} = src2;
+ let Inst{13} = 0b0;
+ let Inst{12-5} = src3;
+ let Inst{4-0} = dst;
+ }
+
+let InputType = "reg", hasNewValue = 1 in
+class T_MType_acc_rr <string mnemonic, bits<3> MajOp, bits<3> MinOp,
+ bit isSwap = 0, list<dag> pattern = [], bit hasNot = 0,
+ bit isSat = 0, bit isShift = 0>
+ : MInst < (outs IntRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "$dst += mpyi($src2, $src3)",
- [(set (i32 IntRegs:$dst),
- (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
- (i32 IntRegs:$src1)))],
- "$src1 = $dst">, ImmRegRel;
-
-// Rx-=mpyi(Rs,#u8)
-let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 8 in
-def MPYI_sub_ri : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2, u8Ext:$src3),
- "$dst -= mpyi($src2, #$src3)",
- [(set (i32 IntRegs:$dst),
- (sub (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
- u8ExtPred:$src3)))],
- "$src1 = $dst">;
-
-// Multiply and use upper result.
-// Rd=mpy(Rs,Rt.H):<<1:rnd:sat
-// Rd=mpy(Rs,Rt.L):<<1:rnd:sat
-// Rd=mpy(Rs,Rt)
-def MPY : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = mpy($src1, $src2)",
- [(set (i32 IntRegs:$dst), (mulhs (i32 IntRegs:$src1),
- (i32 IntRegs:$src2)))]>;
-
-// Rd=mpy(Rs,Rt):rnd
-// Rd=mpyu(Rs,Rt)
-def MPYU : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = mpyu($src1, $src2)",
- [(set (i32 IntRegs:$dst), (mulhu (i32 IntRegs:$src1),
- (i32 IntRegs:$src2)))]>;
-
-// Multiply and use full result.
-// Rdd=mpyu(Rs,Rt)
-def MPYU64 : MInst<(outs DoubleRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = mpyu($src1, $src2)",
- [(set (i64 DoubleRegs:$dst),
- (mul (i64 (anyext (i32 IntRegs:$src1))),
- (i64 (anyext (i32 IntRegs:$src2)))))]>;
-
-// Rdd=mpy(Rs,Rt)
-def MPY64 : MInst<(outs DoubleRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = mpy($src1, $src2)",
- [(set (i64 DoubleRegs:$dst),
- (mul (i64 (sext (i32 IntRegs:$src1))),
- (i64 (sext (i32 IntRegs:$src2)))))]>;
+ "$dst "#mnemonic#"($src2, "#!if(hasNot, "~$src3)","$src3)")
+ #!if(isShift, ":<<1", "")
+ #!if(isSat, ":sat", ""),
+ pattern, "$src1 = $dst", M_tc_2_SLOT23 > {
+ bits<5> dst;
+ bits<5> src2;
+ bits<5> src3;
+
+ let IClass = 0b1110;
+
+ let Inst{27-24} = 0b1111;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = !if(isSwap, src3, src2);
+ let Inst{13} = 0b0;
+ let Inst{12-8} = !if(isSwap, src2, src3);
+ let Inst{7-5} = MinOp;
+ let Inst{4-0} = dst;
+ }
+
+let CextOpcode = "MPYI_acc", Itinerary = M_tc_3x_SLOT23, isCodeGenOnly = 0 in {
+ def M2_macsip : T_MType_acc_ri <"+= mpyi", 0b010, u8Ext,
+ [(set (i32 IntRegs:$dst),
+ (add (mul IntRegs:$src2, u8ExtPred:$src3),
+ IntRegs:$src1))]>, ImmRegRel;
+
+ def M2_maci : T_MType_acc_rr <"+= mpyi", 0b000, 0b000, 0,
+ [(set (i32 IntRegs:$dst),
+ (add (mul IntRegs:$src2, IntRegs:$src3),
+ IntRegs:$src1))]>, ImmRegRel;
+}
+
+let CextOpcode = "ADD_acc", isCodeGenOnly = 0 in {
+ let isExtentSigned = 1 in
+ def M2_accii : T_MType_acc_ri <"+= add", 0b100, s8Ext,
+ [(set (i32 IntRegs:$dst),
+ (add (add (i32 IntRegs:$src2), s8_16ExtPred:$src3),
+ (i32 IntRegs:$src1)))]>, ImmRegRel;
+
+ def M2_acci : T_MType_acc_rr <"+= add", 0b000, 0b001, 0,
+ [(set (i32 IntRegs:$dst),
+ (add (add (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
+ (i32 IntRegs:$src1)))]>, ImmRegRel;
+}
+
+let CextOpcode = "SUB_acc", isCodeGenOnly = 0 in {
+ let isExtentSigned = 1 in
+ def M2_naccii : T_MType_acc_ri <"-= add", 0b101, s8Ext>, ImmRegRel;
+
+ def M2_nacci : T_MType_acc_rr <"-= add", 0b100, 0b001, 0>, ImmRegRel;
+}
+
+let Itinerary = M_tc_3x_SLOT23, isCodeGenOnly = 0 in
+def M2_macsin : T_MType_acc_ri <"-= mpyi", 0b011, u8Ext>;
+
+let isCodeGenOnly = 0 in {
+def M2_xor_xacc : T_MType_acc_rr < "^= xor", 0b100, 0b011, 0>;
+def M2_subacc : T_MType_acc_rr <"+= sub", 0b000, 0b011, 1>;
+}
+
+class T_MType_acc_pat1 <InstHexagon MI, SDNode firstOp, SDNode secOp,
+ PatLeaf ImmPred>
+ : Pat <(secOp IntRegs:$src1, (firstOp IntRegs:$src2, ImmPred:$src3)),
+ (MI IntRegs:$src1, IntRegs:$src2, ImmPred:$src3)>;
+
+class T_MType_acc_pat2 <InstHexagon MI, SDNode firstOp, SDNode secOp>
+ : Pat <(i32 (secOp IntRegs:$src1, (firstOp IntRegs:$src2, IntRegs:$src3))),
+ (MI IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
+
+def : T_MType_acc_pat2 <M2_xor_xacc, xor, xor>;
+def : T_MType_acc_pat1 <M2_macsin, mul, sub, u8ExtPred>;
+
+def : T_MType_acc_pat1 <M2_naccii, add, sub, s8_16ExtPred>;
+def : T_MType_acc_pat2 <M2_nacci, add, sub>;
+//===----------------------------------------------------------------------===//
+// Template Class -- Multiply signed/unsigned halfwords with and without
+// saturation and rounding
+//===----------------------------------------------------------------------===//
+class T_M2_mpyd < bits<2> LHbits, bit isRnd, bit hasShift, bit isUnsigned >
+ : MInst < (outs DoubleRegs:$Rdd), (ins IntRegs:$Rs, IntRegs:$Rt),
+ "$Rdd = "#!if(isUnsigned,"mpyu","mpy")#"($Rs."#!if(LHbits{1},"h","l")
+ #", $Rt."#!if(LHbits{0},"h)","l)")
+ #!if(hasShift,":<<1","")
+ #!if(isRnd,":rnd",""),
+ [] > {
+ bits<5> Rdd;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1110;
+
+ let Inst{27-24} = 0b0100;
+ let Inst{23} = hasShift;
+ let Inst{22} = isUnsigned;
+ let Inst{21} = isRnd;
+ let Inst{6-5} = LHbits;
+ let Inst{4-0} = Rdd;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+}
+
+let isCodeGenOnly = 0 in {
+def M2_mpyd_hh_s0: T_M2_mpyd<0b11, 0, 0, 0>;
+def M2_mpyd_hl_s0: T_M2_mpyd<0b10, 0, 0, 0>;
+def M2_mpyd_lh_s0: T_M2_mpyd<0b01, 0, 0, 0>;
+def M2_mpyd_ll_s0: T_M2_mpyd<0b00, 0, 0, 0>;
+
+def M2_mpyd_hh_s1: T_M2_mpyd<0b11, 0, 1, 0>;
+def M2_mpyd_hl_s1: T_M2_mpyd<0b10, 0, 1, 0>;
+def M2_mpyd_lh_s1: T_M2_mpyd<0b01, 0, 1, 0>;
+def M2_mpyd_ll_s1: T_M2_mpyd<0b00, 0, 1, 0>;
+
+def M2_mpyd_rnd_hh_s0: T_M2_mpyd<0b11, 1, 0, 0>;
+def M2_mpyd_rnd_hl_s0: T_M2_mpyd<0b10, 1, 0, 0>;
+def M2_mpyd_rnd_lh_s0: T_M2_mpyd<0b01, 1, 0, 0>;
+def M2_mpyd_rnd_ll_s0: T_M2_mpyd<0b00, 1, 0, 0>;
+
+def M2_mpyd_rnd_hh_s1: T_M2_mpyd<0b11, 1, 1, 0>;
+def M2_mpyd_rnd_hl_s1: T_M2_mpyd<0b10, 1, 1, 0>;
+def M2_mpyd_rnd_lh_s1: T_M2_mpyd<0b01, 1, 1, 0>;
+def M2_mpyd_rnd_ll_s1: T_M2_mpyd<0b00, 1, 1, 0>;
+
+//Rdd=mpyu(Rs.[HL],Rt.[HL])[:<<1]
+def M2_mpyud_hh_s0: T_M2_mpyd<0b11, 0, 0, 1>;
+def M2_mpyud_hl_s0: T_M2_mpyd<0b10, 0, 0, 1>;
+def M2_mpyud_lh_s0: T_M2_mpyd<0b01, 0, 0, 1>;
+def M2_mpyud_ll_s0: T_M2_mpyd<0b00, 0, 0, 1>;
+
+def M2_mpyud_hh_s1: T_M2_mpyd<0b11, 0, 1, 1>;
+def M2_mpyud_hl_s1: T_M2_mpyd<0b10, 0, 1, 1>;
+def M2_mpyud_lh_s1: T_M2_mpyd<0b01, 0, 1, 1>;
+def M2_mpyud_ll_s1: T_M2_mpyd<0b00, 0, 1, 1>;
+}
+//===----------------------------------------------------------------------===//
+// Template Class for xtype mpy:
+// Vector multiply
+// Complex multiply
+// multiply 32X32 and use full result
+//===----------------------------------------------------------------------===//
+let hasSideEffects = 0 in
+class T_XTYPE_mpy64 <string mnemonic, bits<3> MajOp, bits<3> MinOp,
+ bit isSat, bit hasShift, bit isConj>
+ : MInst <(outs DoubleRegs:$Rdd),
+ (ins IntRegs:$Rs, IntRegs:$Rt),
+ "$Rdd = "#mnemonic#"($Rs, $Rt"#!if(isConj,"*)",")")
+ #!if(hasShift,":<<1","")
+ #!if(isSat,":sat",""),
+ [] > {
+ bits<5> Rdd;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1110;
+
+ let Inst{27-24} = 0b0101;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ let Inst{7-5} = MinOp;
+ let Inst{4-0} = Rdd;
+ }
+
+//===----------------------------------------------------------------------===//
+// Template Class for xtype mpy with accumulation into 64-bit:
+// Vector multiply
+// Complex multiply
+// multiply 32X32 and use full result
+//===----------------------------------------------------------------------===//
+class T_XTYPE_mpy64_acc <string op1, string op2, bits<3> MajOp, bits<3> MinOp,
+ bit isSat, bit hasShift, bit isConj>
+ : MInst <(outs DoubleRegs:$Rxx),
+ (ins DoubleRegs:$dst2, IntRegs:$Rs, IntRegs:$Rt),
+ "$Rxx "#op2#"= "#op1#"($Rs, $Rt"#!if(isConj,"*)",")")
+ #!if(hasShift,":<<1","")
+ #!if(isSat,":sat",""),
+
+ [] , "$dst2 = $Rxx" > {
+ bits<5> Rxx;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1110;
+
+ let Inst{27-24} = 0b0111;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ let Inst{7-5} = MinOp;
+ let Inst{4-0} = Rxx;
+ }
+
+// MPY - Multiply and use full result
+// Rdd = mpy[u](Rs,Rt)
+let isCodeGenOnly = 0 in {
+def M2_dpmpyss_s0 : T_XTYPE_mpy64 < "mpy", 0b000, 0b000, 0, 0, 0>;
+def M2_dpmpyuu_s0 : T_XTYPE_mpy64 < "mpyu", 0b010, 0b000, 0, 0, 0>;
+
+// Rxx[+-]= mpy[u](Rs,Rt)
+def M2_dpmpyss_acc_s0 : T_XTYPE_mpy64_acc < "mpy", "+", 0b000, 0b000, 0, 0, 0>;
+def M2_dpmpyss_nac_s0 : T_XTYPE_mpy64_acc < "mpy", "-", 0b001, 0b000, 0, 0, 0>;
+def M2_dpmpyuu_acc_s0 : T_XTYPE_mpy64_acc < "mpyu", "+", 0b010, 0b000, 0, 0, 0>;
+def M2_dpmpyuu_nac_s0 : T_XTYPE_mpy64_acc < "mpyu", "-", 0b011, 0b000, 0, 0, 0>;
+}
+
+def: Pat<(i64 (mul (i64 (anyext (i32 IntRegs:$src1))),
+ (i64 (anyext (i32 IntRegs:$src2))))),
+ (M2_dpmpyuu_s0 IntRegs:$src1, IntRegs:$src2)>;
+
+def: Pat<(i64 (mul (i64 (sext (i32 IntRegs:$src1))),
+ (i64 (sext (i32 IntRegs:$src2))))),
+ (M2_dpmpyss_s0 IntRegs:$src1, IntRegs:$src2)>;
+
+def: Pat<(i64 (mul (is_sext_i32:$src1),
+ (is_sext_i32:$src2))),
+ (M2_dpmpyss_s0 (LoReg DoubleRegs:$src1), (LoReg DoubleRegs:$src2))>;
// Multiply and accumulate, use full result.
// Rxx[+-]=mpy(Rs,Rt)
-// Rxx+=mpy(Rs,Rt)
-def MPY64_acc : MInst_acc<(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "$dst += mpy($src2, $src3)",
- [(set (i64 DoubleRegs:$dst),
- (add (mul (i64 (sext (i32 IntRegs:$src2))),
- (i64 (sext (i32 IntRegs:$src3)))),
- (i64 DoubleRegs:$src1)))],
- "$src1 = $dst">;
-
-// Rxx-=mpy(Rs,Rt)
-def MPY64_sub : MInst_acc<(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "$dst -= mpy($src2, $src3)",
- [(set (i64 DoubleRegs:$dst),
- (sub (i64 DoubleRegs:$src1),
- (mul (i64 (sext (i32 IntRegs:$src2))),
- (i64 (sext (i32 IntRegs:$src3))))))],
- "$src1 = $dst">;
-
-// Rxx[+-]=mpyu(Rs,Rt)
-// Rxx+=mpyu(Rs,Rt)
-def MPYU64_acc : MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
- IntRegs:$src2, IntRegs:$src3),
- "$dst += mpyu($src2, $src3)",
- [(set (i64 DoubleRegs:$dst),
- (add (mul (i64 (anyext (i32 IntRegs:$src2))),
- (i64 (anyext (i32 IntRegs:$src3)))),
- (i64 DoubleRegs:$src1)))], "$src1 = $dst">;
-
-// Rxx-=mpyu(Rs,Rt)
-def MPYU64_sub : MInst_acc<(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "$dst -= mpyu($src2, $src3)",
- [(set (i64 DoubleRegs:$dst),
- (sub (i64 DoubleRegs:$src1),
- (mul (i64 (anyext (i32 IntRegs:$src2))),
- (i64 (anyext (i32 IntRegs:$src3))))))],
- "$src1 = $dst">;
-
-
-let InputType = "reg", CextOpcode = "ADD_acc" in
-def ADDrr_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
- IntRegs:$src2, IntRegs:$src3),
- "$dst += add($src2, $src3)",
- [(set (i32 IntRegs:$dst), (add (add (i32 IntRegs:$src2),
- (i32 IntRegs:$src3)),
- (i32 IntRegs:$src1)))],
- "$src1 = $dst">, ImmRegRel;
-
-let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8,
-InputType = "imm", CextOpcode = "ADD_acc" in
-def ADDri_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
- IntRegs:$src2, s8Ext:$src3),
- "$dst += add($src2, #$src3)",
- [(set (i32 IntRegs:$dst), (add (add (i32 IntRegs:$src2),
- s8_16ExtPred:$src3),
- (i32 IntRegs:$src1)))],
- "$src1 = $dst">, ImmRegRel;
-
-let CextOpcode = "SUB_acc", InputType = "reg" in
-def SUBrr_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
- IntRegs:$src2, IntRegs:$src3),
- "$dst -= add($src2, $src3)",
- [(set (i32 IntRegs:$dst),
- (sub (i32 IntRegs:$src1), (add (i32 IntRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">, ImmRegRel;
-
-let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8,
-CextOpcode = "SUB_acc", InputType = "imm" in
-def SUBri_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
- IntRegs:$src2, s8Ext:$src3),
- "$dst -= add($src2, #$src3)",
- [(set (i32 IntRegs:$dst), (sub (i32 IntRegs:$src1),
- (add (i32 IntRegs:$src2),
- s8_16ExtPred:$src3)))],
- "$src1 = $dst">, ImmRegRel;
+
+def: Pat<(i64 (add (i64 DoubleRegs:$src1),
+ (mul (i64 (sext (i32 IntRegs:$src2))),
+ (i64 (sext (i32 IntRegs:$src3)))))),
+ (M2_dpmpyss_acc_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
+
+def: Pat<(i64 (sub (i64 DoubleRegs:$src1),
+ (mul (i64 (sext (i32 IntRegs:$src2))),
+ (i64 (sext (i32 IntRegs:$src3)))))),
+ (M2_dpmpyss_nac_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
+
+def: Pat<(i64 (add (i64 DoubleRegs:$src1),
+ (mul (i64 (anyext (i32 IntRegs:$src2))),
+ (i64 (anyext (i32 IntRegs:$src3)))))),
+ (M2_dpmpyuu_acc_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
+
+def: Pat<(i64 (add (i64 DoubleRegs:$src1),
+ (mul (i64 (zext (i32 IntRegs:$src2))),
+ (i64 (zext (i32 IntRegs:$src3)))))),
+ (M2_dpmpyuu_acc_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
+
+def: Pat<(i64 (sub (i64 DoubleRegs:$src1),
+ (mul (i64 (anyext (i32 IntRegs:$src2))),
+ (i64 (anyext (i32 IntRegs:$src3)))))),
+ (M2_dpmpyuu_nac_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
+
+def: Pat<(i64 (sub (i64 DoubleRegs:$src1),
+ (mul (i64 (zext (i32 IntRegs:$src2))),
+ (i64 (zext (i32 IntRegs:$src3)))))),
+ (M2_dpmpyuu_nac_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>;
//===----------------------------------------------------------------------===//
// MTYPE/MPYH -
@@ -1385,245 +2656,459 @@ def SUBri_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1,
//===----------------------------------------------------------------------===//
///
// Store doubleword.
-
//===----------------------------------------------------------------------===//
-// Post increment store
+// Template class for non-predicated post increment stores with immediate offset
//===----------------------------------------------------------------------===//
+let isPredicable = 1, hasSideEffects = 0, addrMode = PostInc in
+class T_store_pi <string mnemonic, RegisterClass RC, Operand ImmOp,
+ bits<4> MajOp, bit isHalf >
+ : STInst <(outs IntRegs:$_dst_),
+ (ins IntRegs:$src1, ImmOp:$offset, RC:$src2),
+ mnemonic#"($src1++#$offset) = $src2"#!if(isHalf, ".h", ""),
+ [], "$src1 = $_dst_" >,
+ AddrModeRel {
+ bits<5> src1;
+ bits<5> src2;
+ bits<7> offset;
+ bits<4> offsetBits;
+
+ string ImmOpStr = !cast<string>(ImmOp);
+ let offsetBits = !if (!eq(ImmOpStr, "s4_3Imm"), offset{6-3},
+ !if (!eq(ImmOpStr, "s4_2Imm"), offset{5-2},
+ !if (!eq(ImmOpStr, "s4_1Imm"), offset{4-1},
+ /* s4_0Imm */ offset{3-0})));
+ let isNVStorable = !if (!eq(ImmOpStr, "s4_3Imm"), 0, 1);
+
+ let IClass = 0b1010;
+
+ let Inst{27-25} = 0b101;
+ let Inst{24-21} = MajOp;
+ let Inst{20-16} = src1;
+ let Inst{13} = 0b0;
+ let Inst{12-8} = src2;
+ let Inst{7} = 0b0;
+ let Inst{6-3} = offsetBits;
+ let Inst{1} = 0b0;
+ }
-multiclass ST_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp,
- bit isNot, bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME : STInst2PI<(outs IntRegs:$dst),
+//===----------------------------------------------------------------------===//
+// Template class for predicated post increment stores with immediate offset
+//===----------------------------------------------------------------------===//
+let isPredicated = 1, hasSideEffects = 0, addrMode = PostInc in
+class T_pstore_pi <string mnemonic, RegisterClass RC, Operand ImmOp,
+ bits<4> MajOp, bit isHalf, bit isPredNot, bit isPredNew >
+ : STInst <(outs IntRegs:$_dst_),
(ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#mnemonic#"($src2++#$offset) = $src3",
- [],
- "$src2 = $dst">;
-}
+ !if(isPredNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#mnemonic#"($src2++#$offset) = $src3"#!if(isHalf, ".h", ""),
+ [], "$src2 = $_dst_" >,
+ AddrModeRel {
+ bits<2> src1;
+ bits<5> src2;
+ bits<7> offset;
+ bits<5> src3;
+ bits<4> offsetBits;
-multiclass ST_PostInc_Pred<string mnemonic, RegisterClass RC,
- Operand ImmOp, bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>;
- // Predicate new
- let Predicates = [HasV4T], validSubTargets = HasV4SubT in
- defm _cdn#NAME#_V4 : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 1>;
+ string ImmOpStr = !cast<string>(ImmOp);
+ let offsetBits = !if (!eq(ImmOpStr, "s4_3Imm"), offset{6-3},
+ !if (!eq(ImmOpStr, "s4_2Imm"), offset{5-2},
+ !if (!eq(ImmOpStr, "s4_1Imm"), offset{4-1},
+ /* s4_0Imm */ offset{3-0})));
+
+ let isNVStorable = !if (!eq(ImmOpStr, "s4_3Imm"), 0, 1);
+ let isPredicatedNew = isPredNew;
+ let isPredicatedFalse = isPredNot;
+
+ let IClass = 0b1010;
+
+ let Inst{27-25} = 0b101;
+ let Inst{24-21} = MajOp;
+ let Inst{20-16} = src2;
+ let Inst{13} = 0b1;
+ let Inst{12-8} = src3;
+ let Inst{7} = isPredNew;
+ let Inst{6-3} = offsetBits;
+ let Inst{2} = isPredNot;
+ let Inst{1-0} = src1;
}
-}
-let hasCtrlDep = 1, isNVStorable = 1, neverHasSideEffects = 1 in
multiclass ST_PostInc<string mnemonic, string BaseOp, RegisterClass RC,
- Operand ImmOp> {
+ Operand ImmOp, bits<4> MajOp, bit isHalf = 0 > {
- let hasCtrlDep = 1, BaseOpcode = "POST_"#BaseOp in {
- let isPredicable = 1 in
- def NAME : STInst2PI<(outs IntRegs:$dst),
- (ins IntRegs:$src1, ImmOp:$offset, RC:$src2),
- mnemonic#"($src1++#$offset) = $src2",
- [],
- "$src1 = $dst">;
-
- let isPredicated = 1 in {
- defm Pt : ST_PostInc_Pred<mnemonic, RC, ImmOp, 0 >;
- defm NotPt : ST_PostInc_Pred<mnemonic, RC, ImmOp, 1 >;
- }
+ let BaseOpcode = "POST_"#BaseOp in {
+ def S2_#NAME#_pi : T_store_pi <mnemonic, RC, ImmOp, MajOp, isHalf>;
+
+ // Predicated
+ def S2_p#NAME#t_pi : T_pstore_pi <mnemonic, RC, ImmOp, MajOp, isHalf, 0, 0>;
+ def S2_p#NAME#f_pi : T_pstore_pi <mnemonic, RC, ImmOp, MajOp, isHalf, 1, 0>;
+
+ // Predicated new
+ def S2_p#NAME#tnew_pi : T_pstore_pi <mnemonic, RC, ImmOp, MajOp,
+ isHalf, 0, 1>;
+ def S2_p#NAME#fnew_pi : T_pstore_pi <mnemonic, RC, ImmOp, MajOp,
+ isHalf, 1, 1>;
}
}
-defm POST_STbri: ST_PostInc <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel;
-defm POST_SThri: ST_PostInc <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel;
-defm POST_STwri: ST_PostInc <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
+let accessSize = ByteAccess, isCodeGenOnly = 0 in
+defm storerb: ST_PostInc <"memb", "STrib", IntRegs, s4_0Imm, 0b1000>;
+
+let accessSize = HalfWordAccess, isCodeGenOnly = 0 in
+defm storerh: ST_PostInc <"memh", "STrih", IntRegs, s4_1Imm, 0b1010>;
+
+let accessSize = WordAccess, isCodeGenOnly = 0 in
+defm storeri: ST_PostInc <"memw", "STriw", IntRegs, s4_2Imm, 0b1100>;
-let isNVStorable = 0 in
-defm POST_STdri: ST_PostInc <"memd", "STrid", DoubleRegs, s4_3Imm>, AddrModeRel;
+let accessSize = DoubleWordAccess, isCodeGenOnly = 0 in
+defm storerd: ST_PostInc <"memd", "STrid", DoubleRegs, s4_3Imm, 0b1110>;
+
+let accessSize = HalfWordAccess, isNVStorable = 0, isCodeGenOnly = 0 in
+defm storerf: ST_PostInc <"memh", "STrih_H", IntRegs, s4_1Imm, 0b1011, 1>;
def : Pat<(post_truncsti8 (i32 IntRegs:$src1), IntRegs:$src2,
s4_3ImmPred:$offset),
- (POST_STbri IntRegs:$src2, s4_0ImmPred:$offset, IntRegs:$src1)>;
+ (S2_storerb_pi IntRegs:$src2, s4_0ImmPred:$offset, IntRegs:$src1)>;
def : Pat<(post_truncsti16 (i32 IntRegs:$src1), IntRegs:$src2,
s4_3ImmPred:$offset),
- (POST_SThri IntRegs:$src2, s4_1ImmPred:$offset, IntRegs:$src1)>;
+ (S2_storerh_pi IntRegs:$src2, s4_1ImmPred:$offset, IntRegs:$src1)>;
def : Pat<(post_store (i32 IntRegs:$src1), IntRegs:$src2, s4_2ImmPred:$offset),
- (POST_STwri IntRegs:$src2, s4_1ImmPred:$offset, IntRegs:$src1)>;
+ (S2_storeri_pi IntRegs:$src2, s4_1ImmPred:$offset, IntRegs:$src1)>;
def : Pat<(post_store (i64 DoubleRegs:$src1), IntRegs:$src2,
s4_3ImmPred:$offset),
- (POST_STdri IntRegs:$src2, s4_3ImmPred:$offset, DoubleRegs:$src1)>;
+ (S2_storerd_pi IntRegs:$src2, s4_3ImmPred:$offset, DoubleRegs:$src1)>;
//===----------------------------------------------------------------------===//
-// multiclass for the store instructions with MEMri operand.
+// Template class for post increment stores with register offset.
//===----------------------------------------------------------------------===//
-multiclass ST_MEMri_Pbase<string mnemonic, RegisterClass RC, bit isNot,
- bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME : STInst2<(outs),
- (ins PredRegs:$src1, MEMri:$addr, RC: $src2),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#mnemonic#"($addr) = $src2",
- []>;
+let isNVStorable = 1 in
+class T_store_pr <string mnemonic, RegisterClass RC, bits<3> MajOp,
+ MemAccessSize AccessSz, bit isHalf = 0>
+ : STInst <(outs IntRegs:$_dst_),
+ (ins IntRegs:$src1, ModRegs:$src2, RC:$src3),
+ mnemonic#"($src1++$src2) = $src3"#!if(isHalf, ".h", ""),
+ [], "$src1 = $_dst_" > {
+ bits<5> src1;
+ bits<1> src2;
+ bits<5> src3;
+ let accessSize = AccessSz;
+
+ let IClass = 0b1010;
+
+ let Inst{27-24} = 0b1101;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = src1;
+ let Inst{13} = src2;
+ let Inst{12-8} = src3;
+ let Inst{7} = 0b0;
+ }
+
+let isCodeGenOnly = 0 in {
+def S2_storerb_pr : T_store_pr<"memb", IntRegs, 0b000, ByteAccess>;
+def S2_storerh_pr : T_store_pr<"memh", IntRegs, 0b010, HalfWordAccess>;
+def S2_storeri_pr : T_store_pr<"memw", IntRegs, 0b100, WordAccess>;
+def S2_storerd_pr : T_store_pr<"memd", DoubleRegs, 0b110, DoubleWordAccess>;
+
+def S2_storerf_pr : T_store_pr<"memh", IntRegs, 0b011, HalfWordAccess, 1>;
}
+let opExtendable = 1, isExtentSigned = 1, isPredicable = 1 in
+class T_store_io <string mnemonic, RegisterClass RC, Operand ImmOp,
+ bits<3>MajOp, bit isH = 0>
+ : STInst <(outs),
+ (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
+ mnemonic#"($src1+#$src2) = $src3"#!if(isH,".h","")>,
+ AddrModeRel, ImmRegRel {
+ bits<5> src1;
+ bits<14> src2; // Actual address offset
+ bits<5> src3;
+ bits<11> offsetBits; // Represents offset encoding
+
+ string ImmOpStr = !cast<string>(ImmOp);
+
+ let opExtentBits = !if (!eq(ImmOpStr, "s11_3Ext"), 14,
+ !if (!eq(ImmOpStr, "s11_2Ext"), 13,
+ !if (!eq(ImmOpStr, "s11_1Ext"), 12,
+ /* s11_0Ext */ 11)));
+ let offsetBits = !if (!eq(ImmOpStr, "s11_3Ext"), src2{13-3},
+ !if (!eq(ImmOpStr, "s11_2Ext"), src2{12-2},
+ !if (!eq(ImmOpStr, "s11_1Ext"), src2{11-1},
+ /* s11_0Ext */ src2{10-0})));
+ let IClass = 0b1010;
+
+ let Inst{27} = 0b0;
+ let Inst{26-25} = offsetBits{10-9};
+ let Inst{24} = 0b1;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = src1;
+ let Inst{13} = offsetBits{8};
+ let Inst{12-8} = src3;
+ let Inst{7-0} = offsetBits{7-0};
+ }
-multiclass ST_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : ST_MEMri_Pbase<mnemonic, RC, PredNot, 0>;
+let opExtendable = 2, isPredicated = 1 in
+class T_pstore_io <string mnemonic, RegisterClass RC, Operand ImmOp,
+ bits<3>MajOp, bit PredNot, bit isPredNew, bit isH = 0>
+ : STInst <(outs),
+ (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$src3, RC:$src4),
+ !if(PredNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#mnemonic#"($src2+#$src3) = $src4"#!if(isH,".h",""),
+ [],"",V2LDST_tc_st_SLOT01 >,
+ AddrModeRel, ImmRegRel {
+ bits<2> src1;
+ bits<5> src2;
+ bits<9> src3; // Actual address offset
+ bits<5> src4;
+ bits<6> offsetBits; // Represents offset encoding
- // Predicate new
- let validSubTargets = HasV4SubT, Predicates = [HasV4T] in
- defm _cdn#NAME#_V4 : ST_MEMri_Pbase<mnemonic, RC, PredNot, 1>;
+ let isPredicatedNew = isPredNew;
+ let isPredicatedFalse = PredNot;
+
+ string ImmOpStr = !cast<string>(ImmOp);
+ let opExtentBits = !if (!eq(ImmOpStr, "u6_3Ext"), 9,
+ !if (!eq(ImmOpStr, "u6_2Ext"), 8,
+ !if (!eq(ImmOpStr, "u6_1Ext"), 7,
+ /* u6_0Ext */ 6)));
+ let offsetBits = !if (!eq(ImmOpStr, "u6_3Ext"), src3{8-3},
+ !if (!eq(ImmOpStr, "u6_2Ext"), src3{7-2},
+ !if (!eq(ImmOpStr, "u6_1Ext"), src3{6-1},
+ /* u6_0Ext */ src3{5-0})));
+ let IClass = 0b0100;
+
+ let Inst{27} = 0b0;
+ let Inst{26} = PredNot;
+ let Inst{25} = isPredNew;
+ let Inst{24} = 0b0;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = src2;
+ let Inst{13} = offsetBits{5};
+ let Inst{12-8} = src4;
+ let Inst{7-3} = offsetBits{4-0};
+ let Inst{1-0} = src1;
}
-}
-let isExtendable = 1, isNVStorable = 1, neverHasSideEffects = 1 in
-multiclass ST_MEMri<string mnemonic, string CextOp, RegisterClass RC,
- bits<5> ImmBits, bits<5> PredImmBits> {
+let isExtendable = 1, isNVStorable = 1, hasSideEffects = 0 in
+multiclass ST_Idxd<string mnemonic, string CextOp, RegisterClass RC,
+ Operand ImmOp, Operand predImmOp, bits<3> MajOp, bit isH = 0> {
+ let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
+ def S2_#NAME#_io : T_store_io <mnemonic, RC, ImmOp, MajOp, isH>;
- let CextOpcode = CextOp, BaseOpcode = CextOp in {
- let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
- isPredicable = 1 in
- def NAME : STInst2<(outs),
- (ins MEMri:$addr, RC:$src),
- mnemonic#"($addr) = $src",
- []>;
+ // Predicated
+ def S2_p#NAME#t_io : T_pstore_io<mnemonic, RC, predImmOp, MajOp, 0, 0, isH>;
+ def S2_p#NAME#f_io : T_pstore_io<mnemonic, RC, predImmOp, MajOp, 1, 0, isH>;
- let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
- isPredicated = 1 in {
- defm Pt : ST_MEMri_Pred<mnemonic, RC, 0>;
- defm NotPt : ST_MEMri_Pred<mnemonic, RC, 1>;
- }
+ // Predicated new
+ def S4_p#NAME#tnew_io : T_pstore_io <mnemonic, RC, predImmOp,
+ MajOp, 0, 1, isH>;
+ def S4_p#NAME#fnew_io : T_pstore_io <mnemonic, RC, predImmOp,
+ MajOp, 1, 1, isH>;
}
}
-let addrMode = BaseImmOffset, isMEMri = "true" in {
+let addrMode = BaseImmOffset, InputType = "imm", isCodeGenOnly = 0 in {
let accessSize = ByteAccess in
- defm STrib: ST_MEMri < "memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
+ defm storerb: ST_Idxd < "memb", "STrib", IntRegs, s11_0Ext, u6_0Ext, 0b000>;
- let accessSize = HalfWordAccess in
- defm STrih: ST_MEMri < "memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
+ let accessSize = HalfWordAccess, opExtentAlign = 1 in
+ defm storerh: ST_Idxd < "memh", "STrih", IntRegs, s11_1Ext, u6_1Ext, 0b010>;
- let accessSize = WordAccess in
- defm STriw: ST_MEMri < "memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
+ let accessSize = WordAccess, opExtentAlign = 2 in
+ defm storeri: ST_Idxd < "memw", "STriw", IntRegs, s11_2Ext, u6_2Ext, 0b100>;
- let accessSize = DoubleWordAccess, isNVStorable = 0 in
- defm STrid: ST_MEMri < "memd", "STrid", DoubleRegs, 14, 9>, AddrModeRel;
+ let accessSize = DoubleWordAccess, isNVStorable = 0, opExtentAlign = 3 in
+ defm storerd: ST_Idxd < "memd", "STrid", DoubleRegs, s11_3Ext,
+ u6_3Ext, 0b110>;
+
+ let accessSize = HalfWordAccess, opExtentAlign = 1 in
+ defm storerf: ST_Idxd < "memh", "STrif", IntRegs, s11_1Ext,
+ u6_1Ext, 0b011, 1>;
}
def : Pat<(truncstorei8 (i32 IntRegs:$src1), ADDRriS11_0:$addr),
- (STrib ADDRriS11_0:$addr, (i32 IntRegs:$src1))>;
+ (S2_storerb_io AddrFI:$addr, 0, (i32 IntRegs:$src1))>;
def : Pat<(truncstorei16 (i32 IntRegs:$src1), ADDRriS11_1:$addr),
- (STrih ADDRriS11_1:$addr, (i32 IntRegs:$src1))>;
+ (S2_storerh_io AddrFI:$addr, 0, (i32 IntRegs:$src1))>;
def : Pat<(store (i32 IntRegs:$src1), ADDRriS11_2:$addr),
- (STriw ADDRriS11_2:$addr, (i32 IntRegs:$src1))>;
+ (S2_storeri_io AddrFI:$addr, 0, (i32 IntRegs:$src1))>;
def : Pat<(store (i64 DoubleRegs:$src1), ADDRriS11_3:$addr),
- (STrid ADDRriS11_3:$addr, (i64 DoubleRegs:$src1))>;
-
-
-//===----------------------------------------------------------------------===//
-// multiclass for the store instructions with base+immediate offset
-// addressing mode
-//===----------------------------------------------------------------------===//
-multiclass ST_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp,
- bit isNot, bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#mnemonic#"($src2+#$src3) = $src4",
- []>;
-}
-
-multiclass ST_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp,
- bit PredNot> {
- let isPredicatedFalse = PredNot, isPredicated = 1 in {
- defm _c#NAME : ST_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 0>;
-
- // Predicate new
- let validSubTargets = HasV4SubT, Predicates = [HasV4T] in
- defm _cdn#NAME#_V4 : ST_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 1>;
- }
-}
+ (S2_storerd_io AddrFI:$addr, 0, (i64 DoubleRegs:$src1))>;
-let isExtendable = 1, isNVStorable = 1, neverHasSideEffects = 1 in
-multiclass ST_Idxd<string mnemonic, string CextOp, RegisterClass RC,
- Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
- bits<5> PredImmBits> {
-
- let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
- let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
- isPredicable = 1 in
- def NAME : STInst2<(outs),
- (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
- mnemonic#"($src1+#$src2) = $src3",
- []>;
-
- let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits in {
- defm Pt : ST_Idxd_Pred<mnemonic, RC, predImmOp, 0>;
- defm NotPt : ST_Idxd_Pred<mnemonic, RC, predImmOp, 1>;
- }
- }
-}
-
-let addrMode = BaseImmOffset, InputType = "reg" in {
- let accessSize = ByteAccess in
- defm STrib_indexed: ST_Idxd < "memb", "STrib", IntRegs, s11_0Ext,
- u6_0Ext, 11, 6>, AddrModeRel, ImmRegRel;
-
- let accessSize = HalfWordAccess in
- defm STrih_indexed: ST_Idxd < "memh", "STrih", IntRegs, s11_1Ext,
- u6_1Ext, 12, 7>, AddrModeRel, ImmRegRel;
-
- let accessSize = WordAccess in
- defm STriw_indexed: ST_Idxd < "memw", "STriw", IntRegs, s11_2Ext,
- u6_2Ext, 13, 8>, AddrModeRel, ImmRegRel;
-
- let accessSize = DoubleWordAccess, isNVStorable = 0 in
- defm STrid_indexed: ST_Idxd < "memd", "STrid", DoubleRegs, s11_3Ext,
- u6_3Ext, 14, 9>, AddrModeRel;
-}
let AddedComplexity = 10 in {
def : Pat<(truncstorei8 (i32 IntRegs:$src1), (add IntRegs:$src2,
s11_0ExtPred:$offset)),
- (STrib_indexed IntRegs:$src2, s11_0ImmPred:$offset,
+ (S2_storerb_io IntRegs:$src2, s11_0ImmPred:$offset,
(i32 IntRegs:$src1))>;
def : Pat<(truncstorei16 (i32 IntRegs:$src1), (add IntRegs:$src2,
s11_1ExtPred:$offset)),
- (STrih_indexed IntRegs:$src2, s11_1ImmPred:$offset,
+ (S2_storerh_io IntRegs:$src2, s11_1ImmPred:$offset,
(i32 IntRegs:$src1))>;
def : Pat<(store (i32 IntRegs:$src1), (add IntRegs:$src2,
s11_2ExtPred:$offset)),
- (STriw_indexed IntRegs:$src2, s11_2ImmPred:$offset,
+ (S2_storeri_io IntRegs:$src2, s11_2ImmPred:$offset,
(i32 IntRegs:$src1))>;
def : Pat<(store (i64 DoubleRegs:$src1), (add IntRegs:$src2,
s11_3ExtPred:$offset)),
- (STrid_indexed IntRegs:$src2, s11_3ImmPred:$offset,
+ (S2_storerd_io IntRegs:$src2, s11_3ImmPred:$offset,
(i64 DoubleRegs:$src1))>;
}
// memh(Rx++#s4:1)=Rt.H
-// Store word.
// Store predicate.
-let Defs = [R10,R11,D5], neverHasSideEffects = 1 in
-def STriw_pred : STInst2<(outs),
- (ins MEMri:$addr, PredRegs:$src1),
- "Error; should not emit",
- []>;
+let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 13,
+ isCodeGenOnly = 1, isPseudo = 1, hasSideEffects = 0 in
+def STriw_pred : STInst<(outs),
+ (ins IntRegs:$addr, s11_2Ext:$off, PredRegs:$src1),
+ ".error \"should not emit\"", []>;
+
+// S2_allocframe: Allocate stack frame.
+let Defs = [R29, R30], Uses = [R29, R31, R30],
+ hasSideEffects = 0, accessSize = DoubleWordAccess, isCodeGenOnly = 0 in
+def S2_allocframe: ST0Inst <
+ (outs), (ins u11_3Imm:$u11_3),
+ "allocframe(#$u11_3)" > {
+ bits<14> u11_3;
+
+ let IClass = 0b1010;
+ let Inst{27-16} = 0b000010011101;
+ let Inst{13-11} = 0b000;
+ let Inst{10-0} = u11_3{13-3};
+ }
-// Allocate stack frame.
-let Defs = [R29, R30], Uses = [R31, R30], neverHasSideEffects = 1 in {
- def ALLOCFRAME : STInst2<(outs),
- (ins i32imm:$amt),
- "allocframe(#$amt)",
- []>;
+// S2_storer[bhwdf]_pci: Store byte/half/word/double.
+// S2_storer[bhwdf]_pci -> S2_storerbnew_pci
+let Uses = [CS], isNVStorable = 1 in
+class T_store_pci <string mnemonic, RegisterClass RC,
+ Operand Imm, bits<4>MajOp,
+ MemAccessSize AlignSize, string RegSrc = "Rt">
+ : STInst <(outs IntRegs:$_dst_),
+ (ins IntRegs:$Rz, Imm:$offset, ModRegs:$Mu, RC:$Rt),
+ #mnemonic#"($Rz ++ #$offset:circ($Mu)) = $"#RegSrc#"",
+ [] ,
+ "$Rz = $_dst_" > {
+ bits<5> Rz;
+ bits<7> offset;
+ bits<1> Mu;
+ bits<5> Rt;
+ let accessSize = AlignSize;
+
+ let IClass = 0b1010;
+ let Inst{27-25} = 0b100;
+ let Inst{24-21} = MajOp;
+ let Inst{20-16} = Rz;
+ let Inst{13} = Mu;
+ let Inst{12-8} = Rt;
+ let Inst{7} = 0b0;
+ let Inst{6-3} =
+ !if (!eq(!cast<string>(AlignSize), "DoubleWordAccess"), offset{6-3},
+ !if (!eq(!cast<string>(AlignSize), "WordAccess"), offset{5-2},
+ !if (!eq(!cast<string>(AlignSize), "HalfWordAccess"), offset{4-1},
+ /* ByteAccess */ offset{3-0})));
+ let Inst{1} = 0b0;
+ }
+
+let isCodeGenOnly = 0 in {
+def S2_storerb_pci : T_store_pci<"memb", IntRegs, s4_0Imm, 0b1000,
+ ByteAccess>;
+def S2_storerh_pci : T_store_pci<"memh", IntRegs, s4_1Imm, 0b1010,
+ HalfWordAccess>;
+def S2_storerf_pci : T_store_pci<"memh", IntRegs, s4_1Imm, 0b1011,
+ HalfWordAccess, "Rt.h">;
+def S2_storeri_pci : T_store_pci<"memw", IntRegs, s4_2Imm, 0b1100,
+ WordAccess>;
+def S2_storerd_pci : T_store_pci<"memd", DoubleRegs, s4_3Imm, 0b1110,
+ DoubleWordAccess>;
}
+
+//===----------------------------------------------------------------------===//
+// Circular stores with auto-increment register
+//===----------------------------------------------------------------------===//
+let Uses = [CS], isNVStorable = 1, isCodeGenOnly = 0 in
+class T_store_pcr <string mnemonic, RegisterClass RC, bits<4>MajOp,
+ MemAccessSize AlignSize, string RegSrc = "Rt">
+ : STInst <(outs IntRegs:$_dst_),
+ (ins IntRegs:$Rz, ModRegs:$Mu, RC:$Rt),
+ #mnemonic#"($Rz ++ I:circ($Mu)) = $"#RegSrc#"",
+ [],
+ "$Rz = $_dst_" > {
+ bits<5> Rz;
+ bits<1> Mu;
+ bits<5> Rt;
+
+ let accessSize = AlignSize;
+
+ let IClass = 0b1010;
+ let Inst{27-25} = 0b100;
+ let Inst{24-21} = MajOp;
+ let Inst{20-16} = Rz;
+ let Inst{13} = Mu;
+ let Inst{12-8} = Rt;
+ let Inst{7} = 0b0;
+ let Inst{1} = 0b1;
+ }
+
+let isCodeGenOnly = 0 in {
+def S2_storerb_pcr : T_store_pcr<"memb", IntRegs, 0b1000, ByteAccess>;
+def S2_storerh_pcr : T_store_pcr<"memh", IntRegs, 0b1010, HalfWordAccess>;
+def S2_storeri_pcr : T_store_pcr<"memw", IntRegs, 0b1100, WordAccess>;
+def S2_storerd_pcr : T_store_pcr<"memd", DoubleRegs, 0b1110, DoubleWordAccess>;
+def S2_storerf_pcr : T_store_pcr<"memh", IntRegs, 0b1011,
+ HalfWordAccess, "Rt.h">;
+}
+
+//===----------------------------------------------------------------------===//
+// Bit-reversed stores with auto-increment register
+//===----------------------------------------------------------------------===//
+let hasSideEffects = 0 in
+class T_store_pbr<string mnemonic, RegisterClass RC,
+ MemAccessSize addrSize, bits<3> majOp,
+ bit isHalf = 0>
+ : STInst
+ <(outs IntRegs:$_dst_),
+ (ins IntRegs:$Rz, ModRegs:$Mu, RC:$src),
+ #mnemonic#"($Rz ++ $Mu:brev) = $src"#!if (!eq(isHalf, 1), ".h", ""),
+ [], "$Rz = $_dst_" > {
+
+ let accessSize = addrSize;
+
+ bits<5> Rz;
+ bits<1> Mu;
+ bits<5> src;
+
+ let IClass = 0b1010;
+
+ let Inst{27-24} = 0b1111;
+ let Inst{23-21} = majOp;
+ let Inst{7} = 0b0;
+ let Inst{20-16} = Rz;
+ let Inst{13} = Mu;
+ let Inst{12-8} = src;
+ }
+
+let isNVStorable = 1, isCodeGenOnly = 0 in {
+ let BaseOpcode = "S2_storerb_pbr" in
+ def S2_storerb_pbr : T_store_pbr<"memb", IntRegs, ByteAccess,
+ 0b000>, NewValueRel;
+ let BaseOpcode = "S2_storerh_pbr" in
+ def S2_storerh_pbr : T_store_pbr<"memh", IntRegs, HalfWordAccess,
+ 0b010>, NewValueRel;
+ let BaseOpcode = "S2_storeri_pbr" in
+ def S2_storeri_pbr : T_store_pbr<"memw", IntRegs, WordAccess,
+ 0b100>, NewValueRel;
+}
+let isCodeGenOnly = 0 in {
+def S2_storerf_pbr : T_store_pbr<"memh", IntRegs, HalfWordAccess, 0b011, 1>;
+def S2_storerd_pbr : T_store_pbr<"memd", DoubleRegs, DoubleWordAccess, 0b110>;
+}
+
//===----------------------------------------------------------------------===//
// ST -
//===----------------------------------------------------------------------===//
@@ -1637,69 +3122,423 @@ def NOT_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1),
[(set (i64 DoubleRegs:$dst), (not (i64 DoubleRegs:$src1)))]>;
-// Sign extend word to doubleword.
-def SXTW : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src1),
- "$dst = sxtw($src1)",
- [(set (i64 DoubleRegs:$dst), (sext (i32 IntRegs:$src1)))]>;
//===----------------------------------------------------------------------===//
// STYPE/ALU -
//===----------------------------------------------------------------------===//
+let hasSideEffects = 0 in
+class T_S2op_1 <string mnemonic, bits<4> RegTyBits, RegisterClass RCOut,
+ RegisterClass RCIn, bits<2> MajOp, bits<3> MinOp, bit isSat>
+ : SInst <(outs RCOut:$dst), (ins RCIn:$src),
+ "$dst = "#mnemonic#"($src)"#!if(isSat, ":sat", ""),
+ [], "", S_2op_tc_1_SLOT23 > {
+ bits<5> dst;
+ bits<5> src;
+
+ let IClass = 0b1000;
+
+ let Inst{27-24} = RegTyBits;
+ let Inst{23-22} = MajOp;
+ let Inst{21} = 0b0;
+ let Inst{20-16} = src;
+ let Inst{7-5} = MinOp;
+ let Inst{4-0} = dst;
+ }
+
+class T_S2op_1_di <string mnemonic, bits<2> MajOp, bits<3> MinOp>
+ : T_S2op_1 <mnemonic, 0b0100, DoubleRegs, IntRegs, MajOp, MinOp, 0>;
+
+let hasNewValue = 1 in
+class T_S2op_1_id <string mnemonic, bits<2> MajOp, bits<3> MinOp, bit isSat = 0>
+ : T_S2op_1 <mnemonic, 0b1000, IntRegs, DoubleRegs, MajOp, MinOp, isSat>;
+
+let hasNewValue = 1 in
+class T_S2op_1_ii <string mnemonic, bits<2> MajOp, bits<3> MinOp, bit isSat = 0>
+ : T_S2op_1 <mnemonic, 0b1100, IntRegs, IntRegs, MajOp, MinOp, isSat>;
+
+// Sign extend word to doubleword
+let isCodeGenOnly = 0 in
+def A2_sxtw : T_S2op_1_di <"sxtw", 0b01, 0b000>;
+
+def: Pat <(i64 (sext I32:$src)), (A2_sxtw I32:$src)>;
+
+// Swizzle the bytes of a word
+let isCodeGenOnly = 0 in
+def A2_swiz : T_S2op_1_ii <"swiz", 0b10, 0b111>;
+
+// Saturate
+let Defs = [USR_OVF], isCodeGenOnly = 0 in {
+ def A2_sat : T_S2op_1_id <"sat", 0b11, 0b000>;
+ def A2_satb : T_S2op_1_ii <"satb", 0b11, 0b111>;
+ def A2_satub : T_S2op_1_ii <"satub", 0b11, 0b110>;
+ def A2_sath : T_S2op_1_ii <"sath", 0b11, 0b100>;
+ def A2_satuh : T_S2op_1_ii <"satuh", 0b11, 0b101>;
+}
+
+let Itinerary = S_2op_tc_2_SLOT23, isCodeGenOnly = 0 in {
+ // Absolute value word
+ def A2_abs : T_S2op_1_ii <"abs", 0b10, 0b100>;
+
+ let Defs = [USR_OVF] in
+ def A2_abssat : T_S2op_1_ii <"abs", 0b10, 0b101, 1>;
+
+ // Negate with saturation
+ let Defs = [USR_OVF] in
+ def A2_negsat : T_S2op_1_ii <"neg", 0b10, 0b110, 1>;
+}
+
+def: Pat<(i32 (select (i1 (setlt (i32 IntRegs:$src), 0)),
+ (i32 (sub 0, (i32 IntRegs:$src))),
+ (i32 IntRegs:$src))),
+ (A2_abs IntRegs:$src)>;
+
+let AddedComplexity = 50 in
+def: Pat<(i32 (xor (add (sra (i32 IntRegs:$src), (i32 31)),
+ (i32 IntRegs:$src)),
+ (sra (i32 IntRegs:$src), (i32 31)))),
+ (A2_abs IntRegs:$src)>;
+
+class T_S2op_2 <string mnemonic, bits<4> RegTyBits, RegisterClass RCOut,
+ RegisterClass RCIn, bits<3> MajOp, bits<3> MinOp,
+ bit isSat, bit isRnd, list<dag> pattern = []>
+ : SInst <(outs RCOut:$dst),
+ (ins RCIn:$src, u5Imm:$u5),
+ "$dst = "#mnemonic#"($src, #$u5)"#!if(isSat, ":sat", "")
+ #!if(isRnd, ":rnd", ""),
+ pattern, "", S_2op_tc_2_SLOT23> {
+ bits<5> dst;
+ bits<5> src;
+ bits<5> u5;
+
+ let IClass = 0b1000;
+
+ let Inst{27-24} = RegTyBits;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = src;
+ let Inst{13} = 0b0;
+ let Inst{12-8} = u5;
+ let Inst{7-5} = MinOp;
+ let Inst{4-0} = dst;
+ }
+
+class T_S2op_2_di <string mnemonic, bits<3> MajOp, bits<3> MinOp>
+ : T_S2op_2 <mnemonic, 0b1000, DoubleRegs, IntRegs, MajOp, MinOp, 0, 0>;
+
+let hasNewValue = 1 in
+class T_S2op_2_id <string mnemonic, bits<3> MajOp, bits<3> MinOp>
+ : T_S2op_2 <mnemonic, 0b1000, IntRegs, DoubleRegs, MajOp, MinOp, 0, 0>;
+
+let hasNewValue = 1 in
+class T_S2op_2_ii <string mnemonic, bits<3> MajOp, bits<3> MinOp,
+ bit isSat = 0, bit isRnd = 0, list<dag> pattern = []>
+ : T_S2op_2 <mnemonic, 0b1100, IntRegs, IntRegs, MajOp, MinOp,
+ isSat, isRnd, pattern>;
+
+class T_S2op_shift <string mnemonic, bits<3> MajOp, bits<3> MinOp, SDNode OpNd>
+ : T_S2op_2_ii <mnemonic, MajOp, MinOp, 0, 0,
+ [(set (i32 IntRegs:$dst), (OpNd (i32 IntRegs:$src),
+ (u5ImmPred:$u5)))]>;
+
+// Arithmetic/logical shift right/left by immediate
+let Itinerary = S_2op_tc_1_SLOT23, isCodeGenOnly = 0 in {
+ def S2_asr_i_r : T_S2op_shift <"asr", 0b000, 0b000, sra>;
+ def S2_lsr_i_r : T_S2op_shift <"lsr", 0b000, 0b001, srl>;
+ def S2_asl_i_r : T_S2op_shift <"asl", 0b000, 0b010, shl>;
+}
+
+// Shift left by immediate with saturation
+let Defs = [USR_OVF], isCodeGenOnly = 0 in
+def S2_asl_i_r_sat : T_S2op_2_ii <"asl", 0b010, 0b010, 1>;
+
+// Shift right with round
+let isCodeGenOnly = 0 in
+def S2_asr_i_r_rnd : T_S2op_2_ii <"asr", 0b010, 0b000, 0, 1>;
+
+def: Pat<(i32 (sra (i32 (add (i32 (sra I32:$src1, u5ImmPred:$src2)),
+ (i32 1))),
+ (i32 1))),
+ (S2_asr_i_r_rnd IntRegs:$src1, u5ImmPred:$src2)>;
+
+class T_S2op_3<string opc, bits<2>MajOp, bits<3>minOp, bits<1> sat = 0>
+ : SInst<(outs DoubleRegs:$Rdd), (ins DoubleRegs:$Rss),
+ "$Rdd = "#opc#"($Rss)"#!if(!eq(sat, 1),":sat","")> {
+ bits<5> Rss;
+ bits<5> Rdd;
+ let IClass = 0b1000;
+ let Inst{27-24} = 0;
+ let Inst{23-22} = MajOp;
+ let Inst{20-16} = Rss;
+ let Inst{7-5} = minOp;
+ let Inst{4-0} = Rdd;
+}
+
+let isCodeGenOnly = 0 in {
+def A2_absp : T_S2op_3 <"abs", 0b10, 0b110>;
+def A2_negp : T_S2op_3 <"neg", 0b10, 0b101>;
+def A2_notp : T_S2op_3 <"not", 0b10, 0b100>;
+}
+
+// Innterleave/deinterleave
+let isCodeGenOnly = 0 in {
+def S2_interleave : T_S2op_3 <"interleave", 0b11, 0b101>;
+def S2_deinterleave : T_S2op_3 <"deinterleave", 0b11, 0b100>;
+}
+
//===----------------------------------------------------------------------===//
// STYPE/BIT +
//===----------------------------------------------------------------------===//
-// clrbit.
-def CLRBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
- "$dst = clrbit($src1, #$src2)",
- [(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1),
- (not
- (shl 1, u5ImmPred:$src2))))]>;
+// Bit count
+
+let hasSideEffects = 0, hasNewValue = 1 in
+class T_COUNT_LEADING<string MnOp, bits<3> MajOp, bits<3> MinOp, bit Is32,
+ dag Out, dag Inp>
+ : SInst<Out, Inp, "$Rd = "#MnOp#"($Rs)", [], "", S_2op_tc_1_SLOT23> {
+ bits<5> Rs;
+ bits<5> Rd;
+ let IClass = 0b1000;
+ let Inst{27} = 0b1;
+ let Inst{26} = Is32;
+ let Inst{25-24} = 0b00;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = Rs;
+ let Inst{7-5} = MinOp;
+ let Inst{4-0} = Rd;
+}
-def CLRBIT_31 : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
- "$dst = clrbit($src1, #$src2)",
- []>;
+class T_COUNT_LEADING_32<string MnOp, bits<3> MajOp, bits<3> MinOp>
+ : T_COUNT_LEADING<MnOp, MajOp, MinOp, 0b1,
+ (outs IntRegs:$Rd), (ins IntRegs:$Rs)>;
+
+class T_COUNT_LEADING_64<string MnOp, bits<3> MajOp, bits<3> MinOp>
+ : T_COUNT_LEADING<MnOp, MajOp, MinOp, 0b0,
+ (outs IntRegs:$Rd), (ins DoubleRegs:$Rs)>;
+
+let isCodeGenOnly = 0 in {
+def S2_cl0 : T_COUNT_LEADING_32<"cl0", 0b000, 0b101>;
+def S2_cl1 : T_COUNT_LEADING_32<"cl1", 0b000, 0b110>;
+def S2_ct0 : T_COUNT_LEADING_32<"ct0", 0b010, 0b100>;
+def S2_ct1 : T_COUNT_LEADING_32<"ct1", 0b010, 0b101>;
+def S2_cl0p : T_COUNT_LEADING_64<"cl0", 0b010, 0b010>;
+def S2_cl1p : T_COUNT_LEADING_64<"cl1", 0b010, 0b100>;
+def S2_clb : T_COUNT_LEADING_32<"clb", 0b000, 0b100>;
+def S2_clbp : T_COUNT_LEADING_64<"clb", 0b010, 0b000>;
+def S2_clbnorm : T_COUNT_LEADING_32<"normamt", 0b000, 0b111>;
+}
-// Map from r0 = and(r1, 2147483647) to r0 = clrbit(r1, #31).
-def : Pat <(and (i32 IntRegs:$src1), 2147483647),
- (CLRBIT_31 (i32 IntRegs:$src1), 31)>;
+def: Pat<(i32 (ctlz I32:$Rs)), (S2_cl0 I32:$Rs)>;
+def: Pat<(i32 (ctlz (not I32:$Rs))), (S2_cl1 I32:$Rs)>;
+def: Pat<(i32 (cttz I32:$Rs)), (S2_ct0 I32:$Rs)>;
+def: Pat<(i32 (cttz (not I32:$Rs))), (S2_ct1 I32:$Rs)>;
+def: Pat<(i32 (trunc (ctlz I64:$Rss))), (S2_cl0p I64:$Rss)>;
+def: Pat<(i32 (trunc (ctlz (not I64:$Rss)))), (S2_cl1p I64:$Rss)>;
+
+// Bit set/clear/toggle
+
+let hasSideEffects = 0, hasNewValue = 1 in
+class T_SCT_BIT_IMM<string MnOp, bits<3> MinOp>
+ : SInst<(outs IntRegs:$Rd), (ins IntRegs:$Rs, u5Imm:$u5),
+ "$Rd = "#MnOp#"($Rs, #$u5)", [], "", S_2op_tc_1_SLOT23> {
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<5> u5;
+ let IClass = 0b1000;
+ let Inst{27-21} = 0b1100110;
+ let Inst{20-16} = Rs;
+ let Inst{13} = 0b0;
+ let Inst{12-8} = u5;
+ let Inst{7-5} = MinOp;
+ let Inst{4-0} = Rd;
+}
-// setbit.
-def SETBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
- "$dst = setbit($src1, #$src2)",
- [(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1),
- (shl 1, u5ImmPred:$src2)))]>;
+let hasSideEffects = 0, hasNewValue = 1 in
+class T_SCT_BIT_REG<string MnOp, bits<2> MinOp>
+ : SInst<(outs IntRegs:$Rd), (ins IntRegs:$Rs, IntRegs:$Rt),
+ "$Rd = "#MnOp#"($Rs, $Rt)", [], "", S_3op_tc_1_SLOT23> {
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<5> Rt;
+ let IClass = 0b1100;
+ let Inst{27-22} = 0b011010;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ let Inst{7-6} = MinOp;
+ let Inst{4-0} = Rd;
+}
-// Map from r0 = or(r1, -2147483648) to r0 = setbit(r1, #31).
-def SETBIT_31 : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
- "$dst = setbit($src1, #$src2)",
- []>;
+let isCodeGenOnly = 0 in {
+def S2_clrbit_i : T_SCT_BIT_IMM<"clrbit", 0b001>;
+def S2_setbit_i : T_SCT_BIT_IMM<"setbit", 0b000>;
+def S2_togglebit_i : T_SCT_BIT_IMM<"togglebit", 0b010>;
+def S2_clrbit_r : T_SCT_BIT_REG<"clrbit", 0b01>;
+def S2_setbit_r : T_SCT_BIT_REG<"setbit", 0b00>;
+def S2_togglebit_r : T_SCT_BIT_REG<"togglebit", 0b10>;
+}
-def : Pat <(or (i32 IntRegs:$src1), -2147483648),
- (SETBIT_31 (i32 IntRegs:$src1), 31)>;
+def: Pat<(i32 (and (i32 IntRegs:$Rs), (not (shl 1, u5ImmPred:$u5)))),
+ (S2_clrbit_i IntRegs:$Rs, u5ImmPred:$u5)>;
+def: Pat<(i32 (or (i32 IntRegs:$Rs), (shl 1, u5ImmPred:$u5))),
+ (S2_setbit_i IntRegs:$Rs, u5ImmPred:$u5)>;
+def: Pat<(i32 (xor (i32 IntRegs:$Rs), (shl 1, u5ImmPred:$u5))),
+ (S2_togglebit_i IntRegs:$Rs, u5ImmPred:$u5)>;
+def: Pat<(i32 (and (i32 IntRegs:$Rs), (not (shl 1, (i32 IntRegs:$Rt))))),
+ (S2_clrbit_r IntRegs:$Rs, IntRegs:$Rt)>;
+def: Pat<(i32 (or (i32 IntRegs:$Rs), (shl 1, (i32 IntRegs:$Rt)))),
+ (S2_setbit_r IntRegs:$Rs, IntRegs:$Rt)>;
+def: Pat<(i32 (xor (i32 IntRegs:$Rs), (shl 1, (i32 IntRegs:$Rt)))),
+ (S2_togglebit_r IntRegs:$Rs, IntRegs:$Rt)>;
+
+// Bit test
+
+let hasSideEffects = 0 in
+class T_TEST_BIT_IMM<string MnOp, bits<3> MajOp>
+ : SInst<(outs PredRegs:$Pd), (ins IntRegs:$Rs, u5Imm:$u5),
+ "$Pd = "#MnOp#"($Rs, #$u5)",
+ [], "", S_2op_tc_2early_SLOT23> {
+ bits<2> Pd;
+ bits<5> Rs;
+ bits<5> u5;
+ let IClass = 0b1000;
+ let Inst{27-24} = 0b0101;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = Rs;
+ let Inst{13} = 0;
+ let Inst{12-8} = u5;
+ let Inst{1-0} = Pd;
+}
-// togglebit.
-def TOGBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
- "$dst = setbit($src1, #$src2)",
- [(set (i32 IntRegs:$dst), (xor (i32 IntRegs:$src1),
- (shl 1, u5ImmPred:$src2)))]>;
+let hasSideEffects = 0 in
+class T_TEST_BIT_REG<string MnOp, bit IsNeg>
+ : SInst<(outs PredRegs:$Pd), (ins IntRegs:$Rs, IntRegs:$Rt),
+ "$Pd = "#MnOp#"($Rs, $Rt)",
+ [], "", S_3op_tc_2early_SLOT23> {
+ bits<2> Pd;
+ bits<5> Rs;
+ bits<5> Rt;
+ let IClass = 0b1100;
+ let Inst{27-22} = 0b011100;
+ let Inst{21} = IsNeg;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ let Inst{1-0} = Pd;
+}
-// Map from r0 = xor(r1, -2147483648) to r0 = togglebit(r1, #31).
-def TOGBIT_31 : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
- "$dst = togglebit($src1, #$src2)",
- []>;
+let isCodeGenOnly = 0 in {
+def S2_tstbit_i : T_TEST_BIT_IMM<"tstbit", 0b000>;
+def S2_tstbit_r : T_TEST_BIT_REG<"tstbit", 0>;
+}
+
+let AddedComplexity = 20 in { // Complexity greater than cmp reg-imm.
+ def: Pat<(i1 (setne (and (shl 1, u5ImmPred:$u5), (i32 IntRegs:$Rs)), 0)),
+ (S2_tstbit_i IntRegs:$Rs, u5ImmPred:$u5)>;
+ def: Pat<(i1 (setne (and (shl 1, (i32 IntRegs:$Rt)), (i32 IntRegs:$Rs)), 0)),
+ (S2_tstbit_r IntRegs:$Rs, IntRegs:$Rt)>;
+ def: Pat<(i1 (trunc (i32 IntRegs:$Rs))),
+ (S2_tstbit_i IntRegs:$Rs, 0)>;
+ def: Pat<(i1 (trunc (i64 DoubleRegs:$Rs))),
+ (S2_tstbit_i (LoReg DoubleRegs:$Rs), 0)>;
+}
+let hasSideEffects = 0 in
+class T_TEST_BITS_IMM<string MnOp, bits<2> MajOp, bit IsNeg>
+ : SInst<(outs PredRegs:$Pd), (ins IntRegs:$Rs, u6Imm:$u6),
+ "$Pd = "#MnOp#"($Rs, #$u6)",
+ [], "", S_2op_tc_2early_SLOT23> {
+ bits<2> Pd;
+ bits<5> Rs;
+ bits<6> u6;
+ let IClass = 0b1000;
+ let Inst{27-24} = 0b0101;
+ let Inst{23-22} = MajOp;
+ let Inst{21} = IsNeg;
+ let Inst{20-16} = Rs;
+ let Inst{13-8} = u6;
+ let Inst{1-0} = Pd;
+}
+
+let hasSideEffects = 0 in
+class T_TEST_BITS_REG<string MnOp, bits<2> MajOp, bit IsNeg>
+ : SInst<(outs PredRegs:$Pd), (ins IntRegs:$Rs, IntRegs:$Rt),
+ "$Pd = "#MnOp#"($Rs, $Rt)",
+ [], "", S_3op_tc_2early_SLOT23> {
+ bits<2> Pd;
+ bits<5> Rs;
+ bits<5> Rt;
+ let IClass = 0b1100;
+ let Inst{27-24} = 0b0111;
+ let Inst{23-22} = MajOp;
+ let Inst{21} = IsNeg;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ let Inst{1-0} = Pd;
+}
-def : Pat <(xor (i32 IntRegs:$src1), -2147483648),
- (TOGBIT_31 (i32 IntRegs:$src1), 31)>;
+let isCodeGenOnly = 0 in {
+def C2_bitsclri : T_TEST_BITS_IMM<"bitsclr", 0b10, 0>;
+def C2_bitsclr : T_TEST_BITS_REG<"bitsclr", 0b10, 0>;
+def C2_bitsset : T_TEST_BITS_REG<"bitsset", 0b01, 0>;
+}
+
+let AddedComplexity = 20 in { // Complexity greater than compare reg-imm.
+ def: Pat<(i1 (seteq (and (i32 IntRegs:$Rs), u6ImmPred:$u6), 0)),
+ (C2_bitsclri IntRegs:$Rs, u6ImmPred:$u6)>;
+ def: Pat<(i1 (seteq (and (i32 IntRegs:$Rs), (i32 IntRegs:$Rt)), 0)),
+ (C2_bitsclr IntRegs:$Rs, IntRegs:$Rt)>;
+}
+
+let AddedComplexity = 10 in // Complexity greater than compare reg-reg.
+def: Pat<(i1 (seteq (and (i32 IntRegs:$Rs), (i32 IntRegs:$Rt)), IntRegs:$Rt)),
+ (C2_bitsset IntRegs:$Rs, IntRegs:$Rt)>;
+
+//===----------------------------------------------------------------------===//
+// STYPE/BIT -
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// STYPE/COMPLEX +
+//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+// STYPE/COMPLEX -
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// XTYPE/PERM +
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// XTYPE/PERM -
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// STYPE/PRED +
+//===----------------------------------------------------------------------===//
// Predicate transfer.
-let neverHasSideEffects = 1 in
-def TFR_RsPd : SInst<(outs IntRegs:$dst), (ins PredRegs:$src1),
- "$dst = $src1 /* Should almost never emit this. */",
- []>;
+let hasSideEffects = 0, hasNewValue = 1, isCodeGenOnly = 0 in
+def C2_tfrpr : SInst<(outs IntRegs:$Rd), (ins PredRegs:$Ps),
+ "$Rd = $Ps", [], "", S_2op_tc_1_SLOT23> {
+ bits<5> Rd;
+ bits<2> Ps;
+
+ let IClass = 0b1000;
+ let Inst{27-24} = 0b1001;
+ let Inst{22} = 0b1;
+ let Inst{17-16} = Ps;
+ let Inst{4-0} = Rd;
+}
+
+// Transfer general register to predicate.
+let hasSideEffects = 0, isCodeGenOnly = 0 in
+def C2_tfrrp: SInst<(outs PredRegs:$Pd), (ins IntRegs:$Rs),
+ "$Pd = $Rs", [], "", S_2op_tc_2early_SLOT23> {
+ bits<2> Pd;
+ bits<5> Rs;
+
+ let IClass = 0b1000;
+ let Inst{27-21} = 0b0101010;
+ let Inst{20-16} = Rs;
+ let Inst{1-0} = Pd;
+}
+
-def TFR_PdRs : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1),
- "$dst = $src1 /* Should almost never emit this. */",
- [(set (i1 PredRegs:$dst), (trunc (i32 IntRegs:$src1)))]>;
//===----------------------------------------------------------------------===//
// STYPE/PRED -
//===----------------------------------------------------------------------===//
@@ -1707,88 +3546,59 @@ def TFR_PdRs : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1),
//===----------------------------------------------------------------------===//
// STYPE/SHIFT +
//===----------------------------------------------------------------------===//
+class S_2OpInstImm<string Mnemonic, bits<3>MajOp, bits<3>MinOp,
+ Operand Imm, list<dag> pattern = [], bit isRnd = 0>
+ : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, Imm:$src2),
+ "$dst = "#Mnemonic#"($src1, #$src2)"#!if(isRnd, ":rnd", ""),
+ pattern> {
+ bits<5> src1;
+ bits<5> dst;
+ let IClass = 0b1000;
+ let Inst{27-24} = 0;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = src1;
+ let Inst{7-5} = MinOp;
+ let Inst{4-0} = dst;
+}
+
+class S_2OpInstImmI6<string Mnemonic, SDNode OpNode, bits<3>MinOp>
+ : S_2OpInstImm<Mnemonic, 0b000, MinOp, u6Imm,
+ [(set (i64 DoubleRegs:$dst), (OpNode (i64 DoubleRegs:$src1),
+ u6ImmPred:$src2))]> {
+ bits<6> src2;
+ let Inst{13-8} = src2;
+}
+
// Shift by immediate.
-def ASR_ri : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
- "$dst = asr($src1, #$src2)",
- [(set (i32 IntRegs:$dst), (sra (i32 IntRegs:$src1),
- u5ImmPred:$src2))]>;
-
-def ASRd_ri : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2),
- "$dst = asr($src1, #$src2)",
- [(set (i64 DoubleRegs:$dst), (sra (i64 DoubleRegs:$src1),
- u6ImmPred:$src2))]>;
-
-def ASL : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
- "$dst = asl($src1, #$src2)",
- [(set (i32 IntRegs:$dst), (shl (i32 IntRegs:$src1),
- u5ImmPred:$src2))]>;
-
-def ASLd_ri : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2),
- "$dst = asl($src1, #$src2)",
- [(set (i64 DoubleRegs:$dst), (shl (i64 DoubleRegs:$src1),
- u6ImmPred:$src2))]>;
-
-def LSR_ri : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
- "$dst = lsr($src1, #$src2)",
- [(set (i32 IntRegs:$dst), (srl (i32 IntRegs:$src1),
- u5ImmPred:$src2))]>;
-
-def LSRd_ri : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2),
- "$dst = lsr($src1, #$src2)",
- [(set (i64 DoubleRegs:$dst), (srl (i64 DoubleRegs:$src1),
- u6ImmPred:$src2))]>;
-
-// Shift by immediate and add.
-let AddedComplexity = 100 in
-def ADDASL : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2,
- u3Imm:$src3),
- "$dst = addasl($src1, $src2, #$src3)",
- [(set (i32 IntRegs:$dst), (add (i32 IntRegs:$src1),
- (shl (i32 IntRegs:$src2),
- u3ImmPred:$src3)))]>;
-
-// Shift by register.
-def ASL_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = asl($src1, $src2)",
- [(set (i32 IntRegs:$dst), (shl (i32 IntRegs:$src1),
- (i32 IntRegs:$src2)))]>;
-
-def ASR_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = asr($src1, $src2)",
- [(set (i32 IntRegs:$dst), (sra (i32 IntRegs:$src1),
- (i32 IntRegs:$src2)))]>;
-
-def LSL_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = lsl($src1, $src2)",
- [(set (i32 IntRegs:$dst), (shl (i32 IntRegs:$src1),
- (i32 IntRegs:$src2)))]>;
-
-def LSR_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
- "$dst = lsr($src1, $src2)",
- [(set (i32 IntRegs:$dst), (srl (i32 IntRegs:$src1),
- (i32 IntRegs:$src2)))]>;
-
-def ASLd : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, IntRegs:$src2),
- "$dst = asl($src1, $src2)",
- [(set (i64 DoubleRegs:$dst), (shl (i64 DoubleRegs:$src1),
- (i32 IntRegs:$src2)))]>;
-
-def LSLd : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, IntRegs:$src2),
- "$dst = lsl($src1, $src2)",
- [(set (i64 DoubleRegs:$dst), (shl (i64 DoubleRegs:$src1),
- (i32 IntRegs:$src2)))]>;
-
-def ASRd_rr : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
- IntRegs:$src2),
- "$dst = asr($src1, $src2)",
- [(set (i64 DoubleRegs:$dst), (sra (i64 DoubleRegs:$src1),
- (i32 IntRegs:$src2)))]>;
-
-def LSRd_rr : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
- IntRegs:$src2),
- "$dst = lsr($src1, $src2)",
- [(set (i64 DoubleRegs:$dst), (srl (i64 DoubleRegs:$src1),
- (i32 IntRegs:$src2)))]>;
+let isCodeGenOnly = 0 in {
+def S2_asr_i_p : S_2OpInstImmI6<"asr", sra, 0b000>;
+def S2_asl_i_p : S_2OpInstImmI6<"asl", shl, 0b010>;
+def S2_lsr_i_p : S_2OpInstImmI6<"lsr", srl, 0b001>;
+}
+
+// Shift left by small amount and add.
+let AddedComplexity = 100, hasNewValue = 1, hasSideEffects = 0,
+ isCodeGenOnly = 0 in
+def S2_addasl_rrri: SInst <(outs IntRegs:$Rd),
+ (ins IntRegs:$Rt, IntRegs:$Rs, u3Imm:$u3),
+ "$Rd = addasl($Rt, $Rs, #$u3)" ,
+ [(set (i32 IntRegs:$Rd), (add (i32 IntRegs:$Rt),
+ (shl (i32 IntRegs:$Rs), u3ImmPred:$u3)))],
+ "", S_3op_tc_2_SLOT23> {
+ bits<5> Rd;
+ bits<5> Rt;
+ bits<5> Rs;
+ bits<3> u3;
+
+ let IClass = 0b1100;
+
+ let Inst{27-21} = 0b0100000;
+ let Inst{20-16} = Rs;
+ let Inst{13} = 0b0;
+ let Inst{12-8} = Rt;
+ let Inst{7-5} = u3;
+ let Inst{4-0} = Rd;
+ }
//===----------------------------------------------------------------------===//
// STYPE/SHIFT -
@@ -1815,38 +3625,191 @@ def LSRd_rr : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
//===----------------------------------------------------------------------===//
// SYSTEM/USER +
//===----------------------------------------------------------------------===//
-def SDHexagonBARRIER: SDTypeProfile<0, 0, []>;
-def HexagonBARRIER: SDNode<"HexagonISD::BARRIER", SDHexagonBARRIER,
- [SDNPHasChain]>;
+def HexagonBARRIER: SDNode<"HexagonISD::BARRIER", SDTNone, [SDNPHasChain]>;
-let hasSideEffects = 1, isSolo = 1 in
+let hasSideEffects = 1, isSoloAX = 1, isCodeGenOnly = 0 in
def BARRIER : SYSInst<(outs), (ins),
"barrier",
- [(HexagonBARRIER)]>;
+ [(HexagonBARRIER)],"",ST_tc_st_SLOT0> {
+ let Inst{31-28} = 0b1010;
+ let Inst{27-21} = 0b1000000;
+}
//===----------------------------------------------------------------------===//
// SYSTEM/SUPER -
//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+// CRUSER - Type.
+//===----------------------------------------------------------------------===//
+// HW loop
+let isExtendable = 1, isExtentSigned = 1, opExtentBits = 9, opExtentAlign = 2,
+ opExtendable = 0, hasSideEffects = 0 in
+class LOOP_iBase<string mnemonic, Operand brOp, bit mustExtend = 0>
+ : CRInst<(outs), (ins brOp:$offset, u10Imm:$src2),
+ #mnemonic#"($offset, #$src2)",
+ [], "" , CR_tc_3x_SLOT3> {
+ bits<9> offset;
+ bits<10> src2;
+
+ let IClass = 0b0110;
+
+ let Inst{27-22} = 0b100100;
+ let Inst{21} = !if (!eq(mnemonic, "loop0"), 0b0, 0b1);
+ let Inst{20-16} = src2{9-5};
+ let Inst{12-8} = offset{8-4};
+ let Inst{7-5} = src2{4-2};
+ let Inst{4-3} = offset{3-2};
+ let Inst{1-0} = src2{1-0};
+}
+
+let isExtendable = 1, isExtentSigned = 1, opExtentBits = 9, opExtentAlign = 2,
+ opExtendable = 0, hasSideEffects = 0 in
+class LOOP_rBase<string mnemonic, Operand brOp, bit mustExtend = 0>
+ : CRInst<(outs), (ins brOp:$offset, IntRegs:$src2),
+ #mnemonic#"($offset, $src2)",
+ [], "" ,CR_tc_3x_SLOT3> {
+ bits<9> offset;
+ bits<5> src2;
+
+ let IClass = 0b0110;
+
+ let Inst{27-22} = 0b000000;
+ let Inst{21} = !if (!eq(mnemonic, "loop0"), 0b0, 0b1);
+ let Inst{20-16} = src2;
+ let Inst{12-8} = offset{8-4};
+ let Inst{4-3} = offset{3-2};
+ }
+
+multiclass LOOP_ri<string mnemonic> {
+ def i : LOOP_iBase<mnemonic, brtarget>;
+ def r : LOOP_rBase<mnemonic, brtarget>;
+}
+
+
+let Defs = [SA0, LC0, USR], isCodeGenOnly = 0 in
+defm J2_loop0 : LOOP_ri<"loop0">;
+
+// Interestingly only loop0's appear to set usr.lpcfg
+let Defs = [SA1, LC1], isCodeGenOnly = 0 in
+defm J2_loop1 : LOOP_ri<"loop1">;
+
+let isBranch = 1, isTerminator = 1, hasSideEffects = 0,
+ Defs = [PC, LC0], Uses = [SA0, LC0] in {
+def ENDLOOP0 : Endloop<(outs), (ins brtarget:$offset),
+ ":endloop0",
+ []>;
+}
+
+let isBranch = 1, isTerminator = 1, hasSideEffects = 0,
+ Defs = [PC, LC1], Uses = [SA1, LC1] in {
+def ENDLOOP1 : Endloop<(outs), (ins brtarget:$offset),
+ ":endloop1",
+ []>;
+}
+
+// Pipelined loop instructions, sp[123]loop0
+let Defs = [LC0, SA0, P3, USR], hasSideEffects = 0,
+ isExtentSigned = 1, isExtendable = 1, opExtentBits = 9, opExtentAlign = 2,
+ opExtendable = 0, isPredicateLate = 1 in
+class SPLOOP_iBase<string SP, bits<2> op>
+ : CRInst <(outs), (ins brtarget:$r7_2, u10Imm:$U10),
+ "p3 = sp"#SP#"loop0($r7_2, #$U10)" > {
+ bits<9> r7_2;
+ bits<10> U10;
+
+ let IClass = 0b0110;
+
+ let Inst{22-21} = op;
+ let Inst{27-23} = 0b10011;
+ let Inst{20-16} = U10{9-5};
+ let Inst{12-8} = r7_2{8-4};
+ let Inst{7-5} = U10{4-2};
+ let Inst{4-3} = r7_2{3-2};
+ let Inst{1-0} = U10{1-0};
+ }
+
+let Defs = [LC0, SA0, P3, USR], hasSideEffects = 0,
+ isExtentSigned = 1, isExtendable = 1, opExtentBits = 9, opExtentAlign = 2,
+ opExtendable = 0, isPredicateLate = 1 in
+class SPLOOP_rBase<string SP, bits<2> op>
+ : CRInst <(outs), (ins brtarget:$r7_2, IntRegs:$Rs),
+ "p3 = sp"#SP#"loop0($r7_2, $Rs)" > {
+ bits<9> r7_2;
+ bits<5> Rs;
+
+ let IClass = 0b0110;
+
+ let Inst{22-21} = op;
+ let Inst{27-23} = 0b00001;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = r7_2{8-4};
+ let Inst{4-3} = r7_2{3-2};
+ }
+
+multiclass SPLOOP_ri<string mnemonic, bits<2> op> {
+ def i : SPLOOP_iBase<mnemonic, op>;
+ def r : SPLOOP_rBase<mnemonic, op>;
+}
+
+let isCodeGenOnly = 0 in {
+defm J2_ploop1s : SPLOOP_ri<"1", 0b01>;
+defm J2_ploop2s : SPLOOP_ri<"2", 0b10>;
+defm J2_ploop3s : SPLOOP_ri<"3", 0b11>;
+}
+
+// Transfer to/from Control/GPR Guest/GPR
+let hasSideEffects = 0 in
+class TFR_CR_RS_base<RegisterClass CTRC, RegisterClass RC, bit isDouble>
+ : CRInst <(outs CTRC:$dst), (ins RC:$src),
+ "$dst = $src", [], "", CR_tc_3x_SLOT3> {
+ bits<5> dst;
+ bits<5> src;
+
+ let IClass = 0b0110;
+
+ let Inst{27-25} = 0b001;
+ let Inst{24} = isDouble;
+ let Inst{23-21} = 0b001;
+ let Inst{20-16} = src;
+ let Inst{4-0} = dst;
+ }
+let isCodeGenOnly = 0 in
+def A2_tfrrcr : TFR_CR_RS_base<CtrRegs, IntRegs, 0b0>;
+def : InstAlias<"m0 = $Rs", (A2_tfrrcr C6, IntRegs:$Rs)>;
+def : InstAlias<"m1 = $Rs", (A2_tfrrcr C7, IntRegs:$Rs)>;
+
+let hasSideEffects = 0 in
+class TFR_RD_CR_base<RegisterClass RC, RegisterClass CTRC, bit isSingle>
+ : CRInst <(outs RC:$dst), (ins CTRC:$src),
+ "$dst = $src", [], "", CR_tc_3x_SLOT3> {
+ bits<5> dst;
+ bits<5> src;
+
+ let IClass = 0b0110;
+
+ let Inst{27-26} = 0b10;
+ let Inst{25} = isSingle;
+ let Inst{24-21} = 0b0000;
+ let Inst{20-16} = src;
+ let Inst{4-0} = dst;
+ }
+
+let hasNewValue = 1, opNewValue = 0, isCodeGenOnly = 0 in
+def A2_tfrcrr : TFR_RD_CR_base<IntRegs, CtrRegs, 1>;
+def : InstAlias<"$Rd = m0", (A2_tfrcrr IntRegs:$Rd, C6)>;
+def : InstAlias<"$Rd = m1", (A2_tfrcrr IntRegs:$Rd, C7)>;
+
+// Y4_trace: Send value to etm trace.
+let isSoloAX = 1, hasSideEffects = 0, isCodeGenOnly = 0 in
+def Y4_trace: CRInst <(outs), (ins IntRegs:$Rs),
+ "trace($Rs)"> {
+ bits<5> Rs;
+
+ let IClass = 0b0110;
+ let Inst{27-21} = 0b0010010;
+ let Inst{20-16} = Rs;
+ }
-// TFRI64 - assembly mapped.
-let isReMaterializable = 1 in
-def TFRI64 : ALU64_rr<(outs DoubleRegs:$dst), (ins s8Imm64:$src1),
- "$dst = #$src1",
- [(set (i64 DoubleRegs:$dst), s8Imm64Pred:$src1)]>;
-
-// Pseudo instruction to encode a set of conditional transfers.
-// This instruction is used instead of a mux and trades-off codesize
-// for performance. We conduct this transformation optimistically in
-// the hope that these instructions get promoted to dot-new transfers.
-let AddedComplexity = 100, isPredicated = 1 in
-def TFR_condset_rr : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1,
- IntRegs:$src2,
- IntRegs:$src3),
- "Error; should not emit",
- [(set (i32 IntRegs:$dst),
- (i32 (select (i1 PredRegs:$src1),
- (i32 IntRegs:$src2),
- (i32 IntRegs:$src3))))]>;
let AddedComplexity = 100, isPredicated = 1 in
def TFR_condset_ri : ALU32_rr<(outs IntRegs:$dst),
(ins PredRegs:$src1, IntRegs:$src2, s12Imm:$src3),
@@ -1877,28 +3840,6 @@ def TFR_FI : ALU32_ri<(outs IntRegs:$dst), (ins FrameIndex:$src1),
"$dst = add($src1)",
[(set (i32 IntRegs:$dst), ADDRri:$src1)]>;
-//
-// CR - Type.
-//
-let neverHasSideEffects = 1, Defs = [SA0, LC0] in {
-def LOOP0_i : CRInst<(outs), (ins brtarget:$offset, u10Imm:$src2),
- "loop0($offset, #$src2)",
- []>;
-}
-
-let neverHasSideEffects = 1, Defs = [SA0, LC0] in {
-def LOOP0_r : CRInst<(outs), (ins brtarget:$offset, IntRegs:$src2),
- "loop0($offset, $src2)",
- []>;
-}
-
-let isBranch = 1, isTerminator = 1, neverHasSideEffects = 1,
- Defs = [PC, LC0], Uses = [SA0, LC0] in {
-def ENDLOOP0 : Endloop<(outs), (ins brtarget:$offset),
- ":endloop0",
- []>;
-}
-
// Support for generating global address.
// Taken from X86InstrInfo.td.
def SDTHexagonCONST32 : SDTypeProfile<1, 1, [
@@ -1909,44 +3850,44 @@ def HexagonCONST32 : SDNode<"HexagonISD::CONST32", SDTHexagonCONST32>;
def HexagonCONST32_GP : SDNode<"HexagonISD::CONST32_GP", SDTHexagonCONST32>;
// HI/LO Instructions
-let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
+let isReMaterializable = 1, isMoveImm = 1, hasSideEffects = 0 in
def LO : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$global),
"$dst.l = #LO($global)",
[]>;
-let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
+let isReMaterializable = 1, isMoveImm = 1, hasSideEffects = 0 in
def HI : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$global),
"$dst.h = #HI($global)",
[]>;
-let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
+let isReMaterializable = 1, isMoveImm = 1, hasSideEffects = 0 in
def LOi : ALU32_ri<(outs IntRegs:$dst), (ins i32imm:$imm_value),
"$dst.l = #LO($imm_value)",
[]>;
-let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
+let isReMaterializable = 1, isMoveImm = 1, hasSideEffects = 0 in
def HIi : ALU32_ri<(outs IntRegs:$dst), (ins i32imm:$imm_value),
"$dst.h = #HI($imm_value)",
[]>;
-let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
+let isReMaterializable = 1, isMoveImm = 1, hasSideEffects = 0 in
def LO_jt : ALU32_ri<(outs IntRegs:$dst), (ins jumptablebase:$jt),
"$dst.l = #LO($jt)",
[]>;
-let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
+let isReMaterializable = 1, isMoveImm = 1, hasSideEffects = 0 in
def HI_jt : ALU32_ri<(outs IntRegs:$dst), (ins jumptablebase:$jt),
"$dst.h = #HI($jt)",
[]>;
-let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in
+let isReMaterializable = 1, isMoveImm = 1, hasSideEffects = 0 in
def LO_label : ALU32_ri<(outs IntRegs:$dst), (ins bblabel:$label),
"$dst.l = #LO($label)",
[]>;
-let isReMaterializable = 1, isMoveImm = 1 , neverHasSideEffects = 1 in
+let isReMaterializable = 1, isMoveImm = 1 , hasSideEffects = 0 in
def HI_label : ALU32_ri<(outs IntRegs:$dst), (ins bblabel:$label),
"$dst.h = #HI($label)",
[]>;
@@ -2044,22 +3985,16 @@ let Defs = [R29, R30, R31], Uses = [R29] in {
[(callseq_end timm:$amt1, timm:$amt2)]>;
}
// Call subroutine.
-let isCall = 1, neverHasSideEffects = 1,
+let isCall = 1, hasSideEffects = 0,
Defs = [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10,
R22, R23, R28, R31, P0, P1, P2, P3, LC0, LC1, SA0, SA1] in {
def CALL : JInst<(outs), (ins calltarget:$dst),
"call $dst", []>;
}
-// Call subroutine from register.
-let isCall = 1, neverHasSideEffects = 1,
- Defs = [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10,
- R22, R23, R28, R31, P0, P1, P2, P3, LC0, LC1, SA0, SA1] in {
- def CALLR : JRInst<(outs), (ins IntRegs:$dst),
- "callr $dst",
- []>;
- }
-
+// Call subroutine indirectly.
+let Defs = VolatileV3.Regs, isCodeGenOnly = 0 in
+def J2_callr : JUMPR_MISC_CALLR<0, 1>;
// Indirect tail-call.
let isCodeGenOnly = 1, isCall = 1, isReturn = 1 in
@@ -2068,13 +4003,15 @@ def TCRETURNR : T_JMPr;
// Direct tail-calls.
let isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0,
isTerminator = 1, isCodeGenOnly = 1 in {
- def TCRETURNtg : T_JMP<(ins calltarget:$dst)>;
- def TCRETURNtext : T_JMP<(ins calltarget:$dst)>;
+ def TCRETURNtg : JInst<(outs), (ins calltarget:$dst), "jump $dst",
+ [], "", J_tc_2early_SLOT23>;
+ def TCRETURNtext : JInst<(outs), (ins calltarget:$dst), "jump $dst",
+ [], "", J_tc_2early_SLOT23>;
}
// Map call instruction.
def : Pat<(call (i32 IntRegs:$dst)),
- (CALLR (i32 IntRegs:$dst))>, Requires<[HasV2TOnly]>;
+ (J2_callr (i32 IntRegs:$dst))>, Requires<[HasV2TOnly]>;
def : Pat<(call tglobaladdr:$dst),
(CALL tglobaladdr:$dst)>, Requires<[HasV2TOnly]>;
def : Pat<(call texternalsym:$dst),
@@ -2090,91 +4027,81 @@ def : Pat<(HexagonTCRet (i32 IntRegs:$dst)),
// Atomic load and store support
// 8 bit atomic load
def : Pat<(atomic_load_8 ADDRriS11_0:$src1),
- (i32 (LDriub ADDRriS11_0:$src1))>;
+ (i32 (L2_loadrub_io AddrFI:$src1, 0))>;
def : Pat<(atomic_load_8 (add (i32 IntRegs:$src1), s11_0ImmPred:$offset)),
- (i32 (LDriub_indexed (i32 IntRegs:$src1), s11_0ImmPred:$offset))>;
+ (i32 (L2_loadrub_io (i32 IntRegs:$src1), s11_0ImmPred:$offset))>;
// 16 bit atomic load
def : Pat<(atomic_load_16 ADDRriS11_1:$src1),
- (i32 (LDriuh ADDRriS11_1:$src1))>;
+ (i32 (L2_loadruh_io AddrFI:$src1, 0))>;
def : Pat<(atomic_load_16 (add (i32 IntRegs:$src1), s11_1ImmPred:$offset)),
- (i32 (LDriuh_indexed (i32 IntRegs:$src1), s11_1ImmPred:$offset))>;
+ (i32 (L2_loadruh_io (i32 IntRegs:$src1), s11_1ImmPred:$offset))>;
def : Pat<(atomic_load_32 ADDRriS11_2:$src1),
- (i32 (LDriw ADDRriS11_2:$src1))>;
+ (i32 (L2_loadri_io AddrFI:$src1, 0))>;
def : Pat<(atomic_load_32 (add (i32 IntRegs:$src1), s11_2ImmPred:$offset)),
- (i32 (LDriw_indexed (i32 IntRegs:$src1), s11_2ImmPred:$offset))>;
+ (i32 (L2_loadri_io (i32 IntRegs:$src1), s11_2ImmPred:$offset))>;
// 64 bit atomic load
def : Pat<(atomic_load_64 ADDRriS11_3:$src1),
- (i64 (LDrid ADDRriS11_3:$src1))>;
+ (i64 (L2_loadrd_io AddrFI:$src1, 0))>;
def : Pat<(atomic_load_64 (add (i32 IntRegs:$src1), s11_3ImmPred:$offset)),
- (i64 (LDrid_indexed (i32 IntRegs:$src1), s11_3ImmPred:$offset))>;
+ (i64 (L2_loadrd_io (i32 IntRegs:$src1), s11_3ImmPred:$offset))>;
def : Pat<(atomic_store_8 ADDRriS11_0:$src2, (i32 IntRegs:$src1)),
- (STrib ADDRriS11_0:$src2, (i32 IntRegs:$src1))>;
+ (S2_storerb_io AddrFI:$src2, 0, (i32 IntRegs:$src1))>;
def : Pat<(atomic_store_8 (add (i32 IntRegs:$src2), s11_0ImmPred:$offset),
(i32 IntRegs:$src1)),
- (STrib_indexed (i32 IntRegs:$src2), s11_0ImmPred:$offset,
+ (S2_storerb_io (i32 IntRegs:$src2), s11_0ImmPred:$offset,
(i32 IntRegs:$src1))>;
def : Pat<(atomic_store_16 ADDRriS11_1:$src2, (i32 IntRegs:$src1)),
- (STrih ADDRriS11_1:$src2, (i32 IntRegs:$src1))>;
+ (S2_storerh_io AddrFI:$src2, 0, (i32 IntRegs:$src1))>;
def : Pat<(atomic_store_16 (i32 IntRegs:$src1),
(add (i32 IntRegs:$src2), s11_1ImmPred:$offset)),
- (STrih_indexed (i32 IntRegs:$src2), s11_1ImmPred:$offset,
+ (S2_storerh_io (i32 IntRegs:$src2), s11_1ImmPred:$offset,
(i32 IntRegs:$src1))>;
def : Pat<(atomic_store_32 ADDRriS11_2:$src2, (i32 IntRegs:$src1)),
- (STriw ADDRriS11_2:$src2, (i32 IntRegs:$src1))>;
+ (S2_storeri_io AddrFI:$src2, 0, (i32 IntRegs:$src1))>;
def : Pat<(atomic_store_32 (add (i32 IntRegs:$src2), s11_2ImmPred:$offset),
(i32 IntRegs:$src1)),
- (STriw_indexed (i32 IntRegs:$src2), s11_2ImmPred:$offset,
+ (S2_storeri_io (i32 IntRegs:$src2), s11_2ImmPred:$offset,
(i32 IntRegs:$src1))>;
def : Pat<(atomic_store_64 ADDRriS11_3:$src2, (i64 DoubleRegs:$src1)),
- (STrid ADDRriS11_3:$src2, (i64 DoubleRegs:$src1))>;
+ (S2_storerd_io AddrFI:$src2, 0, (i64 DoubleRegs:$src1))>;
def : Pat<(atomic_store_64 (add (i32 IntRegs:$src2), s11_3ImmPred:$offset),
(i64 DoubleRegs:$src1)),
- (STrid_indexed (i32 IntRegs:$src2), s11_3ImmPred:$offset,
+ (S2_storerd_io (i32 IntRegs:$src2), s11_3ImmPred:$offset,
(i64 DoubleRegs:$src1))>;
// Map from r0 = and(r1, 65535) to r0 = zxth(r1)
def : Pat <(and (i32 IntRegs:$src1), 65535),
- (ZXTH (i32 IntRegs:$src1))>;
+ (A2_zxth (i32 IntRegs:$src1))>;
// Map from r0 = and(r1, 255) to r0 = zxtb(r1).
def : Pat <(and (i32 IntRegs:$src1), 255),
- (ZXTB (i32 IntRegs:$src1))>;
+ (A2_zxtb (i32 IntRegs:$src1))>;
// Map Add(p1, true) to p1 = not(p1).
// Add(p1, false) should never be produced,
// if it does, it got to be mapped to NOOP.
def : Pat <(add (i1 PredRegs:$src1), -1),
- (NOT_p (i1 PredRegs:$src1))>;
-
-// Map from p0 = setlt(r0, r1) r2 = mux(p0, r3, r4) =>
-// p0 = cmp.lt(r0, r1), r0 = mux(p0, r2, r1).
-// cmp.lt(r0, r1) -> cmp.gt(r1, r0)
-def : Pat <(select (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
- (i32 IntRegs:$src3),
- (i32 IntRegs:$src4)),
- (i32 (TFR_condset_rr (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)),
- (i32 IntRegs:$src4), (i32 IntRegs:$src3)))>,
- Requires<[HasV2TOnly]>;
+ (C2_not (i1 PredRegs:$src1))>;
// Map from p0 = pnot(p0); r0 = mux(p0, #i, #j) => r0 = mux(p0, #j, #i).
def : Pat <(select (not (i1 PredRegs:$src1)), s8ImmPred:$src2, s8ImmPred:$src3),
@@ -2196,91 +4123,91 @@ def : Pat <(select (not (i1 PredRegs:$src1)), IntRegs:$src2, s12ImmPred:$src3),
// Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump.
def : Pat <(brcond (not (i1 PredRegs:$src1)), bb:$offset),
- (JMP_f (i1 PredRegs:$src1), bb:$offset)>;
+ (J2_jumpf (i1 PredRegs:$src1), bb:$offset)>;
// Map from p2 = pnot(p2); p1 = and(p0, p2) => p1 = and(p0, !p2).
def : Pat <(and (i1 PredRegs:$src1), (not (i1 PredRegs:$src2))),
- (i1 (AND_pnotp (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>;
+ (i1 (C2_andn (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>;
let AddedComplexity = 100 in
def : Pat <(i64 (zextloadi1 (HexagonCONST32 tglobaladdr:$global))),
- (i64 (COMBINE_rr (TFRI 0),
- (LDriub_indexed (CONST32_set tglobaladdr:$global), 0)))>,
+ (i64 (A2_combinew (A2_tfrsi 0),
+ (L2_loadrub_io (CONST32_set tglobaladdr:$global), 0)))>,
Requires<[NoV4T]>;
// Map from i1 loads to 32 bits. This assumes that the i1* is byte aligned.
let AddedComplexity = 10 in
def : Pat <(i32 (zextloadi1 ADDRriS11_0:$addr)),
- (i32 (AND_rr (i32 (LDrib ADDRriS11_0:$addr)), (TFRI 0x1)))>;
+ (i32 (A2_and (i32 (L2_loadrb_io AddrFI:$addr, 0)), (A2_tfrsi 0x1)))>;
-// Map from Rdd = sign_extend_inreg(Rss, i32) -> Rdd = SXTW(Rss.lo).
+// Map from Rdd = sign_extend_inreg(Rss, i32) -> Rdd = A2_sxtw(Rss.lo).
def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i32)),
- (i64 (SXTW (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg))))>;
+ (i64 (A2_sxtw (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg))))>;
-// Map from Rdd = sign_extend_inreg(Rss, i16) -> Rdd = SXTW(SXTH(Rss.lo)).
+// Map from Rdd = sign_extend_inreg(Rss, i16) -> Rdd = A2_sxtw(SXTH(Rss.lo)).
def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i16)),
- (i64 (SXTW (i32 (SXTH (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
+ (i64 (A2_sxtw (i32 (A2_sxth (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
subreg_loreg))))))>;
-// Map from Rdd = sign_extend_inreg(Rss, i8) -> Rdd = SXTW(SXTB(Rss.lo)).
+// Map from Rdd = sign_extend_inreg(Rss, i8) -> Rdd = A2_sxtw(SXTB(Rss.lo)).
def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i8)),
- (i64 (SXTW (i32 (SXTB (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
+ (i64 (A2_sxtw (i32 (A2_sxtb (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
subreg_loreg))))))>;
// We want to prevent emitting pnot's as much as possible.
-// Map brcond with an unsupported setcc to a JMP_f.
+// Map brcond with an unsupported setcc to a J2_jumpf.
def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
bb:$offset),
- (JMP_f (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
+ (J2_jumpf (C2_cmpeq (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
bb:$offset)>;
def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), s10ImmPred:$src2)),
bb:$offset),
- (JMP_f (CMPEQri (i32 IntRegs:$src1), s10ImmPred:$src2), bb:$offset)>;
+ (J2_jumpf (C2_cmpeqi (i32 IntRegs:$src1), s10ImmPred:$src2), bb:$offset)>;
def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 -1))), bb:$offset),
- (JMP_f (i1 PredRegs:$src1), bb:$offset)>;
+ (J2_jumpf (i1 PredRegs:$src1), bb:$offset)>;
def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 0))), bb:$offset),
- (JMP_t (i1 PredRegs:$src1), bb:$offset)>;
+ (J2_jumpt (i1 PredRegs:$src1), bb:$offset)>;
// cmp.lt(Rs, Imm) -> !cmp.ge(Rs, Imm) -> !cmp.gt(Rs, Imm-1)
def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)),
bb:$offset),
- (JMP_f (CMPGTri (i32 IntRegs:$src1),
+ (J2_jumpf (C2_cmpgti (i32 IntRegs:$src1),
(DEC_CONST_SIGNED s8ImmPred:$src2)), bb:$offset)>;
// cmp.lt(r0, r1) -> cmp.gt(r1, r0)
def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
bb:$offset),
- (JMP_t (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)), bb:$offset)>;
+ (J2_jumpt (C2_cmpgt (i32 IntRegs:$src2), (i32 IntRegs:$src1)), bb:$offset)>;
def : Pat <(brcond (i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
bb:$offset),
- (JMP_f (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)),
+ (J2_jumpf (C2_cmpgtup (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)),
bb:$offset)>;
def : Pat <(brcond (i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
bb:$offset),
- (JMP_f (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
+ (J2_jumpf (C2_cmpgtu (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
bb:$offset)>;
def : Pat <(brcond (i1 (setule (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
bb:$offset),
- (JMP_f (CMPGTU64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
+ (J2_jumpf (C2_cmpgtup (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
bb:$offset)>;
// Map from a 64-bit select to an emulated 64-bit mux.
// Hexagon does not support 64-bit MUXes; so emulate with combines.
def : Pat <(select (i1 PredRegs:$src1), (i64 DoubleRegs:$src2),
(i64 DoubleRegs:$src3)),
- (i64 (COMBINE_rr (i32 (MUX_rr (i1 PredRegs:$src1),
+ (i64 (A2_combinew (i32 (C2_mux (i1 PredRegs:$src1),
(i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2),
subreg_hireg)),
(i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src3),
subreg_hireg)))),
- (i32 (MUX_rr (i1 PredRegs:$src1),
+ (i32 (C2_mux (i1 PredRegs:$src1),
(i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2),
subreg_loreg)),
(i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src3),
@@ -2290,12 +4217,12 @@ def : Pat <(select (i1 PredRegs:$src1), (i64 DoubleRegs:$src2),
// From LegalizeDAG.cpp: (B1 ? B2 : B3) <=> (B1 & B2)|(!B1&B3).
def : Pat <(select (i1 PredRegs:$src1), (i1 PredRegs:$src2),
(i1 PredRegs:$src3)),
- (OR_pp (AND_pp (i1 PredRegs:$src1), (i1 PredRegs:$src2)),
- (AND_pp (NOT_p (i1 PredRegs:$src1)), (i1 PredRegs:$src3)))>;
+ (C2_or (C2_and (i1 PredRegs:$src1), (i1 PredRegs:$src2)),
+ (C2_and (C2_not (i1 PredRegs:$src1)), (i1 PredRegs:$src3)))>;
// Map Pd = load(addr) -> Rs = load(addr); Pd = Rs.
def : Pat<(i1 (load ADDRriS11_2:$addr)),
- (i1 (TFR_PdRs (i32 (LDrib ADDRriS11_2:$addr))))>;
+ (i1 (C2_tfrrp (i32 (L2_loadrb_io AddrFI:$addr, 0))))>;
// Map for truncating from 64 immediates to 32 bit immediates.
def : Pat<(i32 (trunc (i64 DoubleRegs:$src))),
@@ -2303,263 +4230,263 @@ def : Pat<(i32 (trunc (i64 DoubleRegs:$src))),
// Map for truncating from i64 immediates to i1 bit immediates.
def : Pat<(i1 (trunc (i64 DoubleRegs:$src))),
- (i1 (TFR_PdRs (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
+ (i1 (C2_tfrrp (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
subreg_loreg))))>;
// Map memb(Rs) = Rdd -> memb(Rs) = Rt.
def : Pat<(truncstorei8 (i64 DoubleRegs:$src), ADDRriS11_0:$addr),
- (STrib ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
+ (S2_storerb_io AddrFI:$addr, 0, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
subreg_loreg)))>;
// Map memh(Rs) = Rdd -> memh(Rs) = Rt.
def : Pat<(truncstorei16 (i64 DoubleRegs:$src), ADDRriS11_0:$addr),
- (STrih ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
+ (S2_storerh_io AddrFI:$addr, 0, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
subreg_loreg)))>;
// Map memw(Rs) = Rdd -> memw(Rs) = Rt
def : Pat<(truncstorei32 (i64 DoubleRegs:$src), ADDRriS11_0:$addr),
- (STriw ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
+ (S2_storeri_io AddrFI:$addr, 0, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
subreg_loreg)))>;
// Map memw(Rs) = Rdd -> memw(Rs) = Rt.
def : Pat<(truncstorei32 (i64 DoubleRegs:$src), ADDRriS11_0:$addr),
- (STriw ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
+ (S2_storeri_io AddrFI:$addr, 0, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src),
subreg_loreg)))>;
// Map from i1 = constant<-1>; memw(addr) = i1 -> r0 = 1; memw(addr) = r0.
def : Pat<(store (i1 -1), ADDRriS11_2:$addr),
- (STrib ADDRriS11_2:$addr, (TFRI 1))>;
+ (S2_storerb_io AddrFI:$addr, 0, (A2_tfrsi 1))>;
// Map from i1 = constant<-1>; store i1 -> r0 = 1; store r0.
def : Pat<(store (i1 -1), ADDRriS11_2:$addr),
- (STrib ADDRriS11_2:$addr, (TFRI 1))>;
+ (S2_storerb_io AddrFI:$addr, 0, (A2_tfrsi 1))>;
// Map from memb(Rs) = Pd -> Rt = mux(Pd, #0, #1); store Rt.
def : Pat<(store (i1 PredRegs:$src1), ADDRriS11_2:$addr),
- (STrib ADDRriS11_2:$addr, (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0)) )>;
+ (S2_storerb_io AddrFI:$addr, 0, (i32 (C2_muxii (i1 PredRegs:$src1), 1, 0)) )>;
-// Map Rdd = anyext(Rs) -> Rdd = sxtw(Rs).
+// Map Rdd = anyext(Rs) -> Rdd = A2_sxtw(Rs).
// Hexagon_TODO: We can probably use combine but that will cost 2 instructions.
// Better way to do this?
def : Pat<(i64 (anyext (i32 IntRegs:$src1))),
- (i64 (SXTW (i32 IntRegs:$src1)))>;
+ (i64 (A2_sxtw (i32 IntRegs:$src1)))>;
// Map cmple -> cmpgt.
// rs <= rt -> !(rs > rt).
def : Pat<(i1 (setle (i32 IntRegs:$src1), s10ExtPred:$src2)),
- (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), s10ExtPred:$src2)))>;
+ (i1 (C2_not (C2_cmpgti (i32 IntRegs:$src1), s10ExtPred:$src2)))>;
// rs <= rt -> !(rs > rt).
def : Pat<(i1 (setle (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
- (i1 (NOT_p (CMPGTrr (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>;
+ (i1 (C2_not (C2_cmpgt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>;
// Rss <= Rtt -> !(Rss > Rtt).
def : Pat<(i1 (setle (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
- (i1 (NOT_p (CMPGT64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))))>;
+ (i1 (C2_not (C2_cmpgtp (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))))>;
// Map cmpne -> cmpeq.
// Hexagon_TODO: We should improve on this.
// rs != rt -> !(rs == rt).
def : Pat <(i1 (setne (i32 IntRegs:$src1), s10ExtPred:$src2)),
- (i1 (NOT_p(i1 (CMPEQri (i32 IntRegs:$src1), s10ExtPred:$src2))))>;
+ (i1 (C2_not(i1 (C2_cmpeqi (i32 IntRegs:$src1), s10ExtPred:$src2))))>;
// Map cmpne(Rs) -> !cmpeqe(Rs).
// rs != rt -> !(rs == rt).
def : Pat <(i1 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
- (i1 (NOT_p (i1 (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)))))>;
+ (i1 (C2_not (i1 (C2_cmpeq (i32 IntRegs:$src1), (i32 IntRegs:$src2)))))>;
// Convert setne back to xor for hexagon since we compute w/ pred registers.
def : Pat <(i1 (setne (i1 PredRegs:$src1), (i1 PredRegs:$src2))),
- (i1 (XOR_pp (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>;
+ (i1 (C2_xor (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>;
// Map cmpne(Rss) -> !cmpew(Rss).
// rs != rt -> !(rs == rt).
def : Pat <(i1 (setne (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
- (i1 (NOT_p (i1 (CMPEHexagon4rr (i64 DoubleRegs:$src1),
+ (i1 (C2_not (i1 (C2_cmpeqp (i64 DoubleRegs:$src1),
(i64 DoubleRegs:$src2)))))>;
// Map cmpge(Rs, Rt) -> !(cmpgt(Rs, Rt).
// rs >= rt -> !(rt > rs).
def : Pat <(i1 (setge (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
- (i1 (NOT_p (i1 (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))))>;
+ (i1 (C2_not (i1 (C2_cmpgt (i32 IntRegs:$src2), (i32 IntRegs:$src1)))))>;
// cmpge(Rs, Imm) -> cmpgt(Rs, Imm-1)
def : Pat <(i1 (setge (i32 IntRegs:$src1), s8ExtPred:$src2)),
- (i1 (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2)))>;
+ (i1 (C2_cmpgti (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2)))>;
// Map cmpge(Rss, Rtt) -> !cmpgt(Rtt, Rss).
// rss >= rtt -> !(rtt > rss).
def : Pat <(i1 (setge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
- (i1 (NOT_p (i1 (CMPGT64rr (i64 DoubleRegs:$src2),
+ (i1 (C2_not (i1 (C2_cmpgtp (i64 DoubleRegs:$src2),
(i64 DoubleRegs:$src1)))))>;
// Map cmplt(Rs, Imm) -> !cmpge(Rs, Imm).
// !cmpge(Rs, Imm) -> !cmpgt(Rs, Imm-1).
// rs < rt -> !(rs >= rt).
def : Pat <(i1 (setlt (i32 IntRegs:$src1), s8ExtPred:$src2)),
- (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2))))>;
+ (i1 (C2_not (C2_cmpgti (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2))))>;
// Map cmplt(Rs, Rt) -> cmpgt(Rt, Rs).
// rs < rt -> rt > rs.
// We can let assembler map it, or we can do in the compiler itself.
def : Pat <(i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
- (i1 (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))>;
+ (i1 (C2_cmpgt (i32 IntRegs:$src2), (i32 IntRegs:$src1)))>;
// Map cmplt(Rss, Rtt) -> cmpgt(Rtt, Rss).
// rss < rtt -> (rtt > rss).
def : Pat <(i1 (setlt (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
- (i1 (CMPGT64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>;
+ (i1 (C2_cmpgtp (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>;
// Map from cmpltu(Rs, Rd) -> cmpgtu(Rd, Rs)
// rs < rt -> rt > rs.
// We can let assembler map it, or we can do in the compiler itself.
def : Pat <(i1 (setult (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
- (i1 (CMPGTUrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))>;
+ (i1 (C2_cmpgtu (i32 IntRegs:$src2), (i32 IntRegs:$src1)))>;
// Map from cmpltu(Rss, Rdd) -> cmpgtu(Rdd, Rss).
// rs < rt -> rt > rs.
def : Pat <(i1 (setult (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
- (i1 (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>;
+ (i1 (C2_cmpgtup (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>;
// Generate cmpgeu(Rs, #0) -> cmpeq(Rs, Rs)
def : Pat <(i1 (setuge (i32 IntRegs:$src1), 0)),
- (i1 (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src1)))>;
+ (i1 (C2_cmpeq (i32 IntRegs:$src1), (i32 IntRegs:$src1)))>;
// Generate cmpgeu(Rs, #u8) -> cmpgtu(Rs, #u8 -1)
def : Pat <(i1 (setuge (i32 IntRegs:$src1), u8ExtPred:$src2)),
- (i1 (CMPGTUri (i32 IntRegs:$src1), (DEC_CONST_UNSIGNED u8ExtPred:$src2)))>;
+ (i1 (C2_cmpgtui (i32 IntRegs:$src1), (DEC_CONST_UNSIGNED u8ExtPred:$src2)))>;
// Generate cmpgtu(Rs, #u9)
def : Pat <(i1 (setugt (i32 IntRegs:$src1), u9ExtPred:$src2)),
- (i1 (CMPGTUri (i32 IntRegs:$src1), u9ExtPred:$src2))>;
+ (i1 (C2_cmpgtui (i32 IntRegs:$src1), u9ExtPred:$src2))>;
// Map from Rs >= Rt -> !(Rt > Rs).
// rs >= rt -> !(rt > rs).
def : Pat <(i1 (setuge (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
- (i1 (NOT_p (CMPGTUrr (i32 IntRegs:$src2), (i32 IntRegs:$src1))))>;
+ (i1 (C2_not (C2_cmpgtu (i32 IntRegs:$src2), (i32 IntRegs:$src1))))>;
// Map from Rs >= Rt -> !(Rt > Rs).
// rs >= rt -> !(rt > rs).
def : Pat <(i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
- (i1 (NOT_p (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1))))>;
+ (i1 (C2_not (C2_cmpgtup (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1))))>;
// Map from cmpleu(Rs, Rt) -> !cmpgtu(Rs, Rt).
// Map from (Rs <= Rt) -> !(Rs > Rt).
def : Pat <(i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
- (i1 (NOT_p (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>;
+ (i1 (C2_not (C2_cmpgtu (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>;
// Map from cmpleu(Rss, Rtt) -> !cmpgtu(Rss, Rtt-1).
// Map from (Rs <= Rt) -> !(Rs > Rt).
def : Pat <(i1 (setule (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
- (i1 (NOT_p (CMPGTU64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))))>;
+ (i1 (C2_not (C2_cmpgtup (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))))>;
// Sign extends.
// i1 -> i32
def : Pat <(i32 (sext (i1 PredRegs:$src1))),
- (i32 (MUX_ii (i1 PredRegs:$src1), -1, 0))>;
+ (i32 (C2_muxii (i1 PredRegs:$src1), -1, 0))>;
// i1 -> i64
def : Pat <(i64 (sext (i1 PredRegs:$src1))),
- (i64 (COMBINE_rr (TFRI -1), (MUX_ii (i1 PredRegs:$src1), -1, 0)))>;
+ (i64 (A2_combinew (A2_tfrsi -1), (C2_muxii (i1 PredRegs:$src1), -1, 0)))>;
// Convert sign-extended load back to load and sign extend.
// i8 -> i64
def: Pat <(i64 (sextloadi8 ADDRriS11_0:$src1)),
- (i64 (SXTW (LDrib ADDRriS11_0:$src1)))>;
+ (i64 (A2_sxtw (L2_loadrb_io AddrFI:$src1, 0)))>;
// Convert any-extended load back to load and sign extend.
// i8 -> i64
def: Pat <(i64 (extloadi8 ADDRriS11_0:$src1)),
- (i64 (SXTW (LDrib ADDRriS11_0:$src1)))>;
+ (i64 (A2_sxtw (L2_loadrb_io AddrFI:$src1, 0)))>;
// Convert sign-extended load back to load and sign extend.
// i16 -> i64
def: Pat <(i64 (sextloadi16 ADDRriS11_1:$src1)),
- (i64 (SXTW (LDrih ADDRriS11_1:$src1)))>;
+ (i64 (A2_sxtw (L2_loadrh_io AddrFI:$src1, 0)))>;
// Convert sign-extended load back to load and sign extend.
// i32 -> i64
def: Pat <(i64 (sextloadi32 ADDRriS11_2:$src1)),
- (i64 (SXTW (LDriw ADDRriS11_2:$src1)))>;
+ (i64 (A2_sxtw (L2_loadri_io AddrFI:$src1, 0)))>;
// Zero extends.
// i1 -> i32
def : Pat <(i32 (zext (i1 PredRegs:$src1))),
- (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))>;
+ (i32 (C2_muxii (i1 PredRegs:$src1), 1, 0))>;
// i1 -> i64
def : Pat <(i64 (zext (i1 PredRegs:$src1))),
- (i64 (COMBINE_rr (TFRI 0), (MUX_ii (i1 PredRegs:$src1), 1, 0)))>,
+ (i64 (A2_combinew (A2_tfrsi 0), (C2_muxii (i1 PredRegs:$src1), 1, 0)))>,
Requires<[NoV4T]>;
// i32 -> i64
def : Pat <(i64 (zext (i32 IntRegs:$src1))),
- (i64 (COMBINE_rr (TFRI 0), (i32 IntRegs:$src1)))>,
+ (i64 (A2_combinew (A2_tfrsi 0), (i32 IntRegs:$src1)))>,
Requires<[NoV4T]>;
// i8 -> i64
def: Pat <(i64 (zextloadi8 ADDRriS11_0:$src1)),
- (i64 (COMBINE_rr (TFRI 0), (LDriub ADDRriS11_0:$src1)))>,
+ (i64 (A2_combinew (A2_tfrsi 0), (L2_loadrub_io AddrFI:$src1, 0)))>,
Requires<[NoV4T]>;
let AddedComplexity = 20 in
def: Pat <(i64 (zextloadi8 (add (i32 IntRegs:$src1),
s11_0ExtPred:$offset))),
- (i64 (COMBINE_rr (TFRI 0), (LDriub_indexed IntRegs:$src1,
+ (i64 (A2_combinew (A2_tfrsi 0), (L2_loadrub_io IntRegs:$src1,
s11_0ExtPred:$offset)))>,
Requires<[NoV4T]>;
// i1 -> i64
def: Pat <(i64 (zextloadi1 ADDRriS11_0:$src1)),
- (i64 (COMBINE_rr (TFRI 0), (LDriub ADDRriS11_0:$src1)))>,
+ (i64 (A2_combinew (A2_tfrsi 0), (L2_loadrub_io AddrFI:$src1, 0)))>,
Requires<[NoV4T]>;
let AddedComplexity = 20 in
def: Pat <(i64 (zextloadi1 (add (i32 IntRegs:$src1),
s11_0ExtPred:$offset))),
- (i64 (COMBINE_rr (TFRI 0), (LDriub_indexed IntRegs:$src1,
+ (i64 (A2_combinew (A2_tfrsi 0), (L2_loadrub_io IntRegs:$src1,
s11_0ExtPred:$offset)))>,
Requires<[NoV4T]>;
// i16 -> i64
def: Pat <(i64 (zextloadi16 ADDRriS11_1:$src1)),
- (i64 (COMBINE_rr (TFRI 0), (LDriuh ADDRriS11_1:$src1)))>,
+ (i64 (A2_combinew (A2_tfrsi 0), (L2_loadruh_io AddrFI:$src1, 0)))>,
Requires<[NoV4T]>;
let AddedComplexity = 20 in
def: Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1),
s11_1ExtPred:$offset))),
- (i64 (COMBINE_rr (TFRI 0), (LDriuh_indexed IntRegs:$src1,
+ (i64 (A2_combinew (A2_tfrsi 0), (L2_loadruh_io IntRegs:$src1,
s11_1ExtPred:$offset)))>,
Requires<[NoV4T]>;
// i32 -> i64
def: Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)),
- (i64 (COMBINE_rr (TFRI 0), (LDriw ADDRriS11_2:$src1)))>,
+ (i64 (A2_combinew (A2_tfrsi 0), (L2_loadri_io AddrFI:$src1, 0)))>,
Requires<[NoV4T]>;
let AddedComplexity = 100 in
def: Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
- (i64 (COMBINE_rr (TFRI 0), (LDriw_indexed IntRegs:$src1,
+ (i64 (A2_combinew (A2_tfrsi 0), (L2_loadri_io IntRegs:$src1,
s11_2ExtPred:$offset)))>,
Requires<[NoV4T]>;
let AddedComplexity = 10 in
def: Pat <(i32 (zextloadi1 ADDRriS11_0:$src1)),
- (i32 (LDriw ADDRriS11_0:$src1))>;
+ (i32 (L2_loadri_io AddrFI:$src1, 0))>;
// Map from Rs = Pd to Pd = mux(Pd, #1, #0)
def : Pat <(i32 (zext (i1 PredRegs:$src1))),
- (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))>;
+ (i32 (C2_muxii (i1 PredRegs:$src1), 1, 0))>;
// Map from Rs = Pd to Pd = mux(Pd, #1, #0)
def : Pat <(i32 (anyext (i1 PredRegs:$src1))),
- (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))>;
+ (i32 (C2_muxii (i1 PredRegs:$src1), 1, 0))>;
-// Map from Rss = Pd to Rdd = sxtw (mux(Pd, #1, #0))
+// Map from Rss = Pd to Rdd = A2_sxtw (mux(Pd, #1, #0))
def : Pat <(i64 (anyext (i1 PredRegs:$src1))),
- (i64 (SXTW (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))))>;
+ (i64 (A2_sxtw (i32 (C2_muxii (i1 PredRegs:$src1), 1, 0))))>;
let AddedComplexity = 100 in
@@ -2567,20 +4494,20 @@ def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
(i32 32))),
(i64 (zextloadi32 (i32 (add IntRegs:$src2,
s11_2ExtPred:$offset2)))))),
- (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
- (LDriw_indexed IntRegs:$src2,
+ (i64 (A2_combinew (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ (L2_loadri_io IntRegs:$src2,
s11_2ExtPred:$offset2)))>;
def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
(i32 32))),
(i64 (zextloadi32 ADDRriS11_2:$srcLow)))),
- (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
- (LDriw ADDRriS11_2:$srcLow)))>;
+ (i64 (A2_combinew (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ (L2_loadri_io AddrFI:$srcLow, 0)))>;
def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
(i32 32))),
(i64 (zext (i32 IntRegs:$srcLow))))),
- (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ (i64 (A2_combinew (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
IntRegs:$srcLow))>;
let AddedComplexity = 100 in
@@ -2588,26 +4515,26 @@ def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
(i32 32))),
(i64 (zextloadi32 (i32 (add IntRegs:$src2,
s11_2ExtPred:$offset2)))))),
- (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
- (LDriw_indexed IntRegs:$src2,
+ (i64 (A2_combinew (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ (L2_loadri_io IntRegs:$src2,
s11_2ExtPred:$offset2)))>;
def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
(i32 32))),
(i64 (zextloadi32 ADDRriS11_2:$srcLow)))),
- (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
- (LDriw ADDRriS11_2:$srcLow)))>;
+ (i64 (A2_combinew (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ (L2_loadri_io AddrFI:$srcLow, 0)))>;
def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh),
(i32 32))),
(i64 (zext (i32 IntRegs:$srcLow))))),
- (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
+ (i64 (A2_combinew (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg),
IntRegs:$srcLow))>;
// Any extended 64-bit load.
// anyext i32 -> i64
def: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
- (i64 (COMBINE_rr (TFRI 0), (LDriw ADDRriS11_2:$src1)))>,
+ (i64 (A2_combinew (A2_tfrsi 0), (L2_loadri_io AddrFI:$src1, 0)))>,
Requires<[NoV4T]>;
// When there is an offset we should prefer the pattern below over the pattern above.
@@ -2622,50 +4549,51 @@ def: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
// ********************************************
let AddedComplexity = 100 in
def: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
- (i64 (COMBINE_rr (TFRI 0), (LDriw_indexed IntRegs:$src1,
+ (i64 (A2_combinew (A2_tfrsi 0), (L2_loadri_io IntRegs:$src1,
s11_2ExtPred:$offset)))>,
Requires<[NoV4T]>;
// anyext i16 -> i64.
def: Pat <(i64 (extloadi16 ADDRriS11_2:$src1)),
- (i64 (COMBINE_rr (TFRI 0), (LDrih ADDRriS11_2:$src1)))>,
+ (i64 (A2_combinew (A2_tfrsi 0), (L2_loadrh_io AddrFI:$src1, 0)))>,
Requires<[NoV4T]>;
let AddedComplexity = 20 in
def: Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1),
s11_1ExtPred:$offset))),
- (i64 (COMBINE_rr (TFRI 0), (LDrih_indexed IntRegs:$src1,
+ (i64 (A2_combinew (A2_tfrsi 0), (L2_loadrh_io IntRegs:$src1,
s11_1ExtPred:$offset)))>,
Requires<[NoV4T]>;
// Map from Rdd = zxtw(Rs) -> Rdd = combine(0, Rs).
def : Pat<(i64 (zext (i32 IntRegs:$src1))),
- (i64 (COMBINE_rr (TFRI 0), (i32 IntRegs:$src1)))>,
+ (i64 (A2_combinew (A2_tfrsi 0), (i32 IntRegs:$src1)))>,
Requires<[NoV4T]>;
// Multiply 64-bit unsigned and use upper result.
def : Pat <(mulhu (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
(i64
- (MPYU64_acc
+ (M2_dpmpyuu_acc_s0
(i64
- (COMBINE_rr
- (TFRI 0),
+ (A2_combinew
+ (A2_tfrsi 0),
(i32
(EXTRACT_SUBREG
(i64
- (LSRd_ri
+ (S2_lsr_i_p
(i64
- (MPYU64_acc
+ (M2_dpmpyuu_acc_s0
(i64
- (MPYU64_acc
+ (M2_dpmpyuu_acc_s0
(i64
- (COMBINE_rr (TFRI 0),
+ (A2_combinew (A2_tfrsi 0),
(i32
(EXTRACT_SUBREG
(i64
- (LSRd_ri
+ (S2_lsr_i_p
(i64
- (MPYU64 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
+ (M2_dpmpyuu_s0
+ (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
subreg_loreg)),
(i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2),
subreg_loreg)))), 32)),
@@ -2681,25 +4609,26 @@ def : Pat <(mulhu (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
// Multiply 64-bit signed and use upper result.
def : Pat <(mulhs (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)),
(i64
- (MPY64_acc
+ (M2_dpmpyss_acc_s0
(i64
- (COMBINE_rr (TFRI 0),
+ (A2_combinew (A2_tfrsi 0),
(i32
(EXTRACT_SUBREG
(i64
- (LSRd_ri
+ (S2_lsr_i_p
(i64
- (MPY64_acc
+ (M2_dpmpyss_acc_s0
(i64
- (MPY64_acc
+ (M2_dpmpyss_acc_s0
(i64
- (COMBINE_rr (TFRI 0),
+ (A2_combinew (A2_tfrsi 0),
(i32
(EXTRACT_SUBREG
(i64
- (LSRd_ri
+ (S2_lsr_i_p
(i64
- (MPYU64 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
+ (M2_dpmpyuu_s0
+ (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
subreg_loreg)),
(i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2),
subreg_loreg)))), 32)),
@@ -2744,83 +4673,470 @@ def : Pat<(HexagonWrapperJT tjumptable:$dst),
(i32 (CONST32_set_jt tjumptable:$dst))>;
// XTYPE/SHIFT
-
-// Multi-class for logical operators :
+//
+//===----------------------------------------------------------------------===//
+// Template Class
// Shift by immediate/register and accumulate/logical
-multiclass xtype_imm<string OpcStr, SDNode OpNode1, SDNode OpNode2> {
- def _ri : SInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2, u5Imm:$src3),
- !strconcat("$dst ", !strconcat(OpcStr, "($src2, #$src3)")),
- [(set (i32 IntRegs:$dst),
- (OpNode2 (i32 IntRegs:$src1),
- (OpNode1 (i32 IntRegs:$src2),
- u5ImmPred:$src3)))],
- "$src1 = $dst">;
-
- def d_ri : SInst_acc<(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1, DoubleRegs:$src2, u6Imm:$src3),
- !strconcat("$dst ", !strconcat(OpcStr, "($src2, #$src3)")),
- [(set (i64 DoubleRegs:$dst), (OpNode2 (i64 DoubleRegs:$src1),
- (OpNode1 (i64 DoubleRegs:$src2), u6ImmPred:$src3)))],
- "$src1 = $dst">;
-}
-
-// Multi-class for logical operators :
-// Shift by register and accumulate/logical (32/64 bits)
-multiclass xtype_reg<string OpcStr, SDNode OpNode1, SDNode OpNode2> {
- def _rr : SInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- !strconcat("$dst ", !strconcat(OpcStr, "($src2, $src3)")),
- [(set (i32 IntRegs:$dst),
- (OpNode2 (i32 IntRegs:$src1),
- (OpNode1 (i32 IntRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">;
+//===----------------------------------------------------------------------===//
+
+// Rx[+-&|]=asr(Rs,#u5)
+// Rx[+-&|^]=lsr(Rs,#u5)
+// Rx[+-&|^]=asl(Rs,#u5)
+
+let hasNewValue = 1, opNewValue = 0 in
+class T_shift_imm_acc_r <string opc1, string opc2, SDNode OpNode1,
+ SDNode OpNode2, bits<3> majOp, bits<2> minOp>
+ : SInst_acc<(outs IntRegs:$Rx),
+ (ins IntRegs:$src1, IntRegs:$Rs, u5Imm:$u5),
+ "$Rx "#opc2#opc1#"($Rs, #$u5)",
+ [(set (i32 IntRegs:$Rx),
+ (OpNode2 (i32 IntRegs:$src1),
+ (OpNode1 (i32 IntRegs:$Rs), u5ImmPred:$u5)))],
+ "$src1 = $Rx", S_2op_tc_2_SLOT23> {
+ bits<5> Rx;
+ bits<5> Rs;
+ bits<5> u5;
+
+ let IClass = 0b1000;
+
+ let Inst{27-24} = 0b1110;
+ let Inst{23-22} = majOp{2-1};
+ let Inst{13} = 0b0;
+ let Inst{7} = majOp{0};
+ let Inst{6-5} = minOp;
+ let Inst{4-0} = Rx;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = u5;
+ }
+
+// Rx[+-&|]=asr(Rs,Rt)
+// Rx[+-&|^]=lsr(Rs,Rt)
+// Rx[+-&|^]=asl(Rs,Rt)
+
+let hasNewValue = 1, opNewValue = 0 in
+class T_shift_reg_acc_r <string opc1, string opc2, SDNode OpNode1,
+ SDNode OpNode2, bits<2> majOp, bits<2> minOp>
+ : SInst_acc<(outs IntRegs:$Rx),
+ (ins IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt),
+ "$Rx "#opc2#opc1#"($Rs, $Rt)",
+ [(set (i32 IntRegs:$Rx),
+ (OpNode2 (i32 IntRegs:$src1),
+ (OpNode1 (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))],
+ "$src1 = $Rx", S_3op_tc_2_SLOT23 > {
+ bits<5> Rx;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1100;
+
+ let Inst{27-24} = 0b1100;
+ let Inst{23-22} = majOp;
+ let Inst{7-6} = minOp;
+ let Inst{4-0} = Rx;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ }
- def d_rr : SInst_acc<(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
- !strconcat("$dst ", !strconcat(OpcStr, "($src2, $src3)")),
- [(set (i64 DoubleRegs:$dst),
- (OpNode2 (i64 DoubleRegs:$src1),
- (OpNode1 (i64 DoubleRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">;
+// Rxx[+-&|]=asr(Rss,#u6)
+// Rxx[+-&|^]=lsr(Rss,#u6)
+// Rxx[+-&|^]=asl(Rss,#u6)
+
+class T_shift_imm_acc_p <string opc1, string opc2, SDNode OpNode1,
+ SDNode OpNode2, bits<3> majOp, bits<2> minOp>
+ : SInst_acc<(outs DoubleRegs:$Rxx),
+ (ins DoubleRegs:$src1, DoubleRegs:$Rss, u6Imm:$u6),
+ "$Rxx "#opc2#opc1#"($Rss, #$u6)",
+ [(set (i64 DoubleRegs:$Rxx),
+ (OpNode2 (i64 DoubleRegs:$src1),
+ (OpNode1 (i64 DoubleRegs:$Rss), u6ImmPred:$u6)))],
+ "$src1 = $Rxx", S_2op_tc_2_SLOT23> {
+ bits<5> Rxx;
+ bits<5> Rss;
+ bits<6> u6;
+
+ let IClass = 0b1000;
+
+ let Inst{27-24} = 0b0010;
+ let Inst{23-22} = majOp{2-1};
+ let Inst{7} = majOp{0};
+ let Inst{6-5} = minOp;
+ let Inst{4-0} = Rxx;
+ let Inst{20-16} = Rss;
+ let Inst{13-8} = u6;
+ }
+
+
+// Rxx[+-&|]=asr(Rss,Rt)
+// Rxx[+-&|^]=lsr(Rss,Rt)
+// Rxx[+-&|^]=asl(Rss,Rt)
+// Rxx[+-&|^]=lsl(Rss,Rt)
+
+class T_shift_reg_acc_p <string opc1, string opc2, SDNode OpNode1,
+ SDNode OpNode2, bits<3> majOp, bits<2> minOp>
+ : SInst_acc<(outs DoubleRegs:$Rxx),
+ (ins DoubleRegs:$src1, DoubleRegs:$Rss, IntRegs:$Rt),
+ "$Rxx "#opc2#opc1#"($Rss, $Rt)",
+ [(set (i64 DoubleRegs:$Rxx),
+ (OpNode2 (i64 DoubleRegs:$src1),
+ (OpNode1 (i64 DoubleRegs:$Rss), (i32 IntRegs:$Rt))))],
+ "$src1 = $Rxx", S_3op_tc_2_SLOT23> {
+ bits<5> Rxx;
+ bits<5> Rss;
+ bits<5> Rt;
+
+ let IClass = 0b1100;
+
+ let Inst{27-24} = 0b1011;
+ let Inst{23-21} = majOp;
+ let Inst{20-16} = Rss;
+ let Inst{12-8} = Rt;
+ let Inst{7-6} = minOp;
+ let Inst{4-0} = Rxx;
+ }
+
+//===----------------------------------------------------------------------===//
+// Multi-class for the shift instructions with logical/arithmetic operators.
+//===----------------------------------------------------------------------===//
+multiclass xtype_imm_base<string OpcStr1, string OpcStr2, SDNode OpNode1,
+ SDNode OpNode2, bits<3> majOp, bits<2> minOp > {
+ def _i_r#NAME : T_shift_imm_acc_r< OpcStr1, OpcStr2, OpNode1,
+ OpNode2, majOp, minOp >;
+ def _i_p#NAME : T_shift_imm_acc_p< OpcStr1, OpcStr2, OpNode1,
+ OpNode2, majOp, minOp >;
}
-multiclass basic_xtype_imm<string OpcStr, SDNode OpNode> {
-let AddedComplexity = 100 in
- defm _ADD : xtype_imm< !strconcat("+= ", OpcStr), OpNode, add>;
- defm _SUB : xtype_imm< !strconcat("-= ", OpcStr), OpNode, sub>;
- defm _AND : xtype_imm< !strconcat("&= ", OpcStr), OpNode, and>;
- defm _OR : xtype_imm< !strconcat("|= ", OpcStr), OpNode, or>;
+multiclass xtype_imm_acc<string opc1, SDNode OpNode, bits<2>minOp> {
+ let AddedComplexity = 100 in
+ defm _acc : xtype_imm_base< opc1, "+= ", OpNode, add, 0b001, minOp>;
+
+ defm _nac : xtype_imm_base< opc1, "-= ", OpNode, sub, 0b000, minOp>;
+ defm _and : xtype_imm_base< opc1, "&= ", OpNode, and, 0b010, minOp>;
+ defm _or : xtype_imm_base< opc1, "|= ", OpNode, or, 0b011, minOp>;
}
-multiclass basic_xtype_reg<string OpcStr, SDNode OpNode> {
+multiclass xtype_xor_imm_acc<string opc1, SDNode OpNode, bits<2>minOp> {
let AddedComplexity = 100 in
- defm _ADD : xtype_reg< !strconcat("+= ", OpcStr), OpNode, add>;
- defm _SUB : xtype_reg< !strconcat("-= ", OpcStr), OpNode, sub>;
- defm _AND : xtype_reg< !strconcat("&= ", OpcStr), OpNode, and>;
- defm _OR : xtype_reg< !strconcat("|= ", OpcStr), OpNode, or>;
+ defm _xacc : xtype_imm_base< opc1, "^= ", OpNode, xor, 0b100, minOp>;
}
-multiclass xtype_xor_imm<string OpcStr, SDNode OpNode> {
-let AddedComplexity = 100 in
- defm _XOR : xtype_imm< !strconcat("^= ", OpcStr), OpNode, xor>;
+let isCodeGenOnly = 0 in {
+defm S2_asr : xtype_imm_acc<"asr", sra, 0b00>;
+
+defm S2_lsr : xtype_imm_acc<"lsr", srl, 0b01>,
+ xtype_xor_imm_acc<"lsr", srl, 0b01>;
+
+defm S2_asl : xtype_imm_acc<"asl", shl, 0b10>,
+ xtype_xor_imm_acc<"asl", shl, 0b10>;
}
-defm ASL : basic_xtype_imm<"asl", shl>, basic_xtype_reg<"asl", shl>,
- xtype_xor_imm<"asl", shl>;
+multiclass xtype_reg_acc_r<string opc1, SDNode OpNode, bits<2>minOp> {
+ let AddedComplexity = 100 in
+ def _acc : T_shift_reg_acc_r <opc1, "+= ", OpNode, add, 0b11, minOp>;
-defm LSR : basic_xtype_imm<"lsr", srl>, basic_xtype_reg<"lsr", srl>,
- xtype_xor_imm<"lsr", srl>;
+ def _nac : T_shift_reg_acc_r <opc1, "-= ", OpNode, sub, 0b10, minOp>;
+ def _and : T_shift_reg_acc_r <opc1, "&= ", OpNode, and, 0b01, minOp>;
+ def _or : T_shift_reg_acc_r <opc1, "|= ", OpNode, or, 0b00, minOp>;
+}
-defm ASR : basic_xtype_imm<"asr", sra>, basic_xtype_reg<"asr", sra>;
-defm LSL : basic_xtype_reg<"lsl", shl>;
+multiclass xtype_reg_acc_p<string opc1, SDNode OpNode, bits<2>minOp> {
+ let AddedComplexity = 100 in
+ def _acc : T_shift_reg_acc_p <opc1, "+= ", OpNode, add, 0b110, minOp>;
+
+ def _nac : T_shift_reg_acc_p <opc1, "-= ", OpNode, sub, 0b100, minOp>;
+ def _and : T_shift_reg_acc_p <opc1, "&= ", OpNode, and, 0b010, minOp>;
+ def _or : T_shift_reg_acc_p <opc1, "|= ", OpNode, or, 0b000, minOp>;
+ def _xor : T_shift_reg_acc_p <opc1, "^= ", OpNode, xor, 0b011, minOp>;
+}
+
+multiclass xtype_reg_acc<string OpcStr, SDNode OpNode, bits<2> minOp > {
+ defm _r_r : xtype_reg_acc_r <OpcStr, OpNode, minOp>;
+ defm _r_p : xtype_reg_acc_p <OpcStr, OpNode, minOp>;
+}
+
+let isCodeGenOnly = 0 in {
+defm S2_asl : xtype_reg_acc<"asl", shl, 0b10>;
+defm S2_asr : xtype_reg_acc<"asr", sra, 0b00>;
+defm S2_lsr : xtype_reg_acc<"lsr", srl, 0b01>;
+defm S2_lsl : xtype_reg_acc<"lsl", shl, 0b11>;
+}
+
+//===----------------------------------------------------------------------===//
+let hasSideEffects = 0 in
+class T_S3op_1 <string mnemonic, RegisterClass RC, bits<2> MajOp, bits<3> MinOp,
+ bit SwapOps, bit isSat = 0, bit isRnd = 0, bit hasShift = 0>
+ : SInst <(outs RC:$dst),
+ (ins DoubleRegs:$src1, DoubleRegs:$src2),
+ "$dst = "#mnemonic#"($src1, $src2)"#!if(isRnd, ":rnd", "")
+ #!if(hasShift,":>>1","")
+ #!if(isSat, ":sat", ""),
+ [], "", S_3op_tc_2_SLOT23 > {
+ bits<5> dst;
+ bits<5> src1;
+ bits<5> src2;
+
+ let IClass = 0b1100;
+
+ let Inst{27-24} = 0b0001;
+ let Inst{23-22} = MajOp;
+ let Inst{20-16} = !if (SwapOps, src2, src1);
+ let Inst{12-8} = !if (SwapOps, src1, src2);
+ let Inst{7-5} = MinOp;
+ let Inst{4-0} = dst;
+ }
+
+class T_S3op_64 <string mnemonic, bits<2> MajOp, bits<3> MinOp, bit SwapOps,
+ bit isSat = 0, bit isRnd = 0, bit hasShift = 0 >
+ : T_S3op_1 <mnemonic, DoubleRegs, MajOp, MinOp, SwapOps,
+ isSat, isRnd, hasShift>;
+
+let isCodeGenOnly = 0 in
+def S2_lfsp : T_S3op_64 < "lfs", 0b10, 0b110, 0>;
+
+//===----------------------------------------------------------------------===//
+// Template class used by vector shift, vector rotate, vector neg,
+// 32-bit shift, 64-bit shifts, etc.
+//===----------------------------------------------------------------------===//
+
+let hasSideEffects = 0 in
+class T_S3op_3 <string mnemonic, RegisterClass RC, bits<2> MajOp,
+ bits<2> MinOp, bit isSat = 0, list<dag> pattern = [] >
+ : SInst <(outs RC:$dst),
+ (ins RC:$src1, IntRegs:$src2),
+ "$dst = "#mnemonic#"($src1, $src2)"#!if(isSat, ":sat", ""),
+ pattern, "", S_3op_tc_1_SLOT23> {
+ bits<5> dst;
+ bits<5> src1;
+ bits<5> src2;
+
+ let IClass = 0b1100;
+
+ let Inst{27-24} = !if(!eq(!cast<string>(RC), "IntRegs"), 0b0110, 0b0011);
+ let Inst{23-22} = MajOp;
+ let Inst{20-16} = src1;
+ let Inst{12-8} = src2;
+ let Inst{7-6} = MinOp;
+ let Inst{4-0} = dst;
+ }
+
+let hasNewValue = 1 in
+class T_S3op_shift32 <string mnemonic, SDNode OpNode, bits<2> MinOp>
+ : T_S3op_3 <mnemonic, IntRegs, 0b01, MinOp, 0,
+ [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$src1),
+ (i32 IntRegs:$src2)))]>;
+
+let hasNewValue = 1, Itinerary = S_3op_tc_2_SLOT23 in
+class T_S3op_shift32_Sat <string mnemonic, bits<2> MinOp>
+ : T_S3op_3 <mnemonic, IntRegs, 0b00, MinOp, 1, []>;
+
+
+class T_S3op_shift64 <string mnemonic, SDNode OpNode, bits<2> MinOp>
+ : T_S3op_3 <mnemonic, DoubleRegs, 0b10, MinOp, 0,
+ [(set (i64 DoubleRegs:$dst), (OpNode (i64 DoubleRegs:$src1),
+ (i32 IntRegs:$src2)))]>;
+
+
+class T_S3op_shiftVect <string mnemonic, bits<2> MajOp, bits<2> MinOp>
+ : T_S3op_3 <mnemonic, DoubleRegs, MajOp, MinOp, 0, []>;
+
+
+// Shift by register
+// Rdd=[asr|lsr|asl|lsl](Rss,Rt)
+
+let isCodeGenOnly = 0 in {
+def S2_asr_r_p : T_S3op_shift64 < "asr", sra, 0b00>;
+def S2_lsr_r_p : T_S3op_shift64 < "lsr", srl, 0b01>;
+def S2_asl_r_p : T_S3op_shift64 < "asl", shl, 0b10>;
+def S2_lsl_r_p : T_S3op_shift64 < "lsl", shl, 0b11>;
+}
+
+// Rd=[asr|lsr|asl|lsl](Rs,Rt)
+
+let isCodeGenOnly = 0 in {
+def S2_asr_r_r : T_S3op_shift32<"asr", sra, 0b00>;
+def S2_lsr_r_r : T_S3op_shift32<"lsr", srl, 0b01>;
+def S2_asl_r_r : T_S3op_shift32<"asl", shl, 0b10>;
+def S2_lsl_r_r : T_S3op_shift32<"lsl", shl, 0b11>;
+}
+
+// Shift by register with saturation
+// Rd=asr(Rs,Rt):sat
+// Rd=asl(Rs,Rt):sat
+
+let Defs = [USR_OVF], isCodeGenOnly = 0 in {
+ def S2_asr_r_r_sat : T_S3op_shift32_Sat<"asr", 0b00>;
+ def S2_asl_r_r_sat : T_S3op_shift32_Sat<"asl", 0b10>;
+}
+
+//===----------------------------------------------------------------------===//
+// Template class for 'insert bitfield' instructions
+//===----------------------------------------------------------------------===//
+let hasSideEffects = 0 in
+class T_S3op_insert <string mnemonic, RegisterClass RC>
+ : SInst <(outs RC:$dst),
+ (ins RC:$src1, RC:$src2, DoubleRegs:$src3),
+ "$dst = "#mnemonic#"($src2, $src3)" ,
+ [], "$src1 = $dst", S_3op_tc_1_SLOT23 > {
+ bits<5> dst;
+ bits<5> src2;
+ bits<5> src3;
+
+ let IClass = 0b1100;
+
+ let Inst{27-26} = 0b10;
+ let Inst{25-24} = !if(!eq(!cast<string>(RC), "IntRegs"), 0b00, 0b10);
+ let Inst{23} = 0b0;
+ let Inst{20-16} = src2;
+ let Inst{12-8} = src3;
+ let Inst{4-0} = dst;
+ }
+
+let hasSideEffects = 0 in
+class T_S2op_insert <bits<4> RegTyBits, RegisterClass RC, Operand ImmOp>
+ : SInst <(outs RC:$dst), (ins RC:$dst2, RC:$src1, ImmOp:$src2, ImmOp:$src3),
+ "$dst = insert($src1, #$src2, #$src3)",
+ [], "$dst2 = $dst", S_2op_tc_2_SLOT23> {
+ bits<5> dst;
+ bits<5> src1;
+ bits<6> src2;
+ bits<6> src3;
+ bit bit23;
+ bit bit13;
+ string ImmOpStr = !cast<string>(ImmOp);
+
+ let bit23 = !if (!eq(ImmOpStr, "u6Imm"), src3{5}, 0);
+ let bit13 = !if (!eq(ImmOpStr, "u6Imm"), src2{5}, 0);
+
+ let IClass = 0b1000;
+
+ let Inst{27-24} = RegTyBits;
+ let Inst{23} = bit23;
+ let Inst{22-21} = src3{4-3};
+ let Inst{20-16} = src1;
+ let Inst{13} = bit13;
+ let Inst{12-8} = src2{4-0};
+ let Inst{7-5} = src3{2-0};
+ let Inst{4-0} = dst;
+ }
+
+// Rx=insert(Rs,Rtt)
+// Rx=insert(Rs,#u5,#U5)
+let hasNewValue = 1, isCodeGenOnly = 0 in {
+ def S2_insert_rp : T_S3op_insert <"insert", IntRegs>;
+ def S2_insert : T_S2op_insert <0b1111, IntRegs, u5Imm>;
+}
+
+// Rxx=insert(Rss,Rtt)
+// Rxx=insert(Rss,#u6,#U6)
+let isCodeGenOnly = 0 in {
+def S2_insertp_rp : T_S3op_insert<"insert", DoubleRegs>;
+def S2_insertp : T_S2op_insert <0b0011, DoubleRegs, u6Imm>;
+}
+
+//===----------------------------------------------------------------------===//
+// Template class for 'extract bitfield' instructions
+//===----------------------------------------------------------------------===//
+let hasNewValue = 1, hasSideEffects = 0 in
+class T_S3op_extract <string mnemonic, bits<2> MinOp>
+ : SInst <(outs IntRegs:$Rd), (ins IntRegs:$Rs, DoubleRegs:$Rtt),
+ "$Rd = "#mnemonic#"($Rs, $Rtt)",
+ [], "", S_3op_tc_2_SLOT23 > {
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<5> Rtt;
+
+ let IClass = 0b1100;
+
+ let Inst{27-22} = 0b100100;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rtt;
+ let Inst{7-6} = MinOp;
+ let Inst{4-0} = Rd;
+ }
+
+let hasSideEffects = 0 in
+class T_S2op_extract <string mnemonic, bits<4> RegTyBits,
+ RegisterClass RC, Operand ImmOp>
+ : SInst <(outs RC:$dst), (ins RC:$src1, ImmOp:$src2, ImmOp:$src3),
+ "$dst = "#mnemonic#"($src1, #$src2, #$src3)",
+ [], "", S_2op_tc_2_SLOT23> {
+ bits<5> dst;
+ bits<5> src1;
+ bits<6> src2;
+ bits<6> src3;
+ bit bit23;
+ bit bit13;
+ string ImmOpStr = !cast<string>(ImmOp);
+
+ let bit23 = !if (!eq(ImmOpStr, "u6Imm"), src3{5},
+ !if (!eq(mnemonic, "extractu"), 0, 1));
+
+ let bit13 = !if (!eq(ImmOpStr, "u6Imm"), src2{5}, 0);
+
+ let IClass = 0b1000;
+
+ let Inst{27-24} = RegTyBits;
+ let Inst{23} = bit23;
+ let Inst{22-21} = src3{4-3};
+ let Inst{20-16} = src1;
+ let Inst{13} = bit13;
+ let Inst{12-8} = src2{4-0};
+ let Inst{7-5} = src3{2-0};
+ let Inst{4-0} = dst;
+ }
+
+// Extract bitfield
+
+// Rdd=extractu(Rss,Rtt)
+// Rdd=extractu(Rss,#u6,#U6)
+let isCodeGenOnly = 0 in {
+def S2_extractup_rp : T_S3op_64 < "extractu", 0b00, 0b000, 0>;
+def S2_extractup : T_S2op_extract <"extractu", 0b0001, DoubleRegs, u6Imm>;
+}
+
+// Rd=extractu(Rs,Rtt)
+// Rd=extractu(Rs,#u5,#U5)
+let hasNewValue = 1, isCodeGenOnly = 0 in {
+ def S2_extractu_rp : T_S3op_extract<"extractu", 0b00>;
+ def S2_extractu : T_S2op_extract <"extractu", 0b1101, IntRegs, u5Imm>;
+}
+
+//===----------------------------------------------------------------------===//
+// :raw for of tableindx[bdhw] insns
+//===----------------------------------------------------------------------===//
+
+let hasSideEffects = 0, hasNewValue = 1, opNewValue = 0 in
+class tableidxRaw<string OpStr, bits<2>MinOp>
+ : SInst <(outs IntRegs:$Rx),
+ (ins IntRegs:$_dst_, IntRegs:$Rs, u4Imm:$u4, s6Imm:$S6),
+ "$Rx = "#OpStr#"($Rs, #$u4, #$S6):raw",
+ [], "$Rx = $_dst_" > {
+ bits<5> Rx;
+ bits<5> Rs;
+ bits<4> u4;
+ bits<6> S6;
+
+ let IClass = 0b1000;
+
+ let Inst{27-24} = 0b0111;
+ let Inst{23-22} = MinOp;
+ let Inst{21} = u4{3};
+ let Inst{20-16} = Rs;
+ let Inst{13-8} = S6;
+ let Inst{7-5} = u4{2-0};
+ let Inst{4-0} = Rx;
+ }
+
+let isCodeGenOnly = 0 in {
+def S2_tableidxb : tableidxRaw<"tableidxb", 0b00>;
+def S2_tableidxh : tableidxRaw<"tableidxh", 0b01>;
+def S2_tableidxw : tableidxRaw<"tableidxw", 0b10>;
+def S2_tableidxd : tableidxRaw<"tableidxd", 0b11>;
+}
// Change the sign of the immediate for Rd=-mpyi(Rs,#u8)
def : Pat <(mul (i32 IntRegs:$src1), (ineg n8ImmPred:$src2)),
- (i32 (MPYI_rin (i32 IntRegs:$src1), u8ImmPred:$src2))>;
+ (i32 (M2_mpysin (i32 IntRegs:$src1), u8ImmPred:$src2))>;
//===----------------------------------------------------------------------===//
// V3 Instructions +
diff --git a/lib/Target/Hexagon/HexagonInstrInfoV3.td b/lib/Target/Hexagon/HexagonInstrInfoV3.td
index 7e75554e7fcd..8e9147600fa6 100644
--- a/lib/Target/Hexagon/HexagonInstrInfoV3.td
+++ b/lib/Target/Hexagon/HexagonInstrInfoV3.td
@@ -21,13 +21,52 @@ def callv3nr : SDNode<"HexagonISD::CALLv3nr", SDT_SPCall,
// J +
//===----------------------------------------------------------------------===//
// Call subroutine.
-let isCall = 1, neverHasSideEffects = 1,
- Defs = [D0, D1, D2, D3, D4, D5, D6, D7, R28, R31,
- P0, P1, P2, P3, LC0, LC1, SA0, SA1] in {
- def CALLv3 : JInst<(outs), (ins calltarget:$dst),
- "call $dst", []>, Requires<[HasV3T]>;
+let isCall = 1, hasSideEffects = 1, validSubTargets = HasV3SubT,
+ Defs = VolatileV3.Regs, isPredicable = 1,
+ isExtended = 0, isExtendable = 1, opExtendable = 0,
+ isExtentSigned = 1, opExtentBits = 24, opExtentAlign = 2 in
+class T_Call<string ExtStr>
+ : JInst<(outs), (ins calltarget:$dst),
+ "call " # ExtStr # "$dst", [], "", J_tc_2early_SLOT23> {
+ let BaseOpcode = "call";
+ bits<24> dst;
+
+ let IClass = 0b0101;
+ let Inst{27-25} = 0b101;
+ let Inst{24-16,13-1} = dst{23-2};
+ let Inst{0} = 0b0;
+}
+
+let isCall = 1, hasSideEffects = 1, validSubTargets = HasV3SubT,
+ Defs = VolatileV3.Regs, isPredicated = 1,
+ isExtended = 0, isExtendable = 1, opExtendable = 1,
+ isExtentSigned = 1, opExtentBits = 17, opExtentAlign = 2 in
+class T_CallPred<bit IfTrue, string ExtStr>
+ : JInst<(outs), (ins PredRegs:$Pu, calltarget:$dst),
+ CondStr<"$Pu", IfTrue, 0>.S # "call " # ExtStr # "$dst",
+ [], "", J_tc_2early_SLOT23> {
+ let BaseOpcode = "call";
+ let isPredicatedFalse = !if(IfTrue,0,1);
+ bits<2> Pu;
+ bits<17> dst;
+
+ let IClass = 0b0101;
+ let Inst{27-24} = 0b1101;
+ let Inst{23-22,20-16,13,7-1} = dst{16-2};
+ let Inst{21} = !if(IfTrue,0,1);
+ let Inst{11} = 0b0;
+ let Inst{9-8} = Pu;
+}
+
+multiclass T_Calls<string ExtStr> {
+ def NAME : T_Call<ExtStr>;
+ def t : T_CallPred<1, ExtStr>;
+ def f : T_CallPred<0, ExtStr>;
}
+let isCodeGenOnly = 0 in
+defm J2_call: T_Calls<"">, PredRel;
+
//===----------------------------------------------------------------------===//
// J -
//===----------------------------------------------------------------------===//
@@ -37,7 +76,7 @@ let isCall = 1, neverHasSideEffects = 1,
// JR +
//===----------------------------------------------------------------------===//
// Call subroutine from register.
-let isCall = 1, neverHasSideEffects = 1,
+let isCall = 1, hasSideEffects = 0,
Defs = [D0, D1, D2, D3, D4, D5, D6, D7, R28, R31,
P0, P1, P2, P3, LC0, LC1, SA0, SA1] in {
def CALLRv3 : JRInst<(outs), (ins IntRegs:$dst),
@@ -53,27 +92,69 @@ let isCall = 1, neverHasSideEffects = 1,
// ALU64/ALU +
//===----------------------------------------------------------------------===//
-let AddedComplexity = 200 in
-def MAXw_dd : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
- DoubleRegs:$src2),
- "$dst = max($src2, $src1)",
- [(set (i64 DoubleRegs:$dst),
- (i64 (select (i1 (setlt (i64 DoubleRegs:$src2),
- (i64 DoubleRegs:$src1))),
- (i64 DoubleRegs:$src1),
- (i64 DoubleRegs:$src2))))]>,
-Requires<[HasV3T]>;
-
-let AddedComplexity = 200 in
-def MINw_dd : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
- DoubleRegs:$src2),
- "$dst = min($src2, $src1)",
- [(set (i64 DoubleRegs:$dst),
- (i64 (select (i1 (setgt (i64 DoubleRegs:$src2),
- (i64 DoubleRegs:$src1))),
- (i64 DoubleRegs:$src1),
- (i64 DoubleRegs:$src2))))]>,
-Requires<[HasV3T]>;
+
+let Defs = [USR_OVF], Itinerary = ALU64_tc_2_SLOT23,
+ validSubTargets = HasV3SubT, isCodeGenOnly = 0 in
+def A2_addpsat : T_ALU64_arith<"add", 0b011, 0b101, 1, 0, 1>;
+
+class T_ALU64_addsp_hl<string suffix, bits<3> MinOp>
+ : T_ALU64_rr<"add", suffix, 0b0011, 0b011, MinOp, 0, 0, "">;
+
+let isCodeGenOnly = 0 in {
+def A2_addspl : T_ALU64_addsp_hl<":raw:lo", 0b110>;
+def A2_addsph : T_ALU64_addsp_hl<":raw:hi", 0b111>;
+}
+
+let hasSideEffects = 0, isCodeGenOnly = 0 in
+def A2_addsp : ALU64_rr<(outs DoubleRegs:$Rd),
+ (ins IntRegs:$Rs, DoubleRegs:$Rt), "$Rd = add($Rs, $Rt)",
+ [(set (i64 DoubleRegs:$Rd), (i64 (add (i64 (sext (i32 IntRegs:$Rs))),
+ (i64 DoubleRegs:$Rt))))],
+ "", ALU64_tc_1_SLOT23>;
+
+
+let hasSideEffects = 0 in
+class T_XTYPE_MIN_MAX_P<bit isMax, bit isUnsigned>
+ : ALU64Inst<(outs DoubleRegs:$Rd), (ins DoubleRegs:$Rt, DoubleRegs:$Rs),
+ "$Rd = "#!if(isMax,"max","min")#!if(isUnsigned,"u","")
+ #"($Rt, $Rs)", [], "", ALU64_tc_2_SLOT23> {
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1101;
+
+ let Inst{27-23} = 0b00111;
+ let Inst{22-21} = !if(isMax, 0b10, 0b01);
+ let Inst{20-16} = !if(isMax, Rt, Rs);
+ let Inst{12-8} = !if(isMax, Rs, Rt);
+ let Inst{7} = 0b1;
+ let Inst{6} = !if(isMax, 0b0, 0b1);
+ let Inst{5} = isUnsigned;
+ let Inst{4-0} = Rd;
+}
+
+let isCodeGenOnly = 0 in {
+def A2_minp : T_XTYPE_MIN_MAX_P<0, 0>;
+def A2_minup : T_XTYPE_MIN_MAX_P<0, 1>;
+def A2_maxp : T_XTYPE_MIN_MAX_P<1, 0>;
+def A2_maxup : T_XTYPE_MIN_MAX_P<1, 1>;
+}
+
+multiclass MinMax_pats_p<PatFrag Op, InstHexagon Inst, InstHexagon SwapInst> {
+ defm: T_MinMax_pats<Op, DoubleRegs, i64, Inst, SwapInst>;
+}
+
+let AddedComplexity = 200 in {
+ defm: MinMax_pats_p<setge, A2_maxp, A2_minp>;
+ defm: MinMax_pats_p<setgt, A2_maxp, A2_minp>;
+ defm: MinMax_pats_p<setle, A2_minp, A2_maxp>;
+ defm: MinMax_pats_p<setlt, A2_minp, A2_maxp>;
+ defm: MinMax_pats_p<setuge, A2_maxup, A2_minup>;
+ defm: MinMax_pats_p<setugt, A2_maxup, A2_minup>;
+ defm: MinMax_pats_p<setule, A2_minup, A2_maxup>;
+ defm: MinMax_pats_p<setult, A2_minup, A2_maxup>;
+}
//===----------------------------------------------------------------------===//
// ALU64/ALU -
@@ -100,8 +181,8 @@ Requires<[HasV3T]>;
// Map call instruction
def : Pat<(call (i32 IntRegs:$dst)),
- (CALLRv3 (i32 IntRegs:$dst))>, Requires<[HasV3T]>;
+ (J2_call (i32 IntRegs:$dst))>, Requires<[HasV3T]>;
def : Pat<(call tglobaladdr:$dst),
- (CALLv3 tglobaladdr:$dst)>, Requires<[HasV3T]>;
+ (J2_call tglobaladdr:$dst)>, Requires<[HasV3T]>;
def : Pat<(call texternalsym:$dst),
- (CALLv3 texternalsym:$dst)>, Requires<[HasV3T]>;
+ (J2_call texternalsym:$dst)>, Requires<[HasV3T]>;
diff --git a/lib/Target/Hexagon/HexagonInstrInfoV4.td b/lib/Target/Hexagon/HexagonInstrInfoV4.td
index db5b7eaa68f8..08bfd676fed8 100644
--- a/lib/Target/Hexagon/HexagonInstrInfoV4.td
+++ b/lib/Target/Hexagon/HexagonInstrInfoV4.td
@@ -11,15 +11,32 @@
//
//===----------------------------------------------------------------------===//
-let neverHasSideEffects = 1 in
-class T_Immext<dag ins> :
- EXTENDERInst<(outs), ins, "immext(#$imm)", []>,
- Requires<[HasV4T]>;
+let hasSideEffects = 0 in
+class T_Immext<Operand ImmType>
+ : EXTENDERInst<(outs), (ins ImmType:$imm),
+ "immext(#$imm)", []> {
+ bits<32> imm;
+ let IClass = 0b0000;
+
+ let Inst{27-16} = imm{31-20};
+ let Inst{13-0} = imm{19-6};
+ }
+
+def A4_ext : T_Immext<u26_6Imm>;
+let isCodeGenOnly = 1 in {
+ let isBranch = 1 in
+ def A4_ext_b : T_Immext<brtarget>;
+ let isCall = 1 in
+ def A4_ext_c : T_Immext<calltarget>;
+ def A4_ext_g : T_Immext<globaladdress>;
+}
-def IMMEXT_b : T_Immext<(ins brtarget:$imm)>;
-def IMMEXT_c : T_Immext<(ins calltarget:$imm)>;
-def IMMEXT_g : T_Immext<(ins globaladdress:$imm)>;
-def IMMEXT_i : T_Immext<(ins u26_6Imm:$imm)>;
+def BITPOS32 : SDNodeXForm<imm, [{
+ // Return the bit position we will set [0-31].
+ // As an SDNode.
+ int32_t imm = N->getSExtValue();
+ return XformMskToBitPosU5Imm(imm);
+}]>;
// Fold (add (CONST32 tglobaladdr:$addr) <offset>) into a global address.
def FoldGlobalAddr : ComplexPattern<i32, 1, "foldGlobalAddress", [], []>;
@@ -95,63 +112,152 @@ def NumUsesBelowThresCONST32 : PatFrag<(ops node:$addr),
//===----------------------------------------------------------------------===//
// ALU32 +
//===----------------------------------------------------------------------===//
-// Generate frame index addresses.
-let neverHasSideEffects = 1, isReMaterializable = 1,
-isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in
-def TFR_FI_immext_V4 : ALU32_ri<(outs IntRegs:$dst),
- (ins IntRegs:$src1, s32Imm:$offset),
- "$dst = add($src1, ##$offset)",
- []>,
- Requires<[HasV4T]>;
-// Rd=cmp.eq(Rs,#s8)
-let validSubTargets = HasV4SubT, isExtendable = 1, opExtendable = 2,
-isExtentSigned = 1, opExtentBits = 8 in
-def V4_A4_rcmpeqi : ALU32_ri<(outs IntRegs:$Rd),
- (ins IntRegs:$Rs, s8Ext:$s8),
- "$Rd = cmp.eq($Rs, #$s8)",
- [(set (i32 IntRegs:$Rd),
- (i32 (zext (i1 (seteq (i32 IntRegs:$Rs),
- s8ExtPred:$s8)))))]>,
- Requires<[HasV4T]>;
-
-// Preserve the TSTBIT generation
-def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, (i32 IntRegs:$src2))),
- (i32 IntRegs:$src1))), 0)))),
- (i32 (MUX_ii (i1 (TSTBIT_rr (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
- 1, 0))>;
-
-// Interfered with tstbit generation, above pattern preserves, see : tstbit.ll
-// Rd=cmp.ne(Rs,#s8)
-let validSubTargets = HasV4SubT, isExtendable = 1, opExtendable = 2,
-isExtentSigned = 1, opExtentBits = 8 in
-def V4_A4_rcmpneqi : ALU32_ri<(outs IntRegs:$Rd),
- (ins IntRegs:$Rs, s8Ext:$s8),
- "$Rd = !cmp.eq($Rs, #$s8)",
- [(set (i32 IntRegs:$Rd),
- (i32 (zext (i1 (setne (i32 IntRegs:$Rs),
- s8ExtPred:$s8)))))]>,
- Requires<[HasV4T]>;
-
-// Rd=cmp.eq(Rs,Rt)
-let validSubTargets = HasV4SubT in
-def V4_A4_rcmpeq : ALU32_ri<(outs IntRegs:$Rd),
- (ins IntRegs:$Rs, IntRegs:$Rt),
- "$Rd = cmp.eq($Rs, $Rt)",
- [(set (i32 IntRegs:$Rd),
- (i32 (zext (i1 (seteq (i32 IntRegs:$Rs),
- IntRegs:$Rt)))))]>,
- Requires<[HasV4T]>;
+class T_ALU32_3op_not<string mnemonic, bits<3> MajOp, bits<3> MinOp,
+ bit OpsRev>
+ : T_ALU32_3op<mnemonic, MajOp, MinOp, OpsRev, 0> {
+ let AsmString = "$Rd = "#mnemonic#"($Rs, ~$Rt)";
+}
+
+let BaseOpcode = "andn_rr", CextOpcode = "andn", isCodeGenOnly = 0 in
+def A4_andn : T_ALU32_3op_not<"and", 0b001, 0b100, 1>;
+let BaseOpcode = "orn_rr", CextOpcode = "orn", isCodeGenOnly = 0 in
+def A4_orn : T_ALU32_3op_not<"or", 0b001, 0b101, 1>;
+
+let CextOpcode = "rcmp.eq", isCodeGenOnly = 0 in
+def A4_rcmpeq : T_ALU32_3op<"cmp.eq", 0b011, 0b010, 0, 1>;
+let CextOpcode = "!rcmp.eq", isCodeGenOnly = 0 in
+def A4_rcmpneq : T_ALU32_3op<"!cmp.eq", 0b011, 0b011, 0, 1>;
+
+let isCodeGenOnly = 0 in {
+def C4_cmpneq : T_ALU32_3op_cmp<"!cmp.eq", 0b00, 1, 1>;
+def C4_cmplte : T_ALU32_3op_cmp<"!cmp.gt", 0b10, 1, 0>;
+def C4_cmplteu : T_ALU32_3op_cmp<"!cmp.gtu", 0b11, 1, 0>;
+}
+
+// Pats for instruction selection.
+
+// A class to embed the usual comparison patfrags within a zext to i32.
+// The seteq/setne frags use "lhs" and "rhs" as operands, so use the same
+// names, or else the frag's "body" won't match the operands.
+class CmpInReg<PatFrag Op>
+ : PatFrag<(ops node:$lhs, node:$rhs),(i32 (zext (i1 Op.Fragment)))>;
+
+def: T_cmp32_rr_pat<A4_rcmpeq, CmpInReg<seteq>, i32>;
+def: T_cmp32_rr_pat<A4_rcmpneq, CmpInReg<setne>, i32>;
+
+class T_CMP_rrbh<string mnemonic, bits<3> MinOp, bit IsComm>
+ : SInst<(outs PredRegs:$Pd), (ins IntRegs:$Rs, IntRegs:$Rt),
+ "$Pd = "#mnemonic#"($Rs, $Rt)", [], "", S_3op_tc_2early_SLOT23>,
+ ImmRegRel {
+ let validSubTargets = HasV4SubT;
+ let InputType = "reg";
+ let CextOpcode = mnemonic;
+ let isCompare = 1;
+ let isCommutable = IsComm;
+ let hasSideEffects = 0;
+
+ bits<2> Pd;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1100;
+ let Inst{27-21} = 0b0111110;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ let Inst{7-5} = MinOp;
+ let Inst{1-0} = Pd;
+}
+
+let isCodeGenOnly = 0 in {
+def A4_cmpbeq : T_CMP_rrbh<"cmpb.eq", 0b110, 1>;
+def A4_cmpbgt : T_CMP_rrbh<"cmpb.gt", 0b010, 0>;
+def A4_cmpbgtu : T_CMP_rrbh<"cmpb.gtu", 0b111, 0>;
+def A4_cmpheq : T_CMP_rrbh<"cmph.eq", 0b011, 1>;
+def A4_cmphgt : T_CMP_rrbh<"cmph.gt", 0b100, 0>;
+def A4_cmphgtu : T_CMP_rrbh<"cmph.gtu", 0b101, 0>;
+}
+
+class T_CMP_ribh<string mnemonic, bits<2> MajOp, bit IsHalf, bit IsComm,
+ Operand ImmType, bit IsImmExt, bit IsImmSigned, int ImmBits>
+ : ALU64Inst<(outs PredRegs:$Pd), (ins IntRegs:$Rs, ImmType:$Imm),
+ "$Pd = "#mnemonic#"($Rs, #$Imm)", [], "", ALU64_tc_2early_SLOT23>,
+ ImmRegRel {
+ let validSubTargets = HasV4SubT;
+ let InputType = "imm";
+ let CextOpcode = mnemonic;
+ let isCompare = 1;
+ let isCommutable = IsComm;
+ let hasSideEffects = 0;
+ let isExtendable = IsImmExt;
+ let opExtendable = !if (IsImmExt, 2, 0);
+ let isExtentSigned = IsImmSigned;
+ let opExtentBits = ImmBits;
+
+ bits<2> Pd;
+ bits<5> Rs;
+ bits<8> Imm;
+
+ let IClass = 0b1101;
+ let Inst{27-24} = 0b1101;
+ let Inst{22-21} = MajOp;
+ let Inst{20-16} = Rs;
+ let Inst{12-5} = Imm;
+ let Inst{4} = 0b0;
+ let Inst{3} = IsHalf;
+ let Inst{1-0} = Pd;
+}
+
+let isCodeGenOnly = 0 in {
+def A4_cmpbeqi : T_CMP_ribh<"cmpb.eq", 0b00, 0, 1, u8Imm, 0, 0, 8>;
+def A4_cmpbgti : T_CMP_ribh<"cmpb.gt", 0b01, 0, 0, s8Imm, 0, 1, 8>;
+def A4_cmpbgtui : T_CMP_ribh<"cmpb.gtu", 0b10, 0, 0, u7Ext, 1, 0, 7>;
+def A4_cmpheqi : T_CMP_ribh<"cmph.eq", 0b00, 1, 1, s8Ext, 1, 1, 8>;
+def A4_cmphgti : T_CMP_ribh<"cmph.gt", 0b01, 1, 0, s8Ext, 1, 1, 8>;
+def A4_cmphgtui : T_CMP_ribh<"cmph.gtu", 0b10, 1, 0, u7Ext, 1, 0, 7>;
+}
+class T_RCMP_EQ_ri<string mnemonic, bit IsNeg>
+ : ALU32_ri<(outs IntRegs:$Rd), (ins IntRegs:$Rs, s8Ext:$s8),
+ "$Rd = "#mnemonic#"($Rs, #$s8)", [], "", ALU32_2op_tc_1_SLOT0123>,
+ ImmRegRel {
+ let validSubTargets = HasV4SubT;
+ let InputType = "imm";
+ let CextOpcode = !if (IsNeg, "!rcmp.eq", "rcmp.eq");
+ let isExtendable = 1;
+ let opExtendable = 2;
+ let isExtentSigned = 1;
+ let opExtentBits = 8;
+ let hasNewValue = 1;
+
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<8> s8;
+
+ let IClass = 0b0111;
+ let Inst{27-24} = 0b0011;
+ let Inst{22} = 0b1;
+ let Inst{21} = IsNeg;
+ let Inst{20-16} = Rs;
+ let Inst{13} = 0b1;
+ let Inst{12-5} = s8;
+ let Inst{4-0} = Rd;
+}
+
+let isCodeGenOnly = 0 in {
+def A4_rcmpeqi : T_RCMP_EQ_ri<"cmp.eq", 0>;
+def A4_rcmpneqi : T_RCMP_EQ_ri<"!cmp.eq", 1>;
+}
+
+def: Pat<(i32 (zext (i1 (seteq (i32 IntRegs:$Rs), s8ExtPred:$s8)))),
+ (A4_rcmpeqi IntRegs:$Rs, s8ExtPred:$s8)>;
+def: Pat<(i32 (zext (i1 (setne (i32 IntRegs:$Rs), s8ExtPred:$s8)))),
+ (A4_rcmpneqi IntRegs:$Rs, s8ExtPred:$s8)>;
+
+// Preserve the S2_tstbit_r generation
+def: Pat<(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, (i32 IntRegs:$src2))),
+ (i32 IntRegs:$src1))), 0)))),
+ (C2_muxii (S2_tstbit_r IntRegs:$src1, IntRegs:$src2), 1, 0)>;
-// Rd=cmp.ne(Rs,Rt)
-let validSubTargets = HasV4SubT in
-def V4_A4_rcmpneq : ALU32_ri<(outs IntRegs:$Rd),
- (ins IntRegs:$Rs, IntRegs:$Rt),
- "$Rd = !cmp.eq($Rs, $Rt)",
- [(set (i32 IntRegs:$Rd),
- (i32 (zext (i1 (setne (i32 IntRegs:$Rs),
- IntRegs:$Rt)))))]>,
- Requires<[HasV4T]>;
//===----------------------------------------------------------------------===//
// ALU32 -
@@ -162,24 +268,31 @@ def V4_A4_rcmpneq : ALU32_ri<(outs IntRegs:$Rd),
// ALU32/PERM +
//===----------------------------------------------------------------------===//
-// Combine
-// Rdd=combine(Rs, #s8)
-let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
- neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-def COMBINE_rI_V4 : ALU32_ri<(outs DoubleRegs:$dst),
- (ins IntRegs:$src1, s8Ext:$src2),
- "$dst = combine($src1, #$src2)",
- []>,
- Requires<[HasV4T]>;
+// Combine a word and an immediate into a register pair.
+let hasSideEffects = 0, isExtentSigned = 1, isExtendable = 1,
+ opExtentBits = 8 in
+class T_Combine1 <bits<2> MajOp, dag ins, string AsmStr>
+ : ALU32Inst <(outs DoubleRegs:$Rdd), ins, AsmStr> {
+ bits<5> Rdd;
+ bits<5> Rs;
+ bits<8> s8;
+
+ let IClass = 0b0111;
+ let Inst{27-24} = 0b0011;
+ let Inst{22-21} = MajOp;
+ let Inst{20-16} = Rs;
+ let Inst{13} = 0b1;
+ let Inst{12-5} = s8;
+ let Inst{4-0} = Rdd;
+ }
-// Rdd=combine(#s8, Rs)
-let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8,
- neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-def COMBINE_Ir_V4 : ALU32_ir<(outs DoubleRegs:$dst),
- (ins s8Ext:$src1, IntRegs:$src2),
- "$dst = combine(#$src1, $src2)",
- []>,
- Requires<[HasV4T]>;
+let opExtendable = 2, isCodeGenOnly = 0 in
+def A4_combineri : T_Combine1<0b00, (ins IntRegs:$Rs, s8Ext:$s8),
+ "$Rdd = combine($Rs, #$s8)">;
+
+let opExtendable = 1, isCodeGenOnly = 0 in
+def A4_combineir : T_Combine1<0b01, (ins s8Ext:$s8, IntRegs:$Rs),
+ "$Rdd = combine(#$s8, $Rs)">;
def HexagonWrapperCombineRI_V4 :
SDNode<"HexagonISD::WrapperCombineRI_V4", SDTHexagonI64I32I32>;
@@ -187,23 +300,31 @@ def HexagonWrapperCombineIR_V4 :
SDNode<"HexagonISD::WrapperCombineIR_V4", SDTHexagonI64I32I32>;
def : Pat <(HexagonWrapperCombineRI_V4 IntRegs:$r, s8ExtPred:$i),
- (COMBINE_rI_V4 IntRegs:$r, s8ExtPred:$i)>,
+ (A4_combineri IntRegs:$r, s8ExtPred:$i)>,
Requires<[HasV4T]>;
def : Pat <(HexagonWrapperCombineIR_V4 s8ExtPred:$i, IntRegs:$r),
- (COMBINE_Ir_V4 s8ExtPred:$i, IntRegs:$r)>,
+ (A4_combineir s8ExtPred:$i, IntRegs:$r)>,
Requires<[HasV4T]>;
-let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 6,
- neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-def COMBINE_iI_V4 : ALU32_ii<(outs DoubleRegs:$dst),
- (ins s8Imm:$src1, u6Ext:$src2),
- "$dst = combine(#$src1, #$src2)",
- []>,
- Requires<[HasV4T]>;
+// A4_combineii: Set two small immediates.
+let hasSideEffects = 0, isExtendable = 1, opExtentBits = 6, opExtendable = 2 in
+def A4_combineii: ALU32Inst<(outs DoubleRegs:$Rdd), (ins s8Imm:$s8, u6Ext:$U6),
+ "$Rdd = combine(#$s8, #$U6)"> {
+ bits<5> Rdd;
+ bits<8> s8;
+ bits<6> U6;
+
+ let IClass = 0b0111;
+ let Inst{27-23} = 0b11001;
+ let Inst{20-16} = U6{5-1};
+ let Inst{13} = U6{0};
+ let Inst{12-5} = s8;
+ let Inst{4-0} = Rdd;
+ }
//===----------------------------------------------------------------------===//
-// ALU32/PERM +
+// ALU32/PERM -
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
@@ -212,7 +333,7 @@ def COMBINE_iI_V4 : ALU32_ii<(outs DoubleRegs:$dst),
//===----------------------------------------------------------------------===//
// Template class for load instructions with Absolute set addressing mode.
//===----------------------------------------------------------------------===//
-let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
+let isExtended = 1, opExtendable = 2, hasSideEffects = 0,
validSubTargets = HasV4SubT, addrMode = AbsoluteSet in
class T_LD_abs_set<string mnemonic, RegisterClass RC>:
LDInst2<(outs RC:$dst1, IntRegs:$dst2),
@@ -228,112 +349,152 @@ def LDrih_abs_set_V4 : T_LD_abs_set <"memh", IntRegs>;
def LDriw_abs_set_V4 : T_LD_abs_set <"memw", IntRegs>;
def LDriuh_abs_set_V4 : T_LD_abs_set <"memuh", IntRegs>;
+//===----------------------------------------------------------------------===//
+// Template classes for the non-predicated load instructions with
+// base + register offset addressing mode
+//===----------------------------------------------------------------------===//
+class T_load_rr <string mnemonic, RegisterClass RC, bits<3> MajOp>:
+ LDInst<(outs RC:$dst), (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$u2),
+ "$dst = "#mnemonic#"($src1 + $src2<<#$u2)",
+ [], "", V4LDST_tc_ld_SLOT01>, ImmRegShl, AddrModeRel {
+ bits<5> dst;
+ bits<5> src1;
+ bits<5> src2;
+ bits<2> u2;
-// multiclass for load instructions with base + register offset
-// addressing mode
-multiclass ld_idxd_shl_pbase<string mnemonic, RegisterClass RC, bit isNot,
- bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME : LDInst2<(outs RC:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#"$dst = "#mnemonic#"($src2+$src3<<#$offset)",
- []>, Requires<[HasV4T]>;
-}
+ let IClass = 0b0011;
-multiclass ld_idxd_shl_pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 0>;
- // Predicate new
- defm _cdn#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 1>;
+ let Inst{27-24} = 0b1010;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = src1;
+ let Inst{12-8} = src2;
+ let Inst{13} = u2{1};
+ let Inst{7} = u2{0};
+ let Inst{4-0} = dst;
}
-}
-let neverHasSideEffects = 1 in
-multiclass ld_idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
- let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
+//===----------------------------------------------------------------------===//
+// Template classes for the predicated load instructions with
+// base + register offset addressing mode
+//===----------------------------------------------------------------------===//
+let isPredicated = 1 in
+class T_pload_rr <string mnemonic, RegisterClass RC, bits<3> MajOp,
+ bit isNot, bit isPredNew>:
+ LDInst <(outs RC:$dst),
+ (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$u2),
+ !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#"$dst = "#mnemonic#"($src2+$src3<<#$u2)",
+ [], "", V4LDST_tc_ld_SLOT01>, AddrModeRel {
+ bits<5> dst;
+ bits<2> src1;
+ bits<5> src2;
+ bits<5> src3;
+ bits<2> u2;
+
+ let isPredicatedFalse = isNot;
+ let isPredicatedNew = isPredNew;
+
+ let IClass = 0b0011;
+
+ let Inst{27-26} = 0b00;
+ let Inst{25} = isPredNew;
+ let Inst{24} = isNot;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = src2;
+ let Inst{12-8} = src3;
+ let Inst{13} = u2{1};
+ let Inst{7} = u2{0};
+ let Inst{6-5} = src1;
+ let Inst{4-0} = dst;
+ }
+
+//===----------------------------------------------------------------------===//
+// multiclass for load instructions with base + register offset
+// addressing mode
+//===----------------------------------------------------------------------===//
+let hasSideEffects = 0, addrMode = BaseRegOffset in
+multiclass ld_idxd_shl <string mnemonic, string CextOp, RegisterClass RC,
+ bits<3> MajOp > {
+ let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl,
+ InputType = "reg" in {
let isPredicable = 1 in
- def NAME#_V4 : LDInst2<(outs RC:$dst),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset),
- "$dst = "#mnemonic#"($src1+$src2<<#$offset)",
- []>, Requires<[HasV4T]>;
-
- let isPredicated = 1 in {
- defm Pt_V4 : ld_idxd_shl_pred<mnemonic, RC, 0 >;
- defm NotPt_V4 : ld_idxd_shl_pred<mnemonic, RC, 1>;
- }
+ def L4_#NAME#_rr : T_load_rr <mnemonic, RC, MajOp>;
+
+ // Predicated
+ def L4_p#NAME#t_rr : T_pload_rr <mnemonic, RC, MajOp, 0, 0>;
+ def L4_p#NAME#f_rr : T_pload_rr <mnemonic, RC, MajOp, 1, 0>;
+
+ // Predicated new
+ def L4_p#NAME#tnew_rr : T_pload_rr <mnemonic, RC, MajOp, 0, 1>;
+ def L4_p#NAME#fnew_rr : T_pload_rr <mnemonic, RC, MajOp, 1, 1>;
}
}
-let addrMode = BaseRegOffset in {
- let accessSize = ByteAccess in {
- defm LDrib_indexed_shl: ld_idxd_shl<"memb", "LDrib", IntRegs>,
- AddrModeRel;
- defm LDriub_indexed_shl: ld_idxd_shl<"memub", "LDriub", IntRegs>,
- AddrModeRel;
- }
- let accessSize = HalfWordAccess in {
- defm LDrih_indexed_shl: ld_idxd_shl<"memh", "LDrih", IntRegs>, AddrModeRel;
- defm LDriuh_indexed_shl: ld_idxd_shl<"memuh", "LDriuh", IntRegs>,
- AddrModeRel;
- }
- let accessSize = WordAccess in
- defm LDriw_indexed_shl: ld_idxd_shl<"memw", "LDriw", IntRegs>, AddrModeRel;
+let hasNewValue = 1, accessSize = ByteAccess, isCodeGenOnly = 0 in {
+ defm loadrb : ld_idxd_shl<"memb", "LDrib", IntRegs, 0b000>;
+ defm loadrub : ld_idxd_shl<"memub", "LDriub", IntRegs, 0b001>;
+}
- let accessSize = DoubleWordAccess in
- defm LDrid_indexed_shl: ld_idxd_shl<"memd", "LDrid", DoubleRegs>,
- AddrModeRel;
+let hasNewValue = 1, accessSize = HalfWordAccess, isCodeGenOnly = 0 in {
+ defm loadrh : ld_idxd_shl<"memh", "LDrih", IntRegs, 0b010>;
+ defm loadruh : ld_idxd_shl<"memuh", "LDriuh", IntRegs, 0b011>;
}
+let hasNewValue = 1, accessSize = WordAccess, isCodeGenOnly = 0 in
+defm loadri : ld_idxd_shl<"memw", "LDriw", IntRegs, 0b100>;
+
+let accessSize = DoubleWordAccess, isCodeGenOnly = 0 in
+defm loadrd : ld_idxd_shl<"memd", "LDrid", DoubleRegs, 0b110>;
+
// 'def pats' for load instructions with base + register offset and non-zero
// immediate value. Immediate value is used to left-shift the second
// register operand.
let AddedComplexity = 40 in {
def : Pat <(i32 (sextloadi8 (add IntRegs:$src1,
(shl IntRegs:$src2, u2ImmPred:$offset)))),
- (LDrib_indexed_shl_V4 IntRegs:$src1,
+ (L4_loadrb_rr IntRegs:$src1,
IntRegs:$src2, u2ImmPred:$offset)>,
Requires<[HasV4T]>;
def : Pat <(i32 (zextloadi8 (add IntRegs:$src1,
(shl IntRegs:$src2, u2ImmPred:$offset)))),
- (LDriub_indexed_shl_V4 IntRegs:$src1,
+ (L4_loadrub_rr IntRegs:$src1,
IntRegs:$src2, u2ImmPred:$offset)>,
Requires<[HasV4T]>;
def : Pat <(i32 (extloadi8 (add IntRegs:$src1,
(shl IntRegs:$src2, u2ImmPred:$offset)))),
- (LDriub_indexed_shl_V4 IntRegs:$src1,
+ (L4_loadrub_rr IntRegs:$src1,
IntRegs:$src2, u2ImmPred:$offset)>,
Requires<[HasV4T]>;
def : Pat <(i32 (sextloadi16 (add IntRegs:$src1,
(shl IntRegs:$src2, u2ImmPred:$offset)))),
- (LDrih_indexed_shl_V4 IntRegs:$src1,
+ (L4_loadrh_rr IntRegs:$src1,
IntRegs:$src2, u2ImmPred:$offset)>,
Requires<[HasV4T]>;
def : Pat <(i32 (zextloadi16 (add IntRegs:$src1,
(shl IntRegs:$src2, u2ImmPred:$offset)))),
- (LDriuh_indexed_shl_V4 IntRegs:$src1,
+ (L4_loadruh_rr IntRegs:$src1,
IntRegs:$src2, u2ImmPred:$offset)>,
Requires<[HasV4T]>;
def : Pat <(i32 (extloadi16 (add IntRegs:$src1,
(shl IntRegs:$src2, u2ImmPred:$offset)))),
- (LDriuh_indexed_shl_V4 IntRegs:$src1,
+ (L4_loadruh_rr IntRegs:$src1,
IntRegs:$src2, u2ImmPred:$offset)>,
Requires<[HasV4T]>;
def : Pat <(i32 (load (add IntRegs:$src1,
(shl IntRegs:$src2, u2ImmPred:$offset)))),
- (LDriw_indexed_shl_V4 IntRegs:$src1,
+ (L4_loadri_rr IntRegs:$src1,
IntRegs:$src2, u2ImmPred:$offset)>,
Requires<[HasV4T]>;
def : Pat <(i64 (load (add IntRegs:$src1,
(shl IntRegs:$src2, u2ImmPred:$offset)))),
- (LDrid_indexed_shl_V4 IntRegs:$src1,
+ (L4_loadrd_rr IntRegs:$src1,
IntRegs:$src2, u2ImmPred:$offset)>,
Requires<[HasV4T]>;
}
@@ -343,114 +504,114 @@ def : Pat <(i64 (load (add IntRegs:$src1,
// zero immediate value.
let AddedComplexity = 10 in {
def : Pat <(i64 (load (add IntRegs:$src1, IntRegs:$src2))),
- (LDrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
+ (L4_loadrd_rr IntRegs:$src1, IntRegs:$src2, 0)>,
Requires<[HasV4T]>;
def : Pat <(i32 (sextloadi8 (add IntRegs:$src1, IntRegs:$src2))),
- (LDrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
+ (L4_loadrb_rr IntRegs:$src1, IntRegs:$src2, 0)>,
Requires<[HasV4T]>;
def : Pat <(i32 (zextloadi8 (add IntRegs:$src1, IntRegs:$src2))),
- (LDriub_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
+ (L4_loadrub_rr IntRegs:$src1, IntRegs:$src2, 0)>,
Requires<[HasV4T]>;
def : Pat <(i32 (extloadi8 (add IntRegs:$src1, IntRegs:$src2))),
- (LDriub_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
+ (L4_loadrub_rr IntRegs:$src1, IntRegs:$src2, 0)>,
Requires<[HasV4T]>;
def : Pat <(i32 (sextloadi16 (add IntRegs:$src1, IntRegs:$src2))),
- (LDrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
+ (L4_loadrh_rr IntRegs:$src1, IntRegs:$src2, 0)>,
Requires<[HasV4T]>;
def : Pat <(i32 (zextloadi16 (add IntRegs:$src1, IntRegs:$src2))),
- (LDriuh_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
+ (L4_loadruh_rr IntRegs:$src1, IntRegs:$src2, 0)>,
Requires<[HasV4T]>;
def : Pat <(i32 (extloadi16 (add IntRegs:$src1, IntRegs:$src2))),
- (LDriuh_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
+ (L4_loadruh_rr IntRegs:$src1, IntRegs:$src2, 0)>,
Requires<[HasV4T]>;
def : Pat <(i32 (load (add IntRegs:$src1, IntRegs:$src2))),
- (LDriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
+ (L4_loadri_rr IntRegs:$src1, IntRegs:$src2, 0)>,
Requires<[HasV4T]>;
}
// zext i1->i64
def : Pat <(i64 (zext (i1 PredRegs:$src1))),
- (i64 (COMBINE_Ir_V4 0, (MUX_ii (i1 PredRegs:$src1), 1, 0)))>,
+ (i64 (A4_combineir 0, (C2_muxii (i1 PredRegs:$src1), 1, 0)))>,
Requires<[HasV4T]>;
// zext i32->i64
def : Pat <(i64 (zext (i32 IntRegs:$src1))),
- (i64 (COMBINE_Ir_V4 0, (i32 IntRegs:$src1)))>,
+ (i64 (A4_combineir 0, (i32 IntRegs:$src1)))>,
Requires<[HasV4T]>;
// zext i8->i64
def: Pat <(i64 (zextloadi8 ADDRriS11_0:$src1)),
- (i64 (COMBINE_Ir_V4 0, (LDriub ADDRriS11_0:$src1)))>,
+ (i64 (A4_combineir 0, (L2_loadrub_io AddrFI:$src1, 0)))>,
Requires<[HasV4T]>;
let AddedComplexity = 20 in
def: Pat <(i64 (zextloadi8 (add (i32 IntRegs:$src1),
s11_0ExtPred:$offset))),
- (i64 (COMBINE_Ir_V4 0, (LDriub_indexed IntRegs:$src1,
+ (i64 (A4_combineir 0, (L2_loadrub_io IntRegs:$src1,
s11_0ExtPred:$offset)))>,
Requires<[HasV4T]>;
// zext i1->i64
def: Pat <(i64 (zextloadi1 ADDRriS11_0:$src1)),
- (i64 (COMBINE_Ir_V4 0, (LDriub ADDRriS11_0:$src1)))>,
+ (i64 (A4_combineir 0, (L2_loadrub_io AddrFI:$src1, 0)))>,
Requires<[HasV4T]>;
let AddedComplexity = 20 in
def: Pat <(i64 (zextloadi1 (add (i32 IntRegs:$src1),
s11_0ExtPred:$offset))),
- (i64 (COMBINE_Ir_V4 0, (LDriub_indexed IntRegs:$src1,
+ (i64 (A4_combineir 0, (L2_loadrub_io IntRegs:$src1,
s11_0ExtPred:$offset)))>,
Requires<[HasV4T]>;
// zext i16->i64
def: Pat <(i64 (zextloadi16 ADDRriS11_1:$src1)),
- (i64 (COMBINE_Ir_V4 0, (LDriuh ADDRriS11_1:$src1)))>,
+ (i64 (A4_combineir 0, (L2_loadruh_io AddrFI:$src1, 0)))>,
Requires<[HasV4T]>;
let AddedComplexity = 20 in
def: Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1),
s11_1ExtPred:$offset))),
- (i64 (COMBINE_Ir_V4 0, (LDriuh_indexed IntRegs:$src1,
+ (i64 (A4_combineir 0, (L2_loadruh_io IntRegs:$src1,
s11_1ExtPred:$offset)))>,
Requires<[HasV4T]>;
// anyext i16->i64
def: Pat <(i64 (extloadi16 ADDRriS11_2:$src1)),
- (i64 (COMBINE_Ir_V4 0, (LDrih ADDRriS11_2:$src1)))>,
+ (i64 (A4_combineir 0, (L2_loadrh_io AddrFI:$src1, 0)))>,
Requires<[HasV4T]>;
let AddedComplexity = 20 in
def: Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1),
s11_1ExtPred:$offset))),
- (i64 (COMBINE_Ir_V4 0, (LDrih_indexed IntRegs:$src1,
+ (i64 (A4_combineir 0, (L2_loadrh_io IntRegs:$src1,
s11_1ExtPred:$offset)))>,
Requires<[HasV4T]>;
// zext i32->i64
def: Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)),
- (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>,
+ (i64 (A4_combineir 0, (L2_loadri_io AddrFI:$src1, 0)))>,
Requires<[HasV4T]>;
let AddedComplexity = 100 in
def: Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
- (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1,
+ (i64 (A4_combineir 0, (L2_loadri_io IntRegs:$src1,
s11_2ExtPred:$offset)))>,
Requires<[HasV4T]>;
// anyext i32->i64
def: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
- (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>,
+ (i64 (A4_combineir 0, (L2_loadri_io AddrFI:$src1, 0)))>,
Requires<[HasV4T]>;
let AddedComplexity = 100 in
def: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
- (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1,
+ (i64 (A4_combineir 0, (L2_loadri_io IntRegs:$src1,
s11_2ExtPred:$offset)))>,
Requires<[HasV4T]>;
@@ -482,124 +643,209 @@ def STrih_abs_set_V4 : T_ST_abs_set <"memh", IntRegs>;
def STriw_abs_set_V4 : T_ST_abs_set <"memw", IntRegs>;
//===----------------------------------------------------------------------===//
-// multiclass for store instructions with base + register offset addressing
-// mode
+// Template classes for the non-predicated store instructions with
+// base + register offset addressing mode
//===----------------------------------------------------------------------===//
-multiclass ST_Idxd_shl_Pbase<string mnemonic, RegisterClass RC, bit isNot,
- bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- RC:$src5),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5",
- []>,
- Requires<[HasV4T]>;
-}
+let isPredicable = 1 in
+class T_store_rr <string mnemonic, RegisterClass RC, bits<3> MajOp, bit isH>
+ : STInst < (outs ), (ins IntRegs:$Rs, IntRegs:$Ru, u2Imm:$u2, RC:$Rt),
+ mnemonic#"($Rs + $Ru<<#$u2) = $Rt"#!if(isH, ".h",""),
+ [],"",V4LDST_tc_st_SLOT01>, ImmRegShl, AddrModeRel {
-multiclass ST_Idxd_shl_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 0>;
- // Predicate new
- defm _cdn#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 1>;
+ bits<5> Rs;
+ bits<5> Ru;
+ bits<2> u2;
+ bits<5> Rt;
+
+ let IClass = 0b0011;
+
+ let Inst{27-24} = 0b1011;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Ru;
+ let Inst{13} = u2{1};
+ let Inst{7} = u2{0};
+ let Inst{4-0} = Rt;
+ }
+
+//===----------------------------------------------------------------------===//
+// Template classes for the predicated store instructions with
+// base + register offset addressing mode
+//===----------------------------------------------------------------------===//
+let isPredicated = 1 in
+class T_pstore_rr <string mnemonic, RegisterClass RC, bits<3> MajOp,
+ bit isNot, bit isPredNew, bit isH>
+ : STInst <(outs),
+ (ins PredRegs:$Pv, IntRegs:$Rs, IntRegs:$Ru, u2Imm:$u2, RC:$Rt),
+
+ !if(isNot, "if (!$Pv", "if ($Pv")#!if(isPredNew, ".new) ",
+ ") ")#mnemonic#"($Rs+$Ru<<#$u2) = $Rt"#!if(isH, ".h",""),
+ [], "", V4LDST_tc_st_SLOT01> , AddrModeRel{
+ bits<2> Pv;
+ bits<5> Rs;
+ bits<5> Ru;
+ bits<2> u2;
+ bits<5> Rt;
+
+ let isPredicatedFalse = isNot;
+ let isPredicatedNew = isPredNew;
+
+ let IClass = 0b0011;
+
+ let Inst{27-26} = 0b01;
+ let Inst{25} = isPredNew;
+ let Inst{24} = isNot;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Ru;
+ let Inst{13} = u2{1};
+ let Inst{7} = u2{0};
+ let Inst{6-5} = Pv;
+ let Inst{4-0} = Rt;
+ }
+
+//===----------------------------------------------------------------------===//
+// Template classes for the new-value store instructions with
+// base + register offset addressing mode
+//===----------------------------------------------------------------------===//
+let isPredicable = 1, isNewValue = 1, opNewValue = 3 in
+class T_store_new_rr <string mnemonic, bits<2> MajOp> :
+ NVInst < (outs ), (ins IntRegs:$Rs, IntRegs:$Ru, u2Imm:$u2, IntRegs:$Nt),
+ mnemonic#"($Rs + $Ru<<#$u2) = $Nt.new",
+ [],"",V4LDST_tc_st_SLOT0>, ImmRegShl, AddrModeRel {
+
+ bits<5> Rs;
+ bits<5> Ru;
+ bits<2> u2;
+ bits<3> Nt;
+
+ let IClass = 0b0011;
+
+ let Inst{27-21} = 0b1011101;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Ru;
+ let Inst{13} = u2{1};
+ let Inst{7} = u2{0};
+ let Inst{4-3} = MajOp;
+ let Inst{2-0} = Nt;
}
-}
+//===----------------------------------------------------------------------===//
+// Template classes for the predicated new-value store instructions with
+// base + register offset addressing mode
+//===----------------------------------------------------------------------===//
+let isPredicated = 1, isNewValue = 1, opNewValue = 4 in
+class T_pstore_new_rr <string mnemonic, bits<2> MajOp, bit isNot, bit isPredNew>
+ : NVInst<(outs),
+ (ins PredRegs:$Pv, IntRegs:$Rs, IntRegs:$Ru, u2Imm:$u2, IntRegs:$Nt),
+ !if(isNot, "if (!$Pv", "if ($Pv")#!if(isPredNew, ".new) ",
+ ") ")#mnemonic#"($Rs+$Ru<<#$u2) = $Nt.new",
+ [], "", V4LDST_tc_st_SLOT0>, AddrModeRel {
+ bits<2> Pv;
+ bits<5> Rs;
+ bits<5> Ru;
+ bits<2> u2;
+ bits<3> Nt;
+
+ let isPredicatedFalse = isNot;
+ let isPredicatedNew = isPredNew;
+
+ let IClass = 0b0011;
+ let Inst{27-26} = 0b01;
+ let Inst{25} = isPredNew;
+ let Inst{24} = isNot;
+ let Inst{23-21} = 0b101;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Ru;
+ let Inst{13} = u2{1};
+ let Inst{7} = u2{0};
+ let Inst{6-5} = Pv;
+ let Inst{4-3} = MajOp;
+ let Inst{2-0} = Nt;
+ }
+
+//===----------------------------------------------------------------------===//
+// multiclass for store instructions with base + register offset addressing
+// mode
+//===----------------------------------------------------------------------===//
let isNVStorable = 1 in
-multiclass ST_Idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
+multiclass ST_Idxd_shl<string mnemonic, string CextOp, RegisterClass RC,
+ bits<3> MajOp, bit isH = 0> {
let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
- let isPredicable = 1 in
- def NAME#_V4 : STInst2<(outs),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
- mnemonic#"($src1+$src2<<#$src3) = $src4",
- []>,
- Requires<[HasV4T]>;
+ def S4_#NAME#_rr : T_store_rr <mnemonic, RC, MajOp, isH>;
- let isPredicated = 1 in {
- defm Pt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 0 >;
- defm NotPt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 1>;
- }
+ // Predicated
+ def S4_p#NAME#t_rr : T_pstore_rr <mnemonic, RC, MajOp, 0, 0, isH>;
+ def S4_p#NAME#f_rr : T_pstore_rr <mnemonic, RC, MajOp, 1, 0, isH>;
+
+ // Predicated new
+ def S4_p#NAME#tnew_rr : T_pstore_rr <mnemonic, RC, MajOp, 0, 1, isH>;
+ def S4_p#NAME#fnew_rr : T_pstore_rr <mnemonic, RC, MajOp, 1, 1, isH>;
}
}
+//===----------------------------------------------------------------------===//
// multiclass for new-value store instructions with base + register offset
// addressing mode.
-multiclass ST_Idxd_shl_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
- bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME#_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
- RC:$src5),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5.new",
- []>,
- Requires<[HasV4T]>;
-}
-
-multiclass ST_Idxd_shl_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 0>;
- // Predicate new
- defm _cdn#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 1>;
- }
-}
-
+//===----------------------------------------------------------------------===//
let mayStore = 1, isNVStore = 1 in
-multiclass ST_Idxd_shl_nv<string mnemonic, string CextOp, RegisterClass RC> {
+multiclass ST_Idxd_shl_nv <string mnemonic, string CextOp, RegisterClass RC,
+ bits<2> MajOp> {
let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
- let isPredicable = 1 in
- def NAME#_nv_V4 : NVInst_V4<(outs),
- (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
- mnemonic#"($src1+$src2<<#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
+ def S4_#NAME#new_rr : T_store_new_rr<mnemonic, MajOp>;
- let isPredicated = 1 in {
- defm Pt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 0 >;
- defm NotPt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 1>;
- }
+ // Predicated
+ def S4_p#NAME#newt_rr : T_pstore_new_rr <mnemonic, MajOp, 0, 0>;
+ def S4_p#NAME#newf_rr : T_pstore_new_rr <mnemonic, MajOp, 1, 0>;
+
+ // Predicated new
+ def S4_p#NAME#newtnew_rr : T_pstore_new_rr <mnemonic, MajOp, 0, 1>;
+ def S4_p#NAME#newfnew_rr : T_pstore_new_rr <mnemonic, MajOp, 1, 1>;
}
}
-let addrMode = BaseRegOffset, neverHasSideEffects = 1,
-validSubTargets = HasV4SubT in {
+let addrMode = BaseRegOffset, InputType = "reg", hasSideEffects = 0,
+ isCodeGenOnly = 0 in {
let accessSize = ByteAccess in
- defm STrib_indexed_shl: ST_Idxd_shl<"memb", "STrib", IntRegs>,
- ST_Idxd_shl_nv<"memb", "STrib", IntRegs>, AddrModeRel;
+ defm storerb: ST_Idxd_shl<"memb", "STrib", IntRegs, 0b000>,
+ ST_Idxd_shl_nv<"memb", "STrib", IntRegs, 0b00>;
let accessSize = HalfWordAccess in
- defm STrih_indexed_shl: ST_Idxd_shl<"memh", "STrih", IntRegs>,
- ST_Idxd_shl_nv<"memh", "STrih", IntRegs>, AddrModeRel;
+ defm storerh: ST_Idxd_shl<"memh", "STrih", IntRegs, 0b010>,
+ ST_Idxd_shl_nv<"memh", "STrih", IntRegs, 0b01>;
let accessSize = WordAccess in
- defm STriw_indexed_shl: ST_Idxd_shl<"memw", "STriw", IntRegs>,
- ST_Idxd_shl_nv<"memw", "STriw", IntRegs>, AddrModeRel;
+ defm storeri: ST_Idxd_shl<"memw", "STriw", IntRegs, 0b100>,
+ ST_Idxd_shl_nv<"memw", "STriw", IntRegs, 0b10>;
let isNVStorable = 0, accessSize = DoubleWordAccess in
- defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel;
+ defm storerd: ST_Idxd_shl<"memd", "STrid", DoubleRegs, 0b110>;
+
+ let isNVStorable = 0, accessSize = HalfWordAccess in
+ defm storerf: ST_Idxd_shl<"memh", "STrif", IntRegs, 0b011, 1>;
}
let Predicates = [HasV4T], AddedComplexity = 10 in {
def : Pat<(truncstorei8 (i32 IntRegs:$src4),
(add IntRegs:$src1, (shl IntRegs:$src2,
u2ImmPred:$src3))),
- (STrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
+ (S4_storerb_rr IntRegs:$src1, IntRegs:$src2,
u2ImmPred:$src3, IntRegs:$src4)>;
def : Pat<(truncstorei16 (i32 IntRegs:$src4),
(add IntRegs:$src1, (shl IntRegs:$src2,
u2ImmPred:$src3))),
- (STrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
+ (S4_storerh_rr IntRegs:$src1, IntRegs:$src2,
u2ImmPred:$src3, IntRegs:$src4)>;
def : Pat<(store (i32 IntRegs:$src4),
(add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
- (STriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
+ (S4_storeri_rr IntRegs:$src1, IntRegs:$src2,
u2ImmPred:$src3, IntRegs:$src4)>;
def : Pat<(store (i64 DoubleRegs:$src4),
(add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
- (STrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
+ (S4_storerd_rr IntRegs:$src1, IntRegs:$src2,
u2ImmPred:$src3, DoubleRegs:$src4)>;
}
@@ -668,74 +914,123 @@ defm : T_ST_LOff_Pats<STrih_shl_V4, IntRegs, i32, truncstorei16>;
// TODO: needs to be implemented.
//===----------------------------------------------------------------------===//
+// Template class
+//===----------------------------------------------------------------------===//
+let isPredicable = 1, isExtendable = 1, isExtentSigned = 1, opExtentBits = 8,
+ opExtendable = 2 in
+class T_StoreImm <string mnemonic, Operand OffsetOp, bits<2> MajOp >
+ : STInst <(outs ), (ins IntRegs:$Rs, OffsetOp:$offset, s8Ext:$S8),
+ mnemonic#"($Rs+#$offset)=#$S8",
+ [], "", V4LDST_tc_st_SLOT01>,
+ ImmRegRel, PredNewRel {
+ bits<5> Rs;
+ bits<8> S8;
+ bits<8> offset;
+ bits<6> offsetBits;
+
+ string OffsetOpStr = !cast<string>(OffsetOp);
+ let offsetBits = !if (!eq(OffsetOpStr, "u6_2Imm"), offset{7-2},
+ !if (!eq(OffsetOpStr, "u6_1Imm"), offset{6-1},
+ /* u6_0Imm */ offset{5-0}));
+
+ let IClass = 0b0011;
+
+ let Inst{27-25} = 0b110;
+ let Inst{22-21} = MajOp;
+ let Inst{20-16} = Rs;
+ let Inst{12-7} = offsetBits;
+ let Inst{13} = S8{7};
+ let Inst{6-0} = S8{6-0};
+ }
+
+let isPredicated = 1, isExtendable = 1, isExtentSigned = 1, opExtentBits = 6,
+ opExtendable = 3 in
+class T_StoreImm_pred <string mnemonic, Operand OffsetOp, bits<2> MajOp,
+ bit isPredNot, bit isPredNew >
+ : STInst <(outs ),
+ (ins PredRegs:$Pv, IntRegs:$Rs, OffsetOp:$offset, s6Ext:$S6),
+ !if(isPredNot, "if (!$Pv", "if ($Pv")#!if(isPredNew, ".new) ",
+ ") ")#mnemonic#"($Rs+#$offset)=#$S6",
+ [], "", V4LDST_tc_st_SLOT01>,
+ ImmRegRel, PredNewRel {
+ bits<2> Pv;
+ bits<5> Rs;
+ bits<6> S6;
+ bits<8> offset;
+ bits<6> offsetBits;
+
+ string OffsetOpStr = !cast<string>(OffsetOp);
+ let offsetBits = !if (!eq(OffsetOpStr, "u6_2Imm"), offset{7-2},
+ !if (!eq(OffsetOpStr, "u6_1Imm"), offset{6-1},
+ /* u6_0Imm */ offset{5-0}));
+ let isPredicatedNew = isPredNew;
+ let isPredicatedFalse = isPredNot;
+
+ let IClass = 0b0011;
+
+ let Inst{27-25} = 0b100;
+ let Inst{24} = isPredNew;
+ let Inst{23} = isPredNot;
+ let Inst{22-21} = MajOp;
+ let Inst{20-16} = Rs;
+ let Inst{13} = S6{5};
+ let Inst{12-7} = offsetBits;
+ let Inst{6-5} = Pv;
+ let Inst{4-0} = S6{4-0};
+ }
+
+
+//===----------------------------------------------------------------------===//
// multiclass for store instructions with base + immediate offset
// addressing mode and immediate stored value.
// mem[bhw](Rx++#s4:3)=#s8
// if ([!]Pv[.new]) mem[bhw](Rx++#s4:3)=#s6
//===----------------------------------------------------------------------===//
-multiclass ST_Imm_Pbase<string mnemonic, Operand OffsetOp, bit isNot,
- bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME : STInst2<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, OffsetOp:$src3, s6Ext:$src4),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#mnemonic#"($src2+#$src3) = #$src4",
- []>,
- Requires<[HasV4T]>;
-}
-multiclass ST_Imm_Pred<string mnemonic, Operand OffsetOp, bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 0>;
- // Predicate new
- defm _cdn#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 1>;
- }
+multiclass ST_Imm_Pred <string mnemonic, Operand OffsetOp, bits<2> MajOp,
+ bit PredNot> {
+ def _io : T_StoreImm_pred <mnemonic, OffsetOp, MajOp, PredNot, 0>;
+ // Predicate new
+ def new_io : T_StoreImm_pred <mnemonic, OffsetOp, MajOp, PredNot, 1>;
}
-let isExtendable = 1, isExtentSigned = 1, neverHasSideEffects = 1 in
-multiclass ST_Imm<string mnemonic, string CextOp, Operand OffsetOp> {
+multiclass ST_Imm <string mnemonic, string CextOp, Operand OffsetOp,
+ bits<2> MajOp> {
let CextOpcode = CextOp, BaseOpcode = CextOp#_imm in {
- let opExtendable = 2, opExtentBits = 8, isPredicable = 1 in
- def NAME#_V4 : STInst2<(outs),
- (ins IntRegs:$src1, OffsetOp:$src2, s8Ext:$src3),
- mnemonic#"($src1+#$src2) = #$src3",
- []>,
- Requires<[HasV4T]>;
+ def _io : T_StoreImm <mnemonic, OffsetOp, MajOp>;
- let opExtendable = 3, opExtentBits = 6, isPredicated = 1 in {
- defm Pt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 0>;
- defm NotPt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 1 >;
- }
+ defm t : ST_Imm_Pred <mnemonic, OffsetOp, MajOp, 0>;
+ defm f : ST_Imm_Pred <mnemonic, OffsetOp, MajOp, 1>;
}
}
-let addrMode = BaseImmOffset, InputType = "imm",
-validSubTargets = HasV4SubT in {
+let hasSideEffects = 0, validSubTargets = HasV4SubT, addrMode = BaseImmOffset,
+ InputType = "imm", isCodeGenOnly = 0 in {
let accessSize = ByteAccess in
- defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel, PredNewRel;
+ defm S4_storeirb : ST_Imm<"memb", "STrib", u6_0Imm, 0b00>;
let accessSize = HalfWordAccess in
- defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel, PredNewRel;
+ defm S4_storeirh : ST_Imm<"memh", "STrih", u6_1Imm, 0b01>;
let accessSize = WordAccess in
- defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel, PredNewRel;
+ defm S4_storeiri : ST_Imm<"memw", "STriw", u6_2Imm, 0b10>;
}
let Predicates = [HasV4T], AddedComplexity = 10 in {
def: Pat<(truncstorei8 s8ExtPred:$src3, (add IntRegs:$src1, u6_0ImmPred:$src2)),
- (STrib_imm_V4 IntRegs:$src1, u6_0ImmPred:$src2, s8ExtPred:$src3)>;
+ (S4_storeirb_io IntRegs:$src1, u6_0ImmPred:$src2, s8ExtPred:$src3)>;
def: Pat<(truncstorei16 s8ExtPred:$src3, (add IntRegs:$src1,
u6_1ImmPred:$src2)),
- (STrih_imm_V4 IntRegs:$src1, u6_1ImmPred:$src2, s8ExtPred:$src3)>;
+ (S4_storeirh_io IntRegs:$src1, u6_1ImmPred:$src2, s8ExtPred:$src3)>;
def: Pat<(store s8ExtPred:$src3, (add IntRegs:$src1, u6_2ImmPred:$src2)),
- (STriw_imm_V4 IntRegs:$src1, u6_2ImmPred:$src2, s8ExtPred:$src3)>;
+ (S4_storeiri_io IntRegs:$src1, u6_2ImmPred:$src2, s8ExtPred:$src3)>;
}
let AddedComplexity = 6 in
def : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)),
- (STrib_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
+ (S4_storeirb_io IntRegs:$src1, 0, s8ExtPred:$src2)>,
Requires<[HasV4T]>;
// memb(Rx++#s4:0:circ(Mu))=Rt
@@ -751,7 +1046,7 @@ def : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)),
// memh(Rs+#s11:1)=Rt.H
let AddedComplexity = 6 in
def : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)),
- (STrih_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
+ (S4_storeirh_io IntRegs:$src1, 0, s8ExtPred:$src2)>,
Requires<[HasV4T]>;
// memh(Rs+Ru<<#u2)=Rt.H
@@ -782,7 +1077,7 @@ def : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)),
// TODO: Needs to be implemented.
// Store predicate:
-let neverHasSideEffects = 1 in
+let hasSideEffects = 0 in
def STriw_pred_V4 : STInst2<(outs),
(ins MEMri:$addr, PredRegs:$src1),
"Error; should not emit",
@@ -791,7 +1086,7 @@ def STriw_pred_V4 : STInst2<(outs),
let AddedComplexity = 6 in
def : Pat <(store s8ExtPred:$src2, (i32 IntRegs:$src1)),
- (STriw_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
+ (S4_storeiri_io IntRegs:$src1, 0, s8ExtPred:$src2)>,
Requires<[HasV4T]>;
// memw(Rx++#s4:2)=Rt
@@ -809,170 +1104,249 @@ def : Pat <(store s8ExtPred:$src2, (i32 IntRegs:$src1)),
// NV/ST +
//===----------------------------------------------------------------------===//
-// multiclass for new-value store instructions with base + immediate offset.
-//
-multiclass ST_Idxd_Pbase_nv<string mnemonic, RegisterClass RC,
- Operand predImmOp, bit isNot, bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME#_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#mnemonic#"($src2+#$src3) = $src4.new",
- []>,
- Requires<[HasV4T]>;
-}
+let opNewValue = 2, opExtendable = 1, isExtentSigned = 1, isPredicable = 1 in
+class T_store_io_nv <string mnemonic, RegisterClass RC,
+ Operand ImmOp, bits<2>MajOp>
+ : NVInst_V4 <(outs),
+ (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
+ mnemonic#"($src1+#$src2) = $src3.new",
+ [],"",ST_tc_st_SLOT0> {
+ bits<5> src1;
+ bits<13> src2; // Actual address offset
+ bits<3> src3;
+ bits<11> offsetBits; // Represents offset encoding
+
+ let opExtentBits = !if (!eq(mnemonic, "memb"), 11,
+ !if (!eq(mnemonic, "memh"), 12,
+ !if (!eq(mnemonic, "memw"), 13, 0)));
+
+ let opExtentAlign = !if (!eq(mnemonic, "memb"), 0,
+ !if (!eq(mnemonic, "memh"), 1,
+ !if (!eq(mnemonic, "memw"), 2, 0)));
+
+ let offsetBits = !if (!eq(mnemonic, "memb"), src2{10-0},
+ !if (!eq(mnemonic, "memh"), src2{11-1},
+ !if (!eq(mnemonic, "memw"), src2{12-2}, 0)));
+
+ let IClass = 0b1010;
+
+ let Inst{27} = 0b0;
+ let Inst{26-25} = offsetBits{10-9};
+ let Inst{24-21} = 0b1101;
+ let Inst{20-16} = src1;
+ let Inst{13} = offsetBits{8};
+ let Inst{12-11} = MajOp;
+ let Inst{10-8} = src3;
+ let Inst{7-0} = offsetBits{7-0};
+ }
-multiclass ST_Idxd_Pred_nv<string mnemonic, RegisterClass RC, Operand predImmOp,
- bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 0>;
- // Predicate new
- defm _cdn#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 1>;
+let opExtendable = 2, opNewValue = 3, isPredicated = 1 in
+class T_pstore_io_nv <string mnemonic, RegisterClass RC, Operand predImmOp,
+ bits<2>MajOp, bit PredNot, bit isPredNew>
+ : NVInst_V4 <(outs),
+ (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC:$src4),
+ !if(PredNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#mnemonic#"($src2+#$src3) = $src4.new",
+ [],"",V2LDST_tc_st_SLOT0> {
+ bits<2> src1;
+ bits<5> src2;
+ bits<9> src3;
+ bits<3> src4;
+ bits<6> offsetBits; // Represents offset encoding
+
+ let isPredicatedNew = isPredNew;
+ let isPredicatedFalse = PredNot;
+ let opExtentBits = !if (!eq(mnemonic, "memb"), 6,
+ !if (!eq(mnemonic, "memh"), 7,
+ !if (!eq(mnemonic, "memw"), 8, 0)));
+
+ let opExtentAlign = !if (!eq(mnemonic, "memb"), 0,
+ !if (!eq(mnemonic, "memh"), 1,
+ !if (!eq(mnemonic, "memw"), 2, 0)));
+
+ let offsetBits = !if (!eq(mnemonic, "memb"), src3{5-0},
+ !if (!eq(mnemonic, "memh"), src3{6-1},
+ !if (!eq(mnemonic, "memw"), src3{7-2}, 0)));
+
+ let IClass = 0b0100;
+
+ let Inst{27} = 0b0;
+ let Inst{26} = PredNot;
+ let Inst{25} = isPredNew;
+ let Inst{24-21} = 0b0101;
+ let Inst{20-16} = src2;
+ let Inst{13} = offsetBits{5};
+ let Inst{12-11} = MajOp;
+ let Inst{10-8} = src4;
+ let Inst{7-3} = offsetBits{4-0};
+ let Inst{2} = 0b0;
+ let Inst{1-0} = src1;
}
-}
-let mayStore = 1, isNVStore = 1, neverHasSideEffects = 1, isExtendable = 1 in
+// multiclass for new-value store instructions with base + immediate offset.
+//
+let mayStore = 1, isNVStore = 1, isNewValue = 1, hasSideEffects = 0,
+ isExtendable = 1 in
multiclass ST_Idxd_nv<string mnemonic, string CextOp, RegisterClass RC,
- Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
- bits<5> PredImmBits> {
+ Operand ImmOp, Operand predImmOp, bits<2> MajOp> {
let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
- let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
- isPredicable = 1 in
- def NAME#_nv_V4 : NVInst_V4<(outs),
- (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
- mnemonic#"($src1+#$src2) = $src3.new",
- []>,
- Requires<[HasV4T]>;
-
- let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
- isPredicated = 1 in {
- defm Pt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 0>;
- defm NotPt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 1>;
- }
+ def S2_#NAME#new_io : T_store_io_nv <mnemonic, RC, ImmOp, MajOp>;
+ // Predicated
+ def S2_p#NAME#newt_io :T_pstore_io_nv <mnemonic, RC, predImmOp, MajOp, 0, 0>;
+ def S2_p#NAME#newf_io :T_pstore_io_nv <mnemonic, RC, predImmOp, MajOp, 1, 0>;
+ // Predicated new
+ def S4_p#NAME#newtnew_io :T_pstore_io_nv <mnemonic, RC, predImmOp,
+ MajOp, 0, 1>;
+ def S4_p#NAME#newfnew_io :T_pstore_io_nv <mnemonic, RC, predImmOp,
+ MajOp, 1, 1>;
}
}
-let addrMode = BaseImmOffset, validSubTargets = HasV4SubT in {
+let addrMode = BaseImmOffset, InputType = "imm", isCodeGenOnly = 0 in {
let accessSize = ByteAccess in
- defm STrib_indexed: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext,
- u6_0Ext, 11, 6>, AddrModeRel;
+ defm storerb: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext,
+ u6_0Ext, 0b00>, AddrModeRel;
- let accessSize = HalfWordAccess in
- defm STrih_indexed: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext,
- u6_1Ext, 12, 7>, AddrModeRel;
+ let accessSize = HalfWordAccess, opExtentAlign = 1 in
+ defm storerh: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext,
+ u6_1Ext, 0b01>, AddrModeRel;
- let accessSize = WordAccess in
- defm STriw_indexed: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext,
- u6_2Ext, 13, 8>, AddrModeRel;
+ let accessSize = WordAccess, opExtentAlign = 2 in
+ defm storeri: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext,
+ u6_2Ext, 0b10>, AddrModeRel;
}
-// multiclass for new-value store instructions with base + immediate offset.
-// and MEMri operand.
-multiclass ST_MEMri_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
- bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME#_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, MEMri:$addr, RC: $src2),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#mnemonic#"($addr) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-}
-
-multiclass ST_MEMri_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 0>;
+//===----------------------------------------------------------------------===//
+// Template class for non-predicated post increment .new stores
+// mem[bhwd](Rx++#s4:[0123])=Nt.new
+//===----------------------------------------------------------------------===//
+let isPredicable = 1, hasSideEffects = 0, validSubTargets = HasV4SubT,
+ addrMode = PostInc, isNVStore = 1, isNewValue = 1, opNewValue = 3 in
+class T_StorePI_nv <string mnemonic, Operand ImmOp, bits<2> MajOp >
+ : NVInstPI_V4 <(outs IntRegs:$_dst_),
+ (ins IntRegs:$src1, ImmOp:$offset, IntRegs:$src2),
+ mnemonic#"($src1++#$offset) = $src2.new",
+ [], "$src1 = $_dst_">,
+ AddrModeRel {
+ bits<5> src1;
+ bits<3> src2;
+ bits<7> offset;
+ bits<4> offsetBits;
+
+ string ImmOpStr = !cast<string>(ImmOp);
+ let offsetBits = !if (!eq(ImmOpStr, "s4_2Imm"), offset{5-2},
+ !if (!eq(ImmOpStr, "s4_1Imm"), offset{4-1},
+ /* s4_0Imm */ offset{3-0}));
+ let IClass = 0b1010;
+
+ let Inst{27-21} = 0b1011101;
+ let Inst{20-16} = src1;
+ let Inst{13} = 0b0;
+ let Inst{12-11} = MajOp;
+ let Inst{10-8} = src2;
+ let Inst{7} = 0b0;
+ let Inst{6-3} = offsetBits;
+ let Inst{1} = 0b0;
+ }
- // Predicate new
- defm _cdn#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 1>;
+//===----------------------------------------------------------------------===//
+// Template class for predicated post increment .new stores
+// if([!]Pv[.new]) mem[bhwd](Rx++#s4:[0123])=Nt.new
+//===----------------------------------------------------------------------===//
+let isPredicated = 1, hasSideEffects = 0, validSubTargets = HasV4SubT,
+ addrMode = PostInc, isNVStore = 1, isNewValue = 1, opNewValue = 4 in
+class T_StorePI_nv_pred <string mnemonic, Operand ImmOp,
+ bits<2> MajOp, bit isPredNot, bit isPredNew >
+ : NVInstPI_V4 <(outs IntRegs:$_dst_),
+ (ins PredRegs:$src1, IntRegs:$src2,
+ ImmOp:$offset, IntRegs:$src3),
+ !if(isPredNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#mnemonic#"($src2++#$offset) = $src3.new",
+ [], "$src2 = $_dst_">,
+ AddrModeRel {
+ bits<2> src1;
+ bits<5> src2;
+ bits<3> src3;
+ bits<7> offset;
+ bits<4> offsetBits;
+
+ string ImmOpStr = !cast<string>(ImmOp);
+ let offsetBits = !if (!eq(ImmOpStr, "s4_2Imm"), offset{5-2},
+ !if (!eq(ImmOpStr, "s4_1Imm"), offset{4-1},
+ /* s4_0Imm */ offset{3-0}));
+ let isPredicatedNew = isPredNew;
+ let isPredicatedFalse = isPredNot;
+
+ let IClass = 0b1010;
+
+ let Inst{27-21} = 0b1011101;
+ let Inst{20-16} = src2;
+ let Inst{13} = 0b1;
+ let Inst{12-11} = MajOp;
+ let Inst{10-8} = src3;
+ let Inst{7} = isPredNew;
+ let Inst{6-3} = offsetBits;
+ let Inst{2} = isPredNot;
+ let Inst{1-0} = src1;
}
-}
-let mayStore = 1, isNVStore = 1, isExtendable = 1, neverHasSideEffects = 1 in
-multiclass ST_MEMri_nv<string mnemonic, string CextOp, RegisterClass RC,
- bits<5> ImmBits, bits<5> PredImmBits> {
+multiclass ST_PostInc_Pred_nv<string mnemonic, Operand ImmOp,
+ bits<2> MajOp, bit PredNot> {
+ def _pi : T_StorePI_nv_pred <mnemonic, ImmOp, MajOp, PredNot, 0>;
- let CextOpcode = CextOp, BaseOpcode = CextOp in {
- let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
- isPredicable = 1 in
- def NAME#_nv_V4 : NVInst_V4<(outs),
- (ins MEMri:$addr, RC:$src),
- mnemonic#"($addr) = $src.new",
- []>,
- Requires<[HasV4T]>;
+ // Predicate new
+ def new_pi : T_StorePI_nv_pred <mnemonic, ImmOp, MajOp, PredNot, 1>;
+}
- let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
- neverHasSideEffects = 1, isPredicated = 1 in {
- defm Pt : ST_MEMri_Pred_nv<mnemonic, RC, 0>;
- defm NotPt : ST_MEMri_Pred_nv<mnemonic, RC, 1>;
- }
+multiclass ST_PostInc_nv<string mnemonic, string BaseOp, Operand ImmOp,
+ bits<2> MajOp> {
+ let BaseOpcode = "POST_"#BaseOp in {
+ def S2_#NAME#_pi : T_StorePI_nv <mnemonic, ImmOp, MajOp>;
+
+ // Predicated
+ defm S2_p#NAME#t : ST_PostInc_Pred_nv <mnemonic, ImmOp, MajOp, 0>;
+ defm S2_p#NAME#f : ST_PostInc_Pred_nv <mnemonic, ImmOp, MajOp, 1>;
}
}
-let addrMode = BaseImmOffset, isMEMri = "true", validSubTargets = HasV4SubT,
-mayStore = 1 in {
- let accessSize = ByteAccess in
- defm STrib: ST_MEMri_nv<"memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
+let accessSize = ByteAccess, isCodeGenOnly = 0 in
+defm storerbnew: ST_PostInc_nv <"memb", "STrib", s4_0Imm, 0b00>;
- let accessSize = HalfWordAccess in
- defm STrih: ST_MEMri_nv<"memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
+let accessSize = HalfWordAccess, isCodeGenOnly = 0 in
+defm storerhnew: ST_PostInc_nv <"memh", "STrih", s4_1Imm, 0b01>;
- let accessSize = WordAccess in
- defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
-}
+let accessSize = WordAccess, isCodeGenOnly = 0 in
+defm storerinew: ST_PostInc_nv <"memw", "STriw", s4_2Imm, 0b10>;
//===----------------------------------------------------------------------===//
-// Post increment store
-// mem[bhwd](Rx++#s4:[0123])=Nt.new
+// Template class for post increment .new stores with register offset
//===----------------------------------------------------------------------===//
-
-multiclass ST_PostInc_Pbase_nv<string mnemonic, RegisterClass RC, Operand ImmOp,
- bit isNot, bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
- (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#mnemonic#"($src2++#$offset) = $src3.new",
- [],
- "$src2 = $dst">,
- Requires<[HasV4T]>;
-}
-
-multiclass ST_PostInc_Pred_nv<string mnemonic, RegisterClass RC,
- Operand ImmOp, bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 0>;
- // Predicate new
- let Predicates = [HasV4T], validSubTargets = HasV4SubT in
- defm _cdn#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 1>;
- }
-}
-
-let hasCtrlDep = 1, isNVStore = 1, neverHasSideEffects = 1 in
-multiclass ST_PostInc_nv<string mnemonic, string BaseOp, RegisterClass RC,
- Operand ImmOp> {
-
- let BaseOpcode = "POST_"#BaseOp in {
- let isPredicable = 1 in
- def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
- (ins IntRegs:$src1, ImmOp:$offset, RC:$src2),
- mnemonic#"($src1++#$offset) = $src2.new",
- [],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
-
- let isPredicated = 1 in {
- defm Pt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 0 >;
- defm NotPt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 1 >;
- }
+let isNewValue = 1, mayStore = 1, isNVStore = 1, opNewValue = 3 in
+class T_StorePI_RegNV <string mnemonic, bits<2> MajOp, MemAccessSize AccessSz>
+ : NVInstPI_V4 <(outs IntRegs:$_dst_),
+ (ins IntRegs:$src1, ModRegs:$src2, IntRegs:$src3),
+ #mnemonic#"($src1++$src2) = $src3.new",
+ [], "$src1 = $_dst_"> {
+ bits<5> src1;
+ bits<1> src2;
+ bits<3> src3;
+ let accessSize = AccessSz;
+
+ let IClass = 0b1010;
+
+ let Inst{27-21} = 0b1101101;
+ let Inst{20-16} = src1;
+ let Inst{13} = src2;
+ let Inst{12-11} = MajOp;
+ let Inst{10-8} = src3;
+ let Inst{7} = 0b0;
}
-}
-let addrMode = PostInc, validSubTargets = HasV4SubT in {
-defm POST_STbri: ST_PostInc_nv <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel;
-defm POST_SThri: ST_PostInc_nv <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel;
-defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
+let isCodeGenOnly = 0 in {
+def S2_storerbnew_pr : T_StorePI_RegNV<"memb", 0b00, ByteAccess>;
+def S2_storerhnew_pr : T_StorePI_RegNV<"memh", 0b01, HalfWordAccess>;
+def S2_storerinew_pr : T_StorePI_RegNV<"memw", 0b10, WordAccess>;
}
// memb(Rx++#s4:0:circ(Mu))=Nt.new
@@ -1002,7 +1376,8 @@ defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
// operands.
//===----------------------------------------------------------------------===//
-let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in
+let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11,
+ opExtentAlign = 2 in
class NVJrr_template<string mnemonic, bits<3> majOp, bit NvOpNum,
bit isNegCond, bit isTak>
: NVInst_V4<(outs),
@@ -1010,8 +1385,7 @@ class NVJrr_template<string mnemonic, bits<3> majOp, bit NvOpNum,
"if ("#!if(isNegCond, "!","")#mnemonic#
"($src1"#!if(!eq(NvOpNum, 0),".new, ",", ")#
"$src2"#!if(!eq(NvOpNum, 1),".new))","))")#" jump:"
- #!if(isTak, "t","nt")#" $offset",
- []>, Requires<[HasV4T]> {
+ #!if(isTak, "t","nt")#" $offset", []> {
bits<5> src1;
bits<5> src2;
@@ -1020,8 +1394,8 @@ class NVJrr_template<string mnemonic, bits<3> majOp, bit NvOpNum,
bits<11> offset;
let isTaken = isTak;
- let isBrTaken = !if(isTaken, "true", "false");
let isPredicatedFalse = isNegCond;
+ let opNewValue{0} = NvOpNum;
let Ns = !if(!eq(NvOpNum, 0), src1{2-0}, src2{2-0});
let RegOp = !if(!eq(NvOpNum, 0), src2, src1);
@@ -1064,7 +1438,8 @@ multiclass NVJrr_base<string mnemonic, string BaseOp, bits<3> majOp,
// if ([!]cmp.gtu(Rt,Ns.new)) jump:[n]t #r9:2
let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1,
- Defs = [PC], neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
+ Defs = [PC], hasSideEffects = 0, validSubTargets = HasV4SubT,
+ isCodeGenOnly = 0 in {
defm CMPEQrr : NVJrr_base<"cmp.eq", "CMPEQ", 0b000, 0>, PredRel;
defm CMPGTrr : NVJrr_base<"cmp.gt", "CMPGT", 0b001, 0>, PredRel;
defm CMPGTUrr : NVJrr_base<"cmp.gtu", "CMPGTU", 0b010, 0>, PredRel;
@@ -1077,18 +1452,18 @@ let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1,
// with a register and an unsigned immediate (U5) operand.
//===----------------------------------------------------------------------===//
-let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in
+let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11,
+ opExtentAlign = 2 in
class NVJri_template<string mnemonic, bits<3> majOp, bit isNegCond,
bit isTak>
: NVInst_V4<(outs),
(ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
"if ("#!if(isNegCond, "!","")#mnemonic#"($src1.new, #$src2)) jump:"
- #!if(isTak, "t","nt")#" $offset",
- []>, Requires<[HasV4T]> {
+ #!if(isTak, "t","nt")#" $offset", []> {
let isTaken = isTak;
let isPredicatedFalse = isNegCond;
- let isBrTaken = !if(isTaken, "true", "false");
+ let isTaken = isTak;
bits<3> src1;
bits<5> src2;
@@ -1124,7 +1499,8 @@ multiclass NVJri_base<string mnemonic, string BaseOp, bits<3> majOp> {
// if ([!]cmp.gtu(Ns.new,#U5)) jump:[n]t #r9:2
let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1,
- Defs = [PC], neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
+ Defs = [PC], hasSideEffects = 0, validSubTargets = HasV4SubT,
+ isCodeGenOnly = 0 in {
defm CMPEQri : NVJri_base<"cmp.eq", "CMPEQ", 0b000>, PredRel;
defm CMPGTri : NVJri_base<"cmp.gt", "CMPGT", 0b001>, PredRel;
defm CMPGTUri : NVJri_base<"cmp.gtu", "CMPGTU", 0b010>, PredRel;
@@ -1135,19 +1511,19 @@ let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1,
// with a register and an hardcoded 0/-1 immediate value.
//===----------------------------------------------------------------------===//
-let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 11 in
+let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 11,
+ opExtentAlign = 2 in
class NVJ_ConstImm_template<string mnemonic, bits<3> majOp, string ImmVal,
bit isNegCond, bit isTak>
: NVInst_V4<(outs),
(ins IntRegs:$src1, brtarget:$offset),
"if ("#!if(isNegCond, "!","")#mnemonic
#"($src1.new, #"#ImmVal#")) jump:"
- #!if(isTak, "t","nt")#" $offset",
- []>, Requires<[HasV4T]> {
+ #!if(isTak, "t","nt")#" $offset", []> {
let isTaken = isTak;
let isPredicatedFalse = isNegCond;
- let isBrTaken = !if(isTaken, "true", "false");
+ let isTaken = isTak;
bits<3> src1;
bits<11> offset;
@@ -1172,8 +1548,8 @@ multiclass NVJ_ConstImm_cond<string mnemonic, bits<3> majOp, string ImmVal,
multiclass NVJ_ConstImm_base<string mnemonic, string BaseOp, bits<3> majOp,
string ImmVal> {
let BaseOpcode = BaseOp#_NVJ_ConstImm in {
- defm _t_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 0>; // True cond
- defm _f_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 1>; // False Cond
+ defm _t_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 0>; // True
+ defm _f_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 1>; // False
}
}
@@ -1182,266 +1558,328 @@ multiclass NVJ_ConstImm_base<string mnemonic, string BaseOp, bits<3> majOp,
// if ([!]cmp.gt(Ns.new,#-1)) jump:[n]t #r9:2
let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator=1,
- Defs = [PC], neverHasSideEffects = 1 in {
+ Defs = [PC], hasSideEffects = 0, isCodeGenOnly = 0 in {
defm TSTBIT0 : NVJ_ConstImm_base<"tstbit", "TSTBIT", 0b011, "0">, PredRel;
defm CMPEQn1 : NVJ_ConstImm_base<"cmp.eq", "CMPEQ", 0b100, "-1">, PredRel;
defm CMPGTn1 : NVJ_ConstImm_base<"cmp.gt", "CMPGT", 0b101, "-1">, PredRel;
}
+// J4_hintjumpr: Hint indirect conditional jump.
+let isBranch = 1, isIndirectBranch = 1, hasSideEffects = 0, isCodeGenOnly = 0 in
+def J4_hintjumpr: JRInst <
+ (outs),
+ (ins IntRegs:$Rs),
+ "hintjr($Rs)"> {
+ bits<5> Rs;
+ let IClass = 0b0101;
+ let Inst{27-21} = 0b0010101;
+ let Inst{20-16} = Rs;
+ }
+
//===----------------------------------------------------------------------===//
-// XTYPE/ALU +
+// NV/J -
//===----------------------------------------------------------------------===//
-// Add and accumulate.
-// Rd=add(Rs,add(Ru,#s6))
-let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 6,
-validSubTargets = HasV4SubT in
-def ADDr_ADDri_V4 : MInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2, s6Ext:$src3),
- "$dst = add($src1, add($src2, #$src3))",
- [(set (i32 IntRegs:$dst),
- (add (i32 IntRegs:$src1), (add (i32 IntRegs:$src2),
- s6_16ExtPred:$src3)))]>,
- Requires<[HasV4T]>;
+//===----------------------------------------------------------------------===//
+// CR +
+//===----------------------------------------------------------------------===//
-// Rd=add(Rs,sub(#s6,Ru))
-let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
-validSubTargets = HasV4SubT in
-def ADDr_SUBri_V4 : MInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
- "$dst = add($src1, sub(#$src2, $src3))",
- [(set (i32 IntRegs:$dst),
- (add (i32 IntRegs:$src1), (sub s6_10ExtPred:$src2,
- (i32 IntRegs:$src3))))]>,
- Requires<[HasV4T]>;
+// PC-relative add
+let hasNewValue = 1, isExtendable = 1, opExtendable = 1,
+ isExtentSigned = 0, opExtentBits = 6, hasSideEffects = 0,
+ Uses = [PC], validSubTargets = HasV4SubT in
+def C4_addipc : CRInst <(outs IntRegs:$Rd), (ins u6Ext:$u6),
+ "$Rd = add(pc, #$u6)", [], "", CR_tc_2_SLOT3 > {
+ bits<5> Rd;
+ bits<6> u6;
+
+ let IClass = 0b0110;
+ let Inst{27-16} = 0b101001001001;
+ let Inst{12-7} = u6;
+ let Inst{4-0} = Rd;
+ }
-// Generates the same instruction as ADDr_SUBri_V4 but matches different
-// pattern.
-// Rd=add(Rs,sub(#s6,Ru))
-let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
-validSubTargets = HasV4SubT in
-def ADDri_SUBr_V4 : MInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
- "$dst = add($src1, sub(#$src2, $src3))",
- [(set (i32 IntRegs:$dst),
- (sub (add (i32 IntRegs:$src1), s6_10ExtPred:$src2),
- (i32 IntRegs:$src3)))]>,
- Requires<[HasV4T]>;
-// Add or subtract doublewords with carry.
-//TODO:
-// Rdd=add(Rss,Rtt,Px):carry
-//TODO:
-// Rdd=sub(Rss,Rtt,Px):carry
+let hasSideEffects = 0 in
+class T_LOGICAL_3OP<string MnOp1, string MnOp2, bits<2> OpBits, bit IsNeg>
+ : CRInst<(outs PredRegs:$Pd),
+ (ins PredRegs:$Ps, PredRegs:$Pt, PredRegs:$Pu),
+ "$Pd = " # MnOp1 # "($Ps, " # MnOp2 # "($Pt, " #
+ !if (IsNeg,"!","") # "$Pu))",
+ [], "", CR_tc_2early_SLOT23> {
+ bits<2> Pd;
+ bits<2> Ps;
+ bits<2> Pt;
+ bits<2> Pu;
+
+ let IClass = 0b0110;
+ let Inst{27-24} = 0b1011;
+ let Inst{23} = IsNeg;
+ let Inst{22-21} = OpBits;
+ let Inst{20} = 0b1;
+ let Inst{17-16} = Ps;
+ let Inst{13} = 0b0;
+ let Inst{9-8} = Pt;
+ let Inst{7-6} = Pu;
+ let Inst{1-0} = Pd;
+}
+let isCodeGenOnly = 0 in {
+def C4_and_and : T_LOGICAL_3OP<"and", "and", 0b00, 0>;
+def C4_and_or : T_LOGICAL_3OP<"and", "or", 0b01, 0>;
+def C4_or_and : T_LOGICAL_3OP<"or", "and", 0b10, 0>;
+def C4_or_or : T_LOGICAL_3OP<"or", "or", 0b11, 0>;
+def C4_and_andn : T_LOGICAL_3OP<"and", "and", 0b00, 1>;
+def C4_and_orn : T_LOGICAL_3OP<"and", "or", 0b01, 1>;
+def C4_or_andn : T_LOGICAL_3OP<"or", "and", 0b10, 1>;
+def C4_or_orn : T_LOGICAL_3OP<"or", "or", 0b11, 1>;
+}
-// Logical doublewords.
-// Rdd=and(Rtt,~Rss)
-let validSubTargets = HasV4SubT in
-def ANDd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1, DoubleRegs:$src2),
- "$dst = and($src1, ~$src2)",
- [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1),
- (not (i64 DoubleRegs:$src2))))]>,
- Requires<[HasV4T]>;
+//===----------------------------------------------------------------------===//
+// CR -
+//===----------------------------------------------------------------------===//
-// Rdd=or(Rtt,~Rss)
-let validSubTargets = HasV4SubT in
-def ORd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1, DoubleRegs:$src2),
- "$dst = or($src1, ~$src2)",
- [(set (i64 DoubleRegs:$dst),
- (or (i64 DoubleRegs:$src1), (not (i64 DoubleRegs:$src2))))]>,
- Requires<[HasV4T]>;
+//===----------------------------------------------------------------------===//
+// XTYPE/ALU +
+//===----------------------------------------------------------------------===//
+// Logical with-not instructions.
+let validSubTargets = HasV4SubT, isCodeGenOnly = 0 in {
+ def A4_andnp : T_ALU64_logical<"and", 0b001, 1, 0, 1>;
+ def A4_ornp : T_ALU64_logical<"or", 0b011, 1, 0, 1>;
+}
-// Logical-logical doublewords.
-// Rxx^=xor(Rss,Rtt)
-let validSubTargets = HasV4SubT in
-def XORd_XORdd: MInst_acc<(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3),
- "$dst ^= xor($src2, $src3)",
- [(set (i64 DoubleRegs:$dst),
- (xor (i64 DoubleRegs:$src1), (xor (i64 DoubleRegs:$src2),
- (i64 DoubleRegs:$src3))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
+let hasNewValue = 1, hasSideEffects = 0, isCodeGenOnly = 0 in
+def S4_parity: ALU64Inst<(outs IntRegs:$Rd), (ins IntRegs:$Rs, IntRegs:$Rt),
+ "$Rd = parity($Rs, $Rt)", [], "", ALU64_tc_2_SLOT23> {
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1101;
+ let Inst{27-21} = 0b0101111;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ let Inst{4-0} = Rd;
+}
+// Add and accumulate.
+// Rd=add(Rs,add(Ru,#s6))
+let isExtentSigned = 1, hasNewValue = 1, isExtendable = 1, opExtentBits = 6,
+ opExtendable = 3, isCodeGenOnly = 0 in
+def S4_addaddi : ALU64Inst <(outs IntRegs:$Rd),
+ (ins IntRegs:$Rs, IntRegs:$Ru, s6Ext:$s6),
+ "$Rd = add($Rs, add($Ru, #$s6))" ,
+ [(set (i32 IntRegs:$Rd), (add (i32 IntRegs:$Rs),
+ (add (i32 IntRegs:$Ru), s6_16ExtPred:$s6)))],
+ "", ALU64_tc_2_SLOT23> {
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<5> Ru;
+ bits<6> s6;
+
+ let IClass = 0b1101;
+
+ let Inst{27-23} = 0b10110;
+ let Inst{22-21} = s6{5-4};
+ let Inst{20-16} = Rs;
+ let Inst{13} = s6{3};
+ let Inst{12-8} = Rd;
+ let Inst{7-5} = s6{2-0};
+ let Inst{4-0} = Ru;
+ }
+let isExtentSigned = 1, hasSideEffects = 0, hasNewValue = 1, isExtendable = 1,
+ opExtentBits = 6, opExtendable = 2, isCodeGenOnly = 0 in
+def S4_subaddi: ALU64Inst <(outs IntRegs:$Rd),
+ (ins IntRegs:$Rs, s6Ext:$s6, IntRegs:$Ru),
+ "$Rd = add($Rs, sub(#$s6, $Ru))",
+ [], "", ALU64_tc_2_SLOT23> {
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<6> s6;
+ bits<5> Ru;
+
+ let IClass = 0b1101;
+
+ let Inst{27-23} = 0b10111;
+ let Inst{22-21} = s6{5-4};
+ let Inst{20-16} = Rs;
+ let Inst{13} = s6{3};
+ let Inst{12-8} = Rd;
+ let Inst{7-5} = s6{2-0};
+ let Inst{4-0} = Ru;
+ }
+
+// Extract bitfield
+// Rdd=extract(Rss,#u6,#U6)
+// Rdd=extract(Rss,Rtt)
+// Rd=extract(Rs,Rtt)
+// Rd=extract(Rs,#u5,#U5)
+
+let isCodeGenOnly = 0 in {
+def S4_extractp_rp : T_S3op_64 < "extract", 0b11, 0b100, 0>;
+def S4_extractp : T_S2op_extract <"extract", 0b1010, DoubleRegs, u6Imm>;
+}
-// Logical-logical words.
-// Rx=or(Ru,and(Rx,#s10))
-let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
-validSubTargets = HasV4SubT in
-def ORr_ANDri_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
- "$dst = or($src1, and($src2, #$src3))",
- [(set (i32 IntRegs:$dst),
- (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
- s10ExtPred:$src3)))],
- "$src2 = $dst">,
- Requires<[HasV4T]>;
+let hasNewValue = 1, isCodeGenOnly = 0 in {
+ def S4_extract_rp : T_S3op_extract<"extract", 0b01>;
+ def S4_extract : T_S2op_extract <"extract", 0b1101, IntRegs, u5Imm>;
+}
-// Rx[&|^]=and(Rs,Rt)
-// Rx&=and(Rs,Rt)
-let validSubTargets = HasV4SubT in
-def ANDr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
- "$dst &= and($src2, $src3)",
- [(set (i32 IntRegs:$dst),
- (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
+let Itinerary = M_tc_3x_SLOT23, Defs = [USR_OVF], isCodeGenOnly = 0 in {
+ def M4_mac_up_s1_sat: T_MType_acc_rr<"+= mpy", 0b011, 0b000, 0, [], 0, 1, 1>;
+ def M4_nac_up_s1_sat: T_MType_acc_rr<"-= mpy", 0b011, 0b001, 0, [], 0, 1, 1>;
+}
-// Rx|=and(Rs,Rt)
-let validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "reg" in
-def ORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
- "$dst |= and($src2, $src3)",
- [(set (i32 IntRegs:$dst),
- (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>, ImmRegRel;
+// Logical xor with xor accumulation.
+// Rxx^=xor(Rss,Rtt)
+let hasSideEffects = 0, isCodeGenOnly = 0 in
+def M4_xor_xacc
+ : SInst <(outs DoubleRegs:$Rxx),
+ (ins DoubleRegs:$dst2, DoubleRegs:$Rss, DoubleRegs:$Rtt),
+ "$Rxx ^= xor($Rss, $Rtt)",
+ [(set (i64 DoubleRegs:$Rxx),
+ (xor (i64 DoubleRegs:$dst2), (xor (i64 DoubleRegs:$Rss),
+ (i64 DoubleRegs:$Rtt))))],
+ "$dst2 = $Rxx", S_3op_tc_1_SLOT23> {
+ bits<5> Rxx;
+ bits<5> Rss;
+ bits<5> Rtt;
+
+ let IClass = 0b1100;
+
+ let Inst{27-23} = 0b10101;
+ let Inst{20-16} = Rss;
+ let Inst{12-8} = Rtt;
+ let Inst{4-0} = Rxx;
+ }
+
+// Split bitfield
+let isCodeGenOnly = 0 in
+def A4_bitspliti : T_S2op_2_di <"bitsplit", 0b110, 0b100>;
-// Rx^=and(Rs,Rt)
-let validSubTargets = HasV4SubT in
-def XORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
- "$dst ^= and($src2, $src3)",
- [(set (i32 IntRegs:$dst),
- (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
+// Arithmetic/Convergent round
+let isCodeGenOnly = 0 in
+def A4_cround_ri : T_S2op_2_ii <"cround", 0b111, 0b000>;
-// Rx[&|^]=and(Rs,~Rt)
-// Rx&=and(Rs,~Rt)
-let validSubTargets = HasV4SubT in
-def ANDr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
- "$dst &= and($src2, ~$src3)",
- [(set (i32 IntRegs:$dst),
- (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
- (not (i32 IntRegs:$src3)))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
+let isCodeGenOnly = 0 in
+def A4_round_ri : T_S2op_2_ii <"round", 0b111, 0b100>;
-// Rx|=and(Rs,~Rt)
-let validSubTargets = HasV4SubT in
-def ORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
- "$dst |= and($src2, ~$src3)",
- [(set (i32 IntRegs:$dst),
- (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
- (not (i32 IntRegs:$src3)))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
+let Defs = [USR_OVF], isCodeGenOnly = 0 in
+def A4_round_ri_sat : T_S2op_2_ii <"round", 0b111, 0b110, 1>;
-// Rx^=and(Rs,~Rt)
-let validSubTargets = HasV4SubT in
-def XORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
- "$dst ^= and($src2, ~$src3)",
- [(set (i32 IntRegs:$dst),
- (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
- (not (i32 IntRegs:$src3)))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
+// Logical-logical words.
+// Compound or-and -- Rx=or(Ru,and(Rx,#s10))
+let isExtentSigned = 1, hasNewValue = 1, isExtendable = 1, opExtentBits = 10,
+ opExtendable = 3, isCodeGenOnly = 0 in
+def S4_or_andix:
+ ALU64Inst<(outs IntRegs:$Rx),
+ (ins IntRegs:$Ru, IntRegs:$_src_, s10Ext:$s10),
+ "$Rx = or($Ru, and($_src_, #$s10))" ,
+ [(set (i32 IntRegs:$Rx),
+ (or (i32 IntRegs:$Ru), (and (i32 IntRegs:$_src_), s10ExtPred:$s10)))] ,
+ "$_src_ = $Rx", ALU64_tc_2_SLOT23> {
+ bits<5> Rx;
+ bits<5> Ru;
+ bits<10> s10;
+
+ let IClass = 0b1101;
+
+ let Inst{27-22} = 0b101001;
+ let Inst{20-16} = Rx;
+ let Inst{21} = s10{9};
+ let Inst{13-5} = s10{8-0};
+ let Inst{4-0} = Ru;
+ }
-// Rx[&|^]=or(Rs,Rt)
-// Rx&=or(Rs,Rt)
-let validSubTargets = HasV4SubT in
-def ANDr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
- "$dst &= or($src2, $src3)",
- [(set (i32 IntRegs:$dst),
- (and (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
+// Miscellaneous ALU64 instructions.
+//
+let hasNewValue = 1, hasSideEffects = 0, isCodeGenOnly = 0 in
+def A4_modwrapu: ALU64Inst<(outs IntRegs:$Rd), (ins IntRegs:$Rs, IntRegs:$Rt),
+ "$Rd = modwrap($Rs, $Rt)", [], "", ALU64_tc_2_SLOT23> {
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1101;
+ let Inst{27-21} = 0b0011111;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ let Inst{7-5} = 0b111;
+ let Inst{4-0} = Rd;
+}
-// Rx|=or(Rs,Rt)
-let validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "reg" in
-def ORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
- "$dst |= or($src2, $src3)",
- [(set (i32 IntRegs:$dst),
- (or (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>, ImmRegRel;
+let hasSideEffects = 0, isCodeGenOnly = 0 in
+def A4_bitsplit: ALU64Inst<(outs DoubleRegs:$Rd),
+ (ins IntRegs:$Rs, IntRegs:$Rt),
+ "$Rd = bitsplit($Rs, $Rt)", [], "", ALU64_tc_1_SLOT23> {
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1101;
+ let Inst{27-24} = 0b0100;
+ let Inst{21} = 0b1;
+ let Inst{20-16} = Rs;
+ let Inst{12-8} = Rt;
+ let Inst{4-0} = Rd;
+}
-// Rx^=or(Rs,Rt)
-let validSubTargets = HasV4SubT in
-def XORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
- "$dst ^= or($src2, $src3)",
- [(set (i32 IntRegs:$dst),
- (xor (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
+let isCodeGenOnly = 0 in {
+// Rx[&|]=xor(Rs,Rt)
+def M4_or_xor : T_MType_acc_rr < "|= xor", 0b110, 0b001, 0>;
+def M4_and_xor : T_MType_acc_rr < "&= xor", 0b010, 0b010, 0>;
-// Rx[&|^]=xor(Rs,Rt)
-// Rx&=xor(Rs,Rt)
-let validSubTargets = HasV4SubT in
-def ANDr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
- "$dst &= xor($src2, $src3)",
- [(set (i32 IntRegs:$dst),
- (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
+// Rx[&|^]=or(Rs,Rt)
+def M4_xor_or : T_MType_acc_rr < "^= or", 0b110, 0b011, 0>;
-// Rx|=xor(Rs,Rt)
-let validSubTargets = HasV4SubT in
-def ORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
- "$dst |= xor($src2, $src3)",
- [(set (i32 IntRegs:$dst),
- (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
+let CextOpcode = "ORr_ORr" in
+def M4_or_or : T_MType_acc_rr < "|= or", 0b110, 0b000, 0>;
+def M4_and_or : T_MType_acc_rr < "&= or", 0b010, 0b001, 0>;
-// Rx^=xor(Rs,Rt)
-let validSubTargets = HasV4SubT in
-def XORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
- "$dst ^= xor($src2, $src3)",
- [(set (i32 IntRegs:$dst),
- (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
+// Rx[&|^]=and(Rs,Rt)
+def M4_xor_and : T_MType_acc_rr < "^= and", 0b110, 0b010, 0>;
-// Rx|=and(Rs,#s10)
-let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
-validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "imm" in
-def ORr_ANDri2_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
- "$dst |= and($src2, #$src3)",
- [(set (i32 IntRegs:$dst),
- (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
- s10ExtPred:$src3)))],
- "$src1 = $dst">,
- Requires<[HasV4T]>, ImmRegRel;
+let CextOpcode = "ORr_ANDr" in
+def M4_or_and : T_MType_acc_rr < "|= and", 0b010, 0b011, 0>;
+def M4_and_and : T_MType_acc_rr < "&= and", 0b010, 0b000, 0>;
-// Rx|=or(Rs,#s10)
-let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
-validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "imm" in
-def ORr_ORri_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
- "$dst |= or($src2, #$src3)",
- [(set (i32 IntRegs:$dst),
- (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
- s10ExtPred:$src3)))],
- "$src1 = $dst">,
- Requires<[HasV4T]>, ImmRegRel;
+// Rx[&|^]=and(Rs,~Rt)
+def M4_xor_andn : T_MType_acc_rr < "^= and", 0b001, 0b010, 0, [], 1>;
+def M4_or_andn : T_MType_acc_rr < "|= and", 0b001, 0b000, 0, [], 1>;
+def M4_and_andn : T_MType_acc_rr < "&= and", 0b001, 0b001, 0, [], 1>;
+}
+
+// Compound or-or and or-and
+let isExtentSigned = 1, InputType = "imm", hasNewValue = 1, isExtendable = 1,
+ opExtentBits = 10, opExtendable = 3 in
+class T_CompOR <string mnemonic, bits<2> MajOp, SDNode OpNode>
+ : MInst_acc <(outs IntRegs:$Rx),
+ (ins IntRegs:$src1, IntRegs:$Rs, s10Ext:$s10),
+ "$Rx |= "#mnemonic#"($Rs, #$s10)",
+ [(set (i32 IntRegs:$Rx), (or (i32 IntRegs:$src1),
+ (OpNode (i32 IntRegs:$Rs), s10ExtPred:$s10)))],
+ "$src1 = $Rx", ALU64_tc_2_SLOT23>, ImmRegRel {
+ bits<5> Rx;
+ bits<5> Rs;
+ bits<10> s10;
+
+ let IClass = 0b1101;
+
+ let Inst{27-24} = 0b1010;
+ let Inst{23-22} = MajOp;
+ let Inst{20-16} = Rs;
+ let Inst{21} = s10{9};
+ let Inst{13-5} = s10{8-0};
+ let Inst{4-0} = Rx;
+ }
+let CextOpcode = "ORr_ANDr", isCodeGenOnly = 0 in
+def S4_or_andi : T_CompOR <"and", 0b00, and>;
+
+let CextOpcode = "ORr_ORr", isCodeGenOnly = 0 in
+def S4_or_ori : T_CompOR <"or", 0b10, or>;
// Modulo wrap
// Rd=modwrap(Rs,Rt)
@@ -1480,79 +1918,229 @@ def ORr_ORri_V4 : MInst_acc<(outs IntRegs:$dst),
// XTYPE/ALU -
//===----------------------------------------------------------------------===//
+//===----------------------------------------------------------------------===//
+// XTYPE/BIT +
+//===----------------------------------------------------------------------===//
+
+// Bit reverse
+let isCodeGenOnly = 0 in
+def S2_brevp : T_S2op_3 <"brev", 0b11, 0b110>;
+
+// Bit count
+let isCodeGenOnly = 0 in {
+def S2_ct0p : T_COUNT_LEADING_64<"ct0", 0b111, 0b010>;
+def S2_ct1p : T_COUNT_LEADING_64<"ct1", 0b111, 0b100>;
+def S4_clbpnorm : T_COUNT_LEADING_64<"normamt", 0b011, 0b000>;
+}
+
+def: Pat<(i32 (trunc (cttz (i64 DoubleRegs:$Rss)))),
+ (S2_ct0p (i64 DoubleRegs:$Rss))>;
+def: Pat<(i32 (trunc (cttz (not (i64 DoubleRegs:$Rss))))),
+ (S2_ct1p (i64 DoubleRegs:$Rss))>;
+
+let hasSideEffects = 0, hasNewValue = 1, isCodeGenOnly = 0 in
+def S4_clbaddi : SInst<(outs IntRegs:$Rd), (ins IntRegs:$Rs, s6Imm:$s6),
+ "$Rd = add(clb($Rs), #$s6)", [], "", S_2op_tc_2_SLOT23> {
+ bits<5> Rs;
+ bits<5> Rd;
+ bits<6> s6;
+ let IClass = 0b1000;
+ let Inst{27-24} = 0b1100;
+ let Inst{23-21} = 0b001;
+ let Inst{20-16} = Rs;
+ let Inst{13-8} = s6;
+ let Inst{7-5} = 0b000;
+ let Inst{4-0} = Rd;
+}
+
+let hasSideEffects = 0, hasNewValue = 1, isCodeGenOnly = 0 in
+def S4_clbpaddi : SInst<(outs IntRegs:$Rd), (ins DoubleRegs:$Rs, s6Imm:$s6),
+ "$Rd = add(clb($Rs), #$s6)", [], "", S_2op_tc_2_SLOT23> {
+ bits<5> Rs;
+ bits<5> Rd;
+ bits<6> s6;
+ let IClass = 0b1000;
+ let Inst{27-24} = 0b1000;
+ let Inst{23-21} = 0b011;
+ let Inst{20-16} = Rs;
+ let Inst{13-8} = s6;
+ let Inst{7-5} = 0b010;
+ let Inst{4-0} = Rd;
+}
+
+
+// Bit test/set/clear
+let isCodeGenOnly = 0 in {
+def S4_ntstbit_i : T_TEST_BIT_IMM<"!tstbit", 0b001>;
+def S4_ntstbit_r : T_TEST_BIT_REG<"!tstbit", 1>;
+}
+
+let AddedComplexity = 20 in { // Complexity greater than cmp reg-imm.
+ def: Pat<(i1 (seteq (and (shl 1, u5ImmPred:$u5), (i32 IntRegs:$Rs)), 0)),
+ (S4_ntstbit_i (i32 IntRegs:$Rs), u5ImmPred:$u5)>;
+ def: Pat<(i1 (seteq (and (shl 1, (i32 IntRegs:$Rt)), (i32 IntRegs:$Rs)), 0)),
+ (S4_ntstbit_r (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))>;
+}
+
+// Add extra complexity to prefer these instructions over bitsset/bitsclr.
+// The reason is that tstbit/ntstbit can be folded into a compound instruction:
+// if ([!]tstbit(...)) jump ...
+let AddedComplexity = 100 in
+def: Pat<(i1 (setne (and (i32 IntRegs:$Rs), (i32 Set5ImmPred:$u5)), (i32 0))),
+ (S2_tstbit_i (i32 IntRegs:$Rs), (BITPOS32 Set5ImmPred:$u5))>;
+
+let AddedComplexity = 100 in
+def: Pat<(i1 (seteq (and (i32 IntRegs:$Rs), (i32 Set5ImmPred:$u5)), (i32 0))),
+ (S4_ntstbit_i (i32 IntRegs:$Rs), (BITPOS32 Set5ImmPred:$u5))>;
+
+let isCodeGenOnly = 0 in {
+def C4_nbitsset : T_TEST_BITS_REG<"!bitsset", 0b01, 1>;
+def C4_nbitsclr : T_TEST_BITS_REG<"!bitsclr", 0b10, 1>;
+def C4_nbitsclri : T_TEST_BITS_IMM<"!bitsclr", 0b10, 1>;
+}
+
+// Do not increase complexity of these patterns. In the DAG, "cmp i8" may be
+// represented as a compare against "value & 0xFF", which is an exact match
+// for cmpb (same for cmph). The patterns below do not contain any additional
+// complexity that would make them preferable, and if they were actually used
+// instead of cmpb/cmph, they would result in a compare against register that
+// is loaded with the byte/half mask (i.e. 0xFF or 0xFFFF).
+def: Pat<(i1 (setne (and I32:$Rs, u6ImmPred:$u6), 0)),
+ (C4_nbitsclri I32:$Rs, u6ImmPred:$u6)>;
+def: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), 0)),
+ (C4_nbitsclr I32:$Rs, I32:$Rt)>;
+def: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), I32:$Rt)),
+ (C4_nbitsset I32:$Rs, I32:$Rt)>;
+
+//===----------------------------------------------------------------------===//
+// XTYPE/BIT -
+//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// XTYPE/MPY +
//===----------------------------------------------------------------------===//
-// Multiply and user lower result.
-// Rd=add(#u6,mpyi(Rs,#U6))
-let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
-validSubTargets = HasV4SubT in
-def ADDi_MPYri_V4 : MInst<(outs IntRegs:$dst),
- (ins u6Ext:$src1, IntRegs:$src2, u6Imm:$src3),
- "$dst = add(#$src1, mpyi($src2, #$src3))",
- [(set (i32 IntRegs:$dst),
- (add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
- u6ExtPred:$src1))]>,
- Requires<[HasV4T]>;
+// Rd=add(#u6,mpyi(Rs,#U6)) -- Multiply by immed and add immed.
+
+let hasNewValue = 1, isExtendable = 1, opExtentBits = 6, opExtendable = 1,
+ isCodeGenOnly = 0 in
+def M4_mpyri_addi : MInst<(outs IntRegs:$Rd),
+ (ins u6Ext:$u6, IntRegs:$Rs, u6Imm:$U6),
+ "$Rd = add(#$u6, mpyi($Rs, #$U6))" ,
+ [(set (i32 IntRegs:$Rd),
+ (add (mul (i32 IntRegs:$Rs), u6ImmPred:$U6),
+ u6ExtPred:$u6))] ,"",ALU64_tc_3x_SLOT23> {
+ bits<5> Rd;
+ bits<6> u6;
+ bits<5> Rs;
+ bits<6> U6;
+
+ let IClass = 0b1101;
+
+ let Inst{27-24} = 0b1000;
+ let Inst{23} = U6{5};
+ let Inst{22-21} = u6{5-4};
+ let Inst{20-16} = Rs;
+ let Inst{13} = u6{3};
+ let Inst{12-8} = Rd;
+ let Inst{7-5} = u6{2-0};
+ let Inst{4-0} = U6{4-0};
+ }
+
+// Rd=add(#u6,mpyi(Rs,Rt))
+let CextOpcode = "ADD_MPY", InputType = "imm", hasNewValue = 1,
+ isExtendable = 1, opExtentBits = 6, opExtendable = 1, isCodeGenOnly = 0 in
+def M4_mpyrr_addi : MInst <(outs IntRegs:$Rd),
+ (ins u6Ext:$u6, IntRegs:$Rs, IntRegs:$Rt),
+ "$Rd = add(#$u6, mpyi($Rs, $Rt))" ,
+ [(set (i32 IntRegs:$Rd),
+ (add (mul (i32 IntRegs:$Rs), (i32 IntRegs:$Rt)), u6ExtPred:$u6))],
+ "", ALU64_tc_3x_SLOT23>, ImmRegRel {
+ bits<5> Rd;
+ bits<6> u6;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1101;
+
+ let Inst{27-23} = 0b01110;
+ let Inst{22-21} = u6{5-4};
+ let Inst{20-16} = Rs;
+ let Inst{13} = u6{3};
+ let Inst{12-8} = Rt;
+ let Inst{7-5} = u6{2-0};
+ let Inst{4-0} = Rd;
+ }
+
+let hasNewValue = 1 in
+class T_AddMpy <bit MajOp, PatLeaf ImmPred, dag ins>
+ : ALU64Inst <(outs IntRegs:$dst), ins,
+ "$dst = add($src1, mpyi("#!if(MajOp,"$src3, #$src2))",
+ "#$src2, $src3))"),
+ [(set (i32 IntRegs:$dst),
+ (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src3), ImmPred:$src2)))],
+ "", ALU64_tc_3x_SLOT23> {
+ bits<5> dst;
+ bits<5> src1;
+ bits<8> src2;
+ bits<5> src3;
+
+ let IClass = 0b1101;
+
+ bits<6> ImmValue = !if(MajOp, src2{5-0}, src2{7-2});
+
+ let Inst{27-24} = 0b1111;
+ let Inst{23} = MajOp;
+ let Inst{22-21} = ImmValue{5-4};
+ let Inst{20-16} = src3;
+ let Inst{13} = ImmValue{3};
+ let Inst{12-8} = dst;
+ let Inst{7-5} = ImmValue{2-0};
+ let Inst{4-0} = src1;
+ }
+
+let isCodeGenOnly = 0 in
+def M4_mpyri_addr_u2 : T_AddMpy<0b0, u6_2ImmPred,
+ (ins IntRegs:$src1, u6_2Imm:$src2, IntRegs:$src3)>;
+
+let isExtendable = 1, opExtentBits = 6, opExtendable = 3,
+ CextOpcode = "ADD_MPY", InputType = "imm", isCodeGenOnly = 0 in
+def M4_mpyri_addr : T_AddMpy<0b1, u6ExtPred,
+ (ins IntRegs:$src1, IntRegs:$src3, u6Ext:$src2)>, ImmRegRel;
+
+// Rx=add(Ru,mpyi(Rx,Rs))
+let validSubTargets = HasV4SubT, CextOpcode = "ADD_MPY", InputType = "reg",
+ hasNewValue = 1, isCodeGenOnly = 0 in
+def M4_mpyrr_addr: MInst_acc <(outs IntRegs:$Rx),
+ (ins IntRegs:$Ru, IntRegs:$_src_, IntRegs:$Rs),
+ "$Rx = add($Ru, mpyi($_src_, $Rs))",
+ [(set (i32 IntRegs:$Rx), (add (i32 IntRegs:$Ru),
+ (mul (i32 IntRegs:$_src_), (i32 IntRegs:$Rs))))],
+ "$_src_ = $Rx", M_tc_3x_SLOT23>, ImmRegRel {
+ bits<5> Rx;
+ bits<5> Ru;
+ bits<5> Rs;
+
+ let IClass = 0b1110;
+
+ let Inst{27-21} = 0b0011000;
+ let Inst{12-8} = Rx;
+ let Inst{4-0} = Ru;
+ let Inst{20-16} = Rs;
+ }
// Rd=add(##,mpyi(Rs,#U6))
def : Pat <(add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
(HexagonCONST32 tglobaladdr:$src1)),
- (i32 (ADDi_MPYri_V4 tglobaladdr:$src1, IntRegs:$src2,
+ (i32 (M4_mpyri_addi tglobaladdr:$src1, IntRegs:$src2,
u6ImmPred:$src3))>;
-// Rd=add(#u6,mpyi(Rs,Rt))
-let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
-validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
-def ADDi_MPYrr_V4 : MInst<(outs IntRegs:$dst),
- (ins u6Ext:$src1, IntRegs:$src2, IntRegs:$src3),
- "$dst = add(#$src1, mpyi($src2, $src3))",
- [(set (i32 IntRegs:$dst),
- (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
- u6ExtPred:$src1))]>,
- Requires<[HasV4T]>, ImmRegRel;
-
// Rd=add(##,mpyi(Rs,Rt))
def : Pat <(add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
(HexagonCONST32 tglobaladdr:$src1)),
- (i32 (ADDi_MPYrr_V4 tglobaladdr:$src1, IntRegs:$src2,
+ (i32 (M4_mpyrr_addi tglobaladdr:$src1, IntRegs:$src2,
IntRegs:$src3))>;
-// Rd=add(Ru,mpyi(#u6:2,Rs))
-let validSubTargets = HasV4SubT in
-def ADDr_MPYir_V4 : MInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, u6Imm:$src2, IntRegs:$src3),
- "$dst = add($src1, mpyi(#$src2, $src3))",
- [(set (i32 IntRegs:$dst),
- (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src3),
- u6_2ImmPred:$src2)))]>,
- Requires<[HasV4T]>;
-
-// Rd=add(Ru,mpyi(Rs,#u6))
-let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 6,
-validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
-def ADDr_MPYri_V4 : MInst<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2, u6Ext:$src3),
- "$dst = add($src1, mpyi($src2, #$src3))",
- [(set (i32 IntRegs:$dst),
- (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
- u6ExtPred:$src3)))]>,
- Requires<[HasV4T]>, ImmRegRel;
-
-// Rx=add(Ru,mpyi(Rx,Rs))
-let validSubTargets = HasV4SubT, InputType = "reg", CextOpcode = "ADD_MPY" in
-def ADDr_MPYrr_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
- "$dst = add($src1, mpyi($src2, $src3))",
- [(set (i32 IntRegs:$dst),
- (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src2 = $dst">,
- Requires<[HasV4T]>, ImmRegRel;
-
-
// Polynomial multiply words
// Rdd=pmpyw(Rs,Rt)
// Rxx^=pmpyw(Rs,Rt)
@@ -1590,159 +2178,115 @@ def ADDr_MPYrr_V4 : MInst_acc<(outs IntRegs:$dst),
//===----------------------------------------------------------------------===//
// XTYPE/SHIFT +
//===----------------------------------------------------------------------===//
-
-// Shift by immediate and accumulate.
-// Rx=add(#u8,asl(Rx,#U5))
-let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
-validSubTargets = HasV4SubT in
-def ADDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
- "$dst = add(#$src1, asl($src2, #$src3))",
- [(set (i32 IntRegs:$dst),
- (add (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
- u8ExtPred:$src1))],
- "$src2 = $dst">,
- Requires<[HasV4T]>;
-
-// Rx=add(#u8,lsr(Rx,#U5))
-let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
-validSubTargets = HasV4SubT in
-def ADDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
- "$dst = add(#$src1, lsr($src2, #$src3))",
- [(set (i32 IntRegs:$dst),
- (add (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
- u8ExtPred:$src1))],
- "$src2 = $dst">,
- Requires<[HasV4T]>;
-
-// Rx=sub(#u8,asl(Rx,#U5))
-let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
-validSubTargets = HasV4SubT in
-def SUBi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
- "$dst = sub(#$src1, asl($src2, #$src3))",
- [(set (i32 IntRegs:$dst),
- (sub (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
- u8ExtPred:$src1))],
- "$src2 = $dst">,
- Requires<[HasV4T]>;
-
-// Rx=sub(#u8,lsr(Rx,#U5))
-let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
-validSubTargets = HasV4SubT in
-def SUBi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
- "$dst = sub(#$src1, lsr($src2, #$src3))",
- [(set (i32 IntRegs:$dst),
- (sub (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
- u8ExtPred:$src1))],
- "$src2 = $dst">,
- Requires<[HasV4T]>;
-
-
-//Shift by immediate and logical.
-//Rx=and(#u8,asl(Rx,#U5))
-let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
-validSubTargets = HasV4SubT in
-def ANDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
- "$dst = and(#$src1, asl($src2, #$src3))",
- [(set (i32 IntRegs:$dst),
- (and (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
- u8ExtPred:$src1))],
- "$src2 = $dst">,
- Requires<[HasV4T]>;
-
-//Rx=and(#u8,lsr(Rx,#U5))
+// Shift by immediate and accumulate/logical.
+// Rx=add(#u8,asl(Rx,#U5)) Rx=add(#u8,lsr(Rx,#U5))
+// Rx=sub(#u8,asl(Rx,#U5)) Rx=sub(#u8,lsr(Rx,#U5))
+// Rx=and(#u8,asl(Rx,#U5)) Rx=and(#u8,lsr(Rx,#U5))
+// Rx=or(#u8,asl(Rx,#U5)) Rx=or(#u8,lsr(Rx,#U5))
let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
-validSubTargets = HasV4SubT in
-def ANDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
- "$dst = and(#$src1, lsr($src2, #$src3))",
- [(set (i32 IntRegs:$dst),
- (and (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
- u8ExtPred:$src1))],
- "$src2 = $dst">,
- Requires<[HasV4T]>;
-
-//Rx=or(#u8,asl(Rx,#U5))
-let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
-AddedComplexity = 30, validSubTargets = HasV4SubT in
-def ORi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
- "$dst = or(#$src1, asl($src2, #$src3))",
- [(set (i32 IntRegs:$dst),
- (or (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
- u8ExtPred:$src1))],
- "$src2 = $dst">,
- Requires<[HasV4T]>;
+ hasNewValue = 1, opNewValue = 0, validSubTargets = HasV4SubT in
+class T_S4_ShiftOperate<string MnOp, string MnSh, SDNode Op, SDNode Sh,
+ bit asl_lsr, bits<2> MajOp, InstrItinClass Itin>
+ : MInst_acc<(outs IntRegs:$Rd), (ins u8Ext:$u8, IntRegs:$Rx, u5Imm:$U5),
+ "$Rd = "#MnOp#"(#$u8, "#MnSh#"($Rx, #$U5))",
+ [(set (i32 IntRegs:$Rd),
+ (Op (Sh I32:$Rx, u5ImmPred:$U5), u8ExtPred:$u8))],
+ "$Rd = $Rx", Itin> {
+
+ bits<5> Rd;
+ bits<8> u8;
+ bits<5> Rx;
+ bits<5> U5;
+
+ let IClass = 0b1101;
+ let Inst{27-24} = 0b1110;
+ let Inst{23-21} = u8{7-5};
+ let Inst{20-16} = Rd;
+ let Inst{13} = u8{4};
+ let Inst{12-8} = U5;
+ let Inst{7-5} = u8{3-1};
+ let Inst{4} = asl_lsr;
+ let Inst{3} = u8{0};
+ let Inst{2-1} = MajOp;
+}
-//Rx=or(#u8,lsr(Rx,#U5))
-let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
-AddedComplexity = 30, validSubTargets = HasV4SubT in
-def ORi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
- (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
- "$dst = or(#$src1, lsr($src2, #$src3))",
- [(set (i32 IntRegs:$dst),
- (or (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
- u8ExtPred:$src1))],
- "$src2 = $dst">,
- Requires<[HasV4T]>;
+multiclass T_ShiftOperate<string mnemonic, SDNode Op, bits<2> MajOp,
+ InstrItinClass Itin> {
+ def _asl_ri : T_S4_ShiftOperate<mnemonic, "asl", Op, shl, 0, MajOp, Itin>;
+ def _lsr_ri : T_S4_ShiftOperate<mnemonic, "lsr", Op, srl, 1, MajOp, Itin>;
+}
+let AddedComplexity = 200, isCodeGenOnly = 0 in {
+ defm S4_addi : T_ShiftOperate<"add", add, 0b10, ALU64_tc_2_SLOT23>;
+ defm S4_andi : T_ShiftOperate<"and", and, 0b00, ALU64_tc_2_SLOT23>;
+}
-//Shift by register.
-//Rd=lsl(#s6,Rt)
-let validSubTargets = HasV4SubT in {
-def LSLi_V4 : MInst<(outs IntRegs:$dst), (ins s6Imm:$src1, IntRegs:$src2),
- "$dst = lsl(#$src1, $src2)",
- [(set (i32 IntRegs:$dst), (shl s6ImmPred:$src1,
- (i32 IntRegs:$src2)))]>,
- Requires<[HasV4T]>;
+let AddedComplexity = 30, isCodeGenOnly = 0 in
+defm S4_ori : T_ShiftOperate<"or", or, 0b01, ALU64_tc_1_SLOT23>;
+let isCodeGenOnly = 0 in
+defm S4_subi : T_ShiftOperate<"sub", sub, 0b11, ALU64_tc_1_SLOT23>;
-//Shift by register and logical.
-//Rxx^=asl(Rss,Rt)
-def ASLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
- "$dst ^= asl($src2, $src3)",
- [(set (i64 DoubleRegs:$dst),
- (xor (i64 DoubleRegs:$src1), (shl (i64 DoubleRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
-//Rxx^=asr(Rss,Rt)
-def ASRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
- "$dst ^= asr($src2, $src3)",
- [(set (i64 DoubleRegs:$dst),
- (xor (i64 DoubleRegs:$src1), (sra (i64 DoubleRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
+// Rd=[cround|round](Rs,Rt)
+let hasNewValue = 1, Itinerary = S_3op_tc_2_SLOT23, isCodeGenOnly = 0 in {
+ def A4_cround_rr : T_S3op_3 < "cround", IntRegs, 0b11, 0b00>;
+ def A4_round_rr : T_S3op_3 < "round", IntRegs, 0b11, 0b10>;
+}
-//Rxx^=lsl(Rss,Rt)
-def LSLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
- "$dst ^= lsl($src2, $src3)",
- [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1),
- (shl (i64 DoubleRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
+// Rd=round(Rs,Rt):sat
+let hasNewValue = 1, Defs = [USR_OVF], Itinerary = S_3op_tc_2_SLOT23,
+ isCodeGenOnly = 0 in
+def A4_round_rr_sat : T_S3op_3 < "round", IntRegs, 0b11, 0b11, 1>;
+
+// Rdd=[add|sub](Rss,Rtt,Px):carry
+let isPredicateLate = 1, hasSideEffects = 0 in
+class T_S3op_carry <string mnemonic, bits<3> MajOp>
+ : SInst < (outs DoubleRegs:$Rdd, PredRegs:$Px),
+ (ins DoubleRegs:$Rss, DoubleRegs:$Rtt, PredRegs:$Pu),
+ "$Rdd = "#mnemonic#"($Rss, $Rtt, $Pu):carry",
+ [], "$Px = $Pu", S_3op_tc_1_SLOT23 > {
+ bits<5> Rdd;
+ bits<5> Rss;
+ bits<5> Rtt;
+ bits<2> Pu;
+
+ let IClass = 0b1100;
+
+ let Inst{27-24} = 0b0010;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = Rss;
+ let Inst{12-8} = Rtt;
+ let Inst{6-5} = Pu;
+ let Inst{4-0} = Rdd;
+ }
-//Rxx^=lsr(Rss,Rt)
-def LSRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
- "$dst ^= lsr($src2, $src3)",
- [(set (i64 DoubleRegs:$dst),
- (xor (i64 DoubleRegs:$src1), (srl (i64 DoubleRegs:$src2),
- (i32 IntRegs:$src3))))],
- "$src1 = $dst">,
- Requires<[HasV4T]>;
+let isCodeGenOnly = 0 in {
+def A4_addp_c : T_S3op_carry < "add", 0b110 >;
+def A4_subp_c : T_S3op_carry < "sub", 0b111 >;
}
+// Shift an immediate left by register amount.
+let hasNewValue = 1, hasSideEffects = 0, isCodeGenOnly = 0 in
+def S4_lsli: SInst <(outs IntRegs:$Rd), (ins s6Imm:$s6, IntRegs:$Rt),
+ "$Rd = lsl(#$s6, $Rt)" ,
+ [(set (i32 IntRegs:$Rd), (shl s6ImmPred:$s6,
+ (i32 IntRegs:$Rt)))],
+ "", S_3op_tc_1_SLOT23> {
+ bits<5> Rd;
+ bits<6> s6;
+ bits<5> Rt;
+
+ let IClass = 0b1100;
+
+ let Inst{27-22} = 0b011010;
+ let Inst{20-16} = s6{5-1};
+ let Inst{12-8} = Rt;
+ let Inst{7-6} = 0b11;
+ let Inst{4-0} = Rd;
+ let Inst{5} = s6{0};
+ }
+
//===----------------------------------------------------------------------===//
// XTYPE/SHIFT -
//===----------------------------------------------------------------------===//
@@ -1830,7 +2374,7 @@ class MemOp_rr_base <string opc, bits<2> opcBits, Operand ImmOp,
(ins IntRegs:$base, ImmOp:$offset, IntRegs:$delta),
opc#"($base+#$offset)"#memOp#"$delta",
[]>,
- Requires<[HasV4T, UseMEMOP]> {
+ Requires<[UseMEMOP]> {
bits<5> base;
bits<5> delta;
@@ -1841,6 +2385,7 @@ class MemOp_rr_base <string opc, bits<2> opcBits, Operand ImmOp,
!if (!eq(opcBits, 0b01), offset{6-1},
!if (!eq(opcBits, 0b10), offset{7-2},0)));
+ let opExtentAlign = opcBits;
let IClass = 0b0011;
let Inst{27-24} = 0b1110;
let Inst{22-21} = opcBits;
@@ -1861,7 +2406,7 @@ class MemOp_ri_base <string opc, bits<2> opcBits, Operand ImmOp,
opc#"($base+#$offset)"#memOp#"#$delta"
#!if(memOpBits{1},")", ""), // clrbit, setbit - include ')'
[]>,
- Requires<[HasV4T, UseMEMOP]> {
+ Requires<[UseMEMOP]> {
bits<5> base;
bits<5> delta;
@@ -1872,6 +2417,7 @@ class MemOp_ri_base <string opc, bits<2> opcBits, Operand ImmOp,
!if (!eq(opcBits, 0b01), offset{6-1},
!if (!eq(opcBits, 0b10), offset{7-2},0)));
+ let opExtentAlign = opcBits;
let IClass = 0b0011;
let Inst{27-24} = 0b1111;
let Inst{22-21} = opcBits;
@@ -1884,36 +2430,36 @@ class MemOp_ri_base <string opc, bits<2> opcBits, Operand ImmOp,
// multiclass to define MemOp instructions with register operand.
multiclass MemOp_rr<string opc, bits<2> opcBits, Operand ImmOp> {
- def _ADD#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " += ", 0b00>; // add
- def _SUB#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " -= ", 0b01>; // sub
- def _AND#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " &= ", 0b10>; // and
- def _OR#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " |= ", 0b11>; // or
+ def L4_add#NAME : MemOp_rr_base <opc, opcBits, ImmOp, " += ", 0b00>; // add
+ def L4_sub#NAME : MemOp_rr_base <opc, opcBits, ImmOp, " -= ", 0b01>; // sub
+ def L4_and#NAME : MemOp_rr_base <opc, opcBits, ImmOp, " &= ", 0b10>; // and
+ def L4_or#NAME : MemOp_rr_base <opc, opcBits, ImmOp, " |= ", 0b11>; // or
}
// multiclass to define MemOp instructions with immediate Operand.
multiclass MemOp_ri<string opc, bits<2> opcBits, Operand ImmOp> {
- def _ADD#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " += ", 0b00 >;
- def _SUB#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " -= ", 0b01 >;
- def _CLRBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =clrbit(", 0b10>;
- def _SETBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =setbit(", 0b11>;
+ def L4_iadd#NAME : MemOp_ri_base <opc, opcBits, ImmOp, " += ", 0b00 >;
+ def L4_isub#NAME : MemOp_ri_base <opc, opcBits, ImmOp, " -= ", 0b01 >;
+ def L4_iand#NAME : MemOp_ri_base<opc, opcBits, ImmOp, " = clrbit(", 0b10>;
+ def L4_ior#NAME : MemOp_ri_base<opc, opcBits, ImmOp, " = setbit(", 0b11>;
}
multiclass MemOp_base <string opc, bits<2> opcBits, Operand ImmOp> {
- defm r : MemOp_rr <opc, opcBits, ImmOp>;
- defm i : MemOp_ri <opc, opcBits, ImmOp>;
+ defm _#NAME : MemOp_rr <opc, opcBits, ImmOp>;
+ defm _#NAME : MemOp_ri <opc, opcBits, ImmOp>;
}
// Define MemOp instructions.
let isExtendable = 1, opExtendable = 1, isExtentSigned = 0,
-validSubTargets =HasV4SubT in {
- let opExtentBits = 6, accessSize = ByteAccess in
- defm MemOPb : MemOp_base <"memb", 0b00, u6_0Ext>;
+ validSubTargets =HasV4SubT in {
+ let opExtentBits = 6, accessSize = ByteAccess, isCodeGenOnly = 0 in
+ defm memopb_io : MemOp_base <"memb", 0b00, u6_0Ext>;
- let opExtentBits = 7, accessSize = HalfWordAccess in
- defm MemOPh : MemOp_base <"memh", 0b01, u6_1Ext>;
+ let opExtentBits = 7, accessSize = HalfWordAccess, isCodeGenOnly = 0 in
+ defm memoph_io : MemOp_base <"memh", 0b01, u6_1Ext>;
- let opExtentBits = 8, accessSize = WordAccess in
- defm MemOPw : MemOp_base <"memw", 0b10, u6_2Ext>;
+ let opExtentBits = 8, accessSize = WordAccess, isCodeGenOnly = 0 in
+ defm memopw_io : MemOp_base <"memw", 0b10, u6_2Ext>;
}
//===----------------------------------------------------------------------===//
@@ -1946,10 +2492,10 @@ multiclass MemOpi_u5ALUOp<PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred,
multiclass MemOpi_u5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
// Half Word
defm : MemOpi_u5ALUOp <ldOpHalf, truncstorei16, u6_1ExtPred,
- MemOPh_ADDi_V4, MemOPh_SUBi_V4>;
+ L4_iadd_memoph_io, L4_isub_memoph_io>;
// Byte
defm : MemOpi_u5ALUOp <ldOpByte, truncstorei8, u6ExtPred,
- MemOPb_ADDi_V4, MemOPb_SUBi_V4>;
+ L4_iadd_memopb_io, L4_isub_memopb_io>;
}
let Predicates = [HasV4T, UseMEMOP] in {
@@ -1958,8 +2504,8 @@ let Predicates = [HasV4T, UseMEMOP] in {
defm : MemOpi_u5ExtType<extloadi8, extloadi16>; // any extend
// Word
- defm : MemOpi_u5ALUOp <load, store, u6_2ExtPred, MemOPw_ADDi_V4,
- MemOPw_SUBi_V4>;
+ defm : MemOpi_u5ALUOp <load, store, u6_2ExtPred, L4_iadd_memopw_io,
+ L4_isub_memopw_io>;
}
//===----------------------------------------------------------------------===//
@@ -1987,10 +2533,10 @@ multiclass MemOpi_m5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf extPred,
multiclass MemOpi_m5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
// Half Word
defm : MemOpi_m5Pats <ldOpHalf, truncstorei16, u6_1ExtPred, m5HImmPred,
- ADDRriU6_1, MEMOPIMM_HALF, MemOPh_SUBi_V4>;
+ ADDRriU6_1, MEMOPIMM_HALF, L4_isub_memoph_io>;
// Byte
defm : MemOpi_m5Pats <ldOpByte, truncstorei8, u6ExtPred, m5BImmPred,
- ADDRriU6_0, MEMOPIMM_BYTE, MemOPb_SUBi_V4>;
+ ADDRriU6_0, MEMOPIMM_BYTE, L4_isub_memopb_io>;
}
let Predicates = [HasV4T, UseMEMOP] in {
@@ -2000,7 +2546,7 @@ let Predicates = [HasV4T, UseMEMOP] in {
// Word
defm : MemOpi_m5Pats <load, store, u6_2ExtPred, m5ImmPred,
- ADDRriU6_2, MEMOPIMM, MemOPw_SUBi_V4>;
+ ADDRriU6_2, MEMOPIMM, L4_isub_memopw_io>;
}
//===----------------------------------------------------------------------===//
@@ -2031,16 +2577,16 @@ multiclass MemOpi_bitPats <PatFrag ldOp, PatFrag stOp, PatLeaf immPred,
multiclass MemOpi_bitExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
// Byte - clrbit
defm : MemOpi_bitPats<ldOpByte, truncstorei8, Clr3ImmPred, u6ExtPred,
- ADDRriU6_0, CLRMEMIMM_BYTE, MemOPb_CLRBITi_V4, and>;
+ ADDRriU6_0, CLRMEMIMM_BYTE, L4_iand_memopb_io, and>;
// Byte - setbit
defm : MemOpi_bitPats<ldOpByte, truncstorei8, Set3ImmPred, u6ExtPred,
- ADDRriU6_0, SETMEMIMM_BYTE, MemOPb_SETBITi_V4, or>;
+ ADDRriU6_0, SETMEMIMM_BYTE, L4_ior_memopb_io, or>;
// Half Word - clrbit
defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Clr4ImmPred, u6_1ExtPred,
- ADDRriU6_1, CLRMEMIMM_SHORT, MemOPh_CLRBITi_V4, and>;
+ ADDRriU6_1, CLRMEMIMM_SHORT, L4_iand_memoph_io, and>;
// Half Word - setbit
defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Set4ImmPred, u6_1ExtPred,
- ADDRriU6_1, SETMEMIMM_SHORT, MemOPh_SETBITi_V4, or>;
+ ADDRriU6_1, SETMEMIMM_SHORT, L4_ior_memoph_io, or>;
}
let Predicates = [HasV4T, UseMEMOP] in {
@@ -2053,9 +2599,9 @@ let Predicates = [HasV4T, UseMEMOP] in {
// memw(Rs+#0) = [clrbit|setbit](#U5)
// memw(Rs+#u6:2) = [clrbit|setbit](#U5)
defm : MemOpi_bitPats<load, store, Clr5ImmPred, u6_2ExtPred, ADDRriU6_2,
- CLRMEMIMM, MemOPw_CLRBITi_V4, and>;
+ CLRMEMIMM, L4_iand_memopw_io, and>;
defm : MemOpi_bitPats<load, store, Set5ImmPred, u6_2ExtPred, ADDRriU6_2,
- SETMEMIMM, MemOPw_SETBITi_V4, or>;
+ SETMEMIMM, L4_ior_memopw_io, or>;
}
//===----------------------------------------------------------------------===//
@@ -2096,12 +2642,12 @@ multiclass MemOPr_ALUOp<PatFrag ldOp, PatFrag stOp,
multiclass MemOPr_ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
// Half Word
defm : MemOPr_ALUOp <ldOpHalf, truncstorei16, ADDRriU6_1, u6_1ExtPred,
- MemOPh_ADDr_V4, MemOPh_SUBr_V4,
- MemOPh_ANDr_V4, MemOPh_ORr_V4>;
+ L4_add_memoph_io, L4_sub_memoph_io,
+ L4_and_memoph_io, L4_or_memoph_io>;
// Byte
defm : MemOPr_ALUOp <ldOpByte, truncstorei8, ADDRriU6_0, u6ExtPred,
- MemOPb_ADDr_V4, MemOPb_SUBr_V4,
- MemOPb_ANDr_V4, MemOPb_ORr_V4>;
+ L4_add_memopb_io, L4_sub_memopb_io,
+ L4_and_memopb_io, L4_or_memopb_io>;
}
// Define 'def Pats' for MemOps with register addend.
@@ -2111,8 +2657,8 @@ let Predicates = [HasV4T, UseMEMOP] in {
defm : MemOPr_ExtType<sextloadi8, sextloadi16>; // sign extend
defm : MemOPr_ExtType<extloadi8, extloadi16>; // any extend
// Word
- defm : MemOPr_ALUOp <load, store, ADDRriU6_2, u6_2ExtPred, MemOPw_ADDr_V4,
- MemOPw_SUBr_V4, MemOPw_ANDr_V4, MemOPw_ORr_V4 >;
+ defm : MemOPr_ALUOp <load, store, ADDRriU6_2, u6_2ExtPred, L4_add_memopw_io,
+ L4_sub_memopw_io, L4_and_memopw_io, L4_or_memopw_io >;
}
//===----------------------------------------------------------------------===//
@@ -2130,6 +2676,42 @@ let Predicates = [HasV4T, UseMEMOP] in {
// incorrect code for negative numbers.
// Pd=cmpb.eq(Rs,#u8)
+let isCompare = 1, isExtendable = 1, opExtendable = 2, hasSideEffects = 0,
+ validSubTargets = HasV4SubT in
+class CMP_NOT_REG_IMM<string OpName, bits<2> op, Operand ImmOp,
+ list<dag> Pattern>
+ : ALU32Inst <(outs PredRegs:$dst), (ins IntRegs:$src1, ImmOp:$src2),
+ "$dst = !cmp."#OpName#"($src1, #$src2)",
+ Pattern,
+ "", ALU32_2op_tc_2early_SLOT0123> {
+ bits<2> dst;
+ bits<5> src1;
+ bits<10> src2;
+
+ let IClass = 0b0111;
+ let Inst{27-24} = 0b0101;
+ let Inst{23-22} = op;
+ let Inst{20-16} = src1;
+ let Inst{21} = !if (!eq(OpName, "gtu"), 0b0, src2{9});
+ let Inst{13-5} = src2{8-0};
+ let Inst{4-2} = 0b100;
+ let Inst{1-0} = dst;
+}
+
+let opExtentBits = 10, isExtentSigned = 1 in {
+def C4_cmpneqi : CMP_NOT_REG_IMM <"eq", 0b00, s10Ext, [(set (i1 PredRegs:$dst),
+ (setne (i32 IntRegs:$src1), s10ExtPred:$src2))]>;
+
+def C4_cmpltei : CMP_NOT_REG_IMM <"gt", 0b01, s10Ext, [(set (i1 PredRegs:$dst),
+ (not (setgt (i32 IntRegs:$src1), s10ExtPred:$src2)))]>;
+
+}
+let opExtentBits = 9 in
+def C4_cmplteui : CMP_NOT_REG_IMM <"gtu", 0b10, u9Ext, [(set (i1 PredRegs:$dst),
+ (not (setugt (i32 IntRegs:$src1), u9ExtPred:$src2)))]>;
+
+
+
// p=!cmp.eq(r1,r2)
let isCompare = 1, validSubTargets = HasV4SubT in
def CMPnotEQ_rr : ALU32_rr<(outs PredRegs:$dst),
@@ -2139,15 +2721,6 @@ def CMPnotEQ_rr : ALU32_rr<(outs PredRegs:$dst),
(setne (i32 IntRegs:$src1), (i32 IntRegs:$src2)))]>,
Requires<[HasV4T]>;
-// p=!cmp.eq(r1,#s10)
-let isCompare = 1, validSubTargets = HasV4SubT in
-def CMPnotEQ_ri : ALU32_ri<(outs PredRegs:$dst),
- (ins IntRegs:$src1, s10Ext:$src2),
- "$dst = !cmp.eq($src1, #$src2)",
- [(set (i1 PredRegs:$dst),
- (setne (i32 IntRegs:$src1), s10ImmPred:$src2))]>,
- Requires<[HasV4T]>;
-
// p=!cmp.gt(r1,r2)
let isCompare = 1, validSubTargets = HasV4SubT in
def CMPnotGT_rr : ALU32_rr<(outs PredRegs:$dst),
@@ -2157,14 +2730,6 @@ def CMPnotGT_rr : ALU32_rr<(outs PredRegs:$dst),
(not (setgt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
Requires<[HasV4T]>;
-// p=!cmp.gt(r1,#s10)
-let isCompare = 1, validSubTargets = HasV4SubT in
-def CMPnotGT_ri : ALU32_ri<(outs PredRegs:$dst),
- (ins IntRegs:$src1, s10Ext:$src2),
- "$dst = !cmp.gt($src1, #$src2)",
- [(set (i1 PredRegs:$dst),
- (not (setgt (i32 IntRegs:$src1), s10ImmPred:$src2)))]>,
- Requires<[HasV4T]>;
// p=!cmp.gtu(r1,r2)
let isCompare = 1, validSubTargets = HasV4SubT in
@@ -2175,15 +2740,6 @@ def CMPnotGTU_rr : ALU32_rr<(outs PredRegs:$dst),
(not (setugt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
Requires<[HasV4T]>;
-// p=!cmp.gtu(r1,#u9)
-let isCompare = 1, validSubTargets = HasV4SubT in
-def CMPnotGTU_ri : ALU32_ri<(outs PredRegs:$dst),
- (ins IntRegs:$src1, u9Ext:$src2),
- "$dst = !cmp.gtu($src1, #$src2)",
- [(set (i1 PredRegs:$dst),
- (not (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)))]>,
- Requires<[HasV4T]>;
-
let isCompare = 1, validSubTargets = HasV4SubT in
def CMPbEQri_V4 : MInst<(outs PredRegs:$dst),
(ins IntRegs:$src1, u8Imm:$src2),
@@ -2194,7 +2750,7 @@ def CMPbEQri_V4 : MInst<(outs PredRegs:$dst),
def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)),
bb:$offset),
- (JMP_f (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
+ (J2_jumpf (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
bb:$offset)>,
Requires<[HasV4T]>;
@@ -2331,7 +2887,7 @@ def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 254)),
// if (!Pd.new) Rd=#0
// cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
def : Pat <(i32 (zext (i1 (setult (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
- (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt),
+ (i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rt),
(i32 IntRegs:$Rs))),
1, 0))>,
Requires<[HasV4T]>;
@@ -2344,7 +2900,7 @@ def : Pat <(i32 (zext (i1 (setult (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
// if (!Pd.new) Rd=#0
// cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
def : Pat <(i32 (zext (i1 (setlt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
- (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt),
+ (i32 (TFR_condset_ii (i1 (C2_cmpgt (i32 IntRegs:$Rt),
(i32 IntRegs:$Rs))),
1, 0))>,
Requires<[HasV4T]>;
@@ -2356,7 +2912,7 @@ def : Pat <(i32 (zext (i1 (setlt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
// if (Pd.new) Rd=#1
// if (!Pd.new) Rd=#0
def : Pat <(i32 (zext (i1 (setugt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
- (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs),
+ (i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rs),
(i32 IntRegs:$Rt))),
1, 0))>,
Requires<[HasV4T]>;
@@ -2378,7 +2934,7 @@ def : Pat <(i32 (zext (i1 (setugt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
// if (!Pd.new) Rd=#1
// cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
def : Pat <(i32 (zext (i1 (setuge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
- (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt),
+ (i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rt),
(i32 IntRegs:$Rs))),
0, 1))>,
Requires<[HasV4T]>;
@@ -2391,7 +2947,7 @@ def : Pat <(i32 (zext (i1 (setuge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
// if (!Pd.new) Rd=#1
// cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
def : Pat <(i32 (zext (i1 (setge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
- (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt),
+ (i32 (TFR_condset_ii (i1 (C2_cmpgt (i32 IntRegs:$Rt),
(i32 IntRegs:$Rs))),
0, 1))>,
Requires<[HasV4T]>;
@@ -2403,7 +2959,7 @@ def : Pat <(i32 (zext (i1 (setge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
// if (Pd.new) Rd=#0
// if (!Pd.new) Rd=#1
def : Pat <(i32 (zext (i1 (setule (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
- (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs),
+ (i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rs),
(i32 IntRegs:$Rt))),
0, 1))>,
Requires<[HasV4T]>;
@@ -2415,7 +2971,7 @@ def : Pat <(i32 (zext (i1 (setule (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
// if (Pd.new) Rd=#0
// if (!Pd.new) Rd=#1
def : Pat <(i32 (zext (i1 (setle (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
- (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rs),
+ (i32 (TFR_condset_ii (i1 (C2_cmpgt (i32 IntRegs:$Rs),
(i32 IntRegs:$Rt))),
0, 1))>,
Requires<[HasV4T]>;
@@ -2439,7 +2995,7 @@ def : Pat <(i32 (zext (i1 (setle (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
let AddedComplexity = 139 in
def : Pat <(i32 (zext (i1 (setult (i32 (and (i32 IntRegs:$src1), 255)),
u7StrictPosImmPred:$src2)))),
- (i32 (MUX_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$src1),
+ (i32 (C2_muxii (i1 (CMPbGTUri_V4 (i32 IntRegs:$src1),
(DEC_CONST_BYTE u7StrictPosImmPred:$src2))),
0, 1))>,
Requires<[HasV4T]>;
@@ -2566,17 +3122,61 @@ def NTSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
// XTYPE/PRED -
//===----------------------------------------------------------------------===//
-//Deallocate frame and return.
-// dealloc_return
-let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1,
- Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1 in {
-let validSubTargets = HasV4SubT in
- def DEALLOC_RET_V4 : LD0Inst<(outs), (ins),
- "dealloc_return",
- []>,
- Requires<[HasV4T]>;
+//===----------------------------------------------------------------------===//
+// Multiclass for DeallocReturn
+//===----------------------------------------------------------------------===//
+class L4_RETURN<string mnemonic, bit isNot, bit isPredNew, bit isTak>
+ : LD0Inst<(outs), (ins PredRegs:$src),
+ !if(isNot, "if (!$src", "if ($src")#
+ !if(isPredNew, ".new) ", ") ")#mnemonic#
+ !if(isPredNew, #!if(isTak,":t", ":nt"),""),
+ [], "", LD_tc_3or4stall_SLOT0> {
+
+ bits<2> src;
+ let BaseOpcode = "L4_RETURN";
+ let isPredicatedFalse = isNot;
+ let isPredicatedNew = isPredNew;
+ let isTaken = isTak;
+ let IClass = 0b1001;
+
+ let Inst{27-16} = 0b011000011110;
+
+ let Inst{13} = isNot;
+ let Inst{12} = isTak;
+ let Inst{11} = isPredNew;
+ let Inst{10} = 0b0;
+ let Inst{9-8} = src;
+ let Inst{4-0} = 0b11110;
+ }
+
+// Produce all predicated forms, p, !p, p.new, !p.new, :t, :nt
+multiclass L4_RETURN_PRED<string mnemonic, bit PredNot> {
+ let isPredicated = 1 in {
+ def _#NAME# : L4_RETURN <mnemonic, PredNot, 0, 1>;
+ def _#NAME#new_pnt : L4_RETURN <mnemonic, PredNot, 1, 0>;
+ def _#NAME#new_pt : L4_RETURN <mnemonic, PredNot, 1, 1>;
+ }
+}
+
+multiclass LD_MISC_L4_RETURN<string mnemonic> {
+ let isBarrier = 1, isPredicable = 1 in
+ def NAME : LD0Inst <(outs), (ins), mnemonic, [], "",
+ LD_tc_3or4stall_SLOT0> {
+ let BaseOpcode = "L4_RETURN";
+ let IClass = 0b1001;
+ let Inst{27-16} = 0b011000011110;
+ let Inst{13-10} = 0b0000;
+ let Inst{4-0} = 0b11110;
+ }
+ defm t : L4_RETURN_PRED<mnemonic, 0 >;
+ defm f : L4_RETURN_PRED<mnemonic, 1 >;
}
+let isReturn = 1, isTerminator = 1,
+ Defs = [R29, R30, R31, PC], Uses = [R30], hasSideEffects = 0,
+ validSubTargets = HasV4SubT, isCodeGenOnly = 0 in
+defm L4_return: LD_MISC_L4_RETURN <"dealloc_return">, PredNewRel;
+
// Restore registers and dealloc return function call.
let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
Defs = [R29, R30, R31, PC] in {
@@ -2609,454 +3209,579 @@ let isCall = 1, isBarrier = 1,
Requires<[HasV4T]>;
}
-// if (Ps) dealloc_return
-let isReturn = 1, isTerminator = 1,
- Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
- isPredicated = 1 in {
-let validSubTargets = HasV4SubT in
- def DEALLOC_RET_cPt_V4 : LD0Inst<(outs),
- (ins PredRegs:$src1),
- "if ($src1) dealloc_return",
- []>,
- Requires<[HasV4T]>;
-}
+//===----------------------------------------------------------------------===//
+// Template class for non predicated store instructions with
+// GP-Relative or absolute addressing.
+//===----------------------------------------------------------------------===//
+let hasSideEffects = 0, isPredicable = 1, isNVStorable = 1 in
+class T_StoreAbsGP <string mnemonic, RegisterClass RC, Operand ImmOp,
+ bits<2>MajOp, Operand AddrOp, bit isAbs, bit isHalf>
+ : STInst<(outs), (ins AddrOp:$addr, RC:$src),
+ mnemonic # !if(isAbs, "(##", "(#")#"$addr) = $src"#!if(isHalf, ".h",""),
+ [], "", V2LDST_tc_st_SLOT01> {
+ bits<19> addr;
+ bits<5> src;
+ bits<16> offsetBits;
+
+ string ImmOpStr = !cast<string>(ImmOp);
+ let offsetBits = !if (!eq(ImmOpStr, "u16_3Imm"), addr{18-3},
+ !if (!eq(ImmOpStr, "u16_2Imm"), addr{17-2},
+ !if (!eq(ImmOpStr, "u16_1Imm"), addr{16-1},
+ /* u16_0Imm */ addr{15-0})));
+ let IClass = 0b0100;
+ let Inst{27} = 1;
+ let Inst{26-25} = offsetBits{15-14};
+ let Inst{24} = 0b0;
+ let Inst{23-22} = MajOp;
+ let Inst{21} = isHalf;
+ let Inst{20-16} = offsetBits{13-9};
+ let Inst{13} = offsetBits{8};
+ let Inst{12-8} = src;
+ let Inst{7-0} = offsetBits{7-0};
+ }
-// if (!Ps) dealloc_return
-let isReturn = 1, isTerminator = 1,
- Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
- isPredicated = 1, isPredicatedFalse = 1 in {
-let validSubTargets = HasV4SubT in
- def DEALLOC_RET_cNotPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
- "if (!$src1) dealloc_return",
- []>,
- Requires<[HasV4T]>;
-}
+//===----------------------------------------------------------------------===//
+// Template class for predicated store instructions with
+// GP-Relative or absolute addressing.
+//===----------------------------------------------------------------------===//
+let hasSideEffects = 0, isPredicated = 1, isNVStorable = 1, opExtentBits = 6,
+ opExtendable = 1 in
+class T_StoreAbs_Pred <string mnemonic, RegisterClass RC, bits<2> MajOp,
+ bit isHalf, bit isNot, bit isNew>
+ : STInst<(outs), (ins PredRegs:$src1, u6Ext:$absaddr, RC: $src2),
+ !if(isNot, "if (!$src1", "if ($src1")#!if(isNew, ".new) ",
+ ") ")#mnemonic#"(#$absaddr) = $src2"#!if(isHalf, ".h",""),
+ [], "", ST_tc_st_SLOT01>, AddrModeRel {
+ bits<2> src1;
+ bits<6> absaddr;
+ bits<5> src2;
+
+ let isPredicatedNew = isNew;
+ let isPredicatedFalse = isNot;
+
+ let IClass = 0b1010;
-// if (Ps.new) dealloc_return:nt
-let isReturn = 1, isTerminator = 1,
- Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
- isPredicated = 1 in {
-let validSubTargets = HasV4SubT in
- def DEALLOC_RET_cdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
- "if ($src1.new) dealloc_return:nt",
- []>,
- Requires<[HasV4T]>;
-}
+ let Inst{27-24} = 0b1111;
+ let Inst{23-22} = MajOp;
+ let Inst{21} = isHalf;
+ let Inst{17-16} = absaddr{5-4};
+ let Inst{13} = isNew;
+ let Inst{12-8} = src2;
+ let Inst{7} = 0b1;
+ let Inst{6-3} = absaddr{3-0};
+ let Inst{2} = isNot;
+ let Inst{1-0} = src1;
+ }
-// if (!Ps.new) dealloc_return:nt
-let isReturn = 1, isTerminator = 1,
- Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
- isPredicated = 1, isPredicatedFalse = 1 in {
-let validSubTargets = HasV4SubT in
- def DEALLOC_RET_cNotdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
- "if (!$src1.new) dealloc_return:nt",
- []>,
- Requires<[HasV4T]>;
+//===----------------------------------------------------------------------===//
+// Template class for predicated store instructions with absolute addressing.
+//===----------------------------------------------------------------------===//
+class T_StoreAbs <string mnemonic, RegisterClass RC, Operand ImmOp,
+ bits<2> MajOp, bit isHalf>
+ : T_StoreAbsGP <mnemonic, RC, ImmOp, MajOp, u0AlwaysExt, 1, isHalf>,
+ AddrModeRel {
+ string ImmOpStr = !cast<string>(ImmOp);
+ let opExtentBits = !if (!eq(ImmOpStr, "u16_3Imm"), 19,
+ !if (!eq(ImmOpStr, "u16_2Imm"), 18,
+ !if (!eq(ImmOpStr, "u16_1Imm"), 17,
+ /* u16_0Imm */ 16)));
+
+ let opExtentAlign = !if (!eq(ImmOpStr, "u16_3Imm"), 3,
+ !if (!eq(ImmOpStr, "u16_2Imm"), 2,
+ !if (!eq(ImmOpStr, "u16_1Imm"), 1,
+ /* u16_0Imm */ 0)));
}
-// if (Ps.new) dealloc_return:t
-let isReturn = 1, isTerminator = 1,
- Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
- isPredicated = 1 in {
-let validSubTargets = HasV4SubT in
- def DEALLOC_RET_cdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
- "if ($src1.new) dealloc_return:t",
- []>,
- Requires<[HasV4T]>;
-}
+//===----------------------------------------------------------------------===//
+// Multiclass for store instructions with absolute addressing.
+//===----------------------------------------------------------------------===//
+let validSubTargets = HasV4SubT, addrMode = Absolute, isExtended = 1 in
+multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC,
+ Operand ImmOp, bits<2> MajOp, bit isHalf = 0> {
+ let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
+ let opExtendable = 0, isPredicable = 1 in
+ def S2_#NAME#abs : T_StoreAbs <mnemonic, RC, ImmOp, MajOp, isHalf>;
-// if (!Ps.new) dealloc_return:nt
-let isReturn = 1, isTerminator = 1,
- Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
- isPredicated = 1, isPredicatedFalse = 1 in {
-let validSubTargets = HasV4SubT in
- def DEALLOC_RET_cNotdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
- "if (!$src1.new) dealloc_return:t",
- []>,
- Requires<[HasV4T]>;
+ // Predicated
+ def S4_p#NAME#t_abs : T_StoreAbs_Pred<mnemonic, RC, MajOp, isHalf, 0, 0>;
+ def S4_p#NAME#f_abs : T_StoreAbs_Pred<mnemonic, RC, MajOp, isHalf, 1, 0>;
+
+ // .new Predicated
+ def S4_p#NAME#tnew_abs : T_StoreAbs_Pred<mnemonic, RC, MajOp, isHalf, 0, 1>;
+ def S4_p#NAME#fnew_abs : T_StoreAbs_Pred<mnemonic, RC, MajOp, isHalf, 1, 1>;
+ }
}
-// Load/Store with absolute addressing mode
-// memw(#u6)=Rt
+//===----------------------------------------------------------------------===//
+// Template class for non predicated new-value store instructions with
+// GP-Relative or absolute addressing.
+//===----------------------------------------------------------------------===//
+let hasSideEffects = 0, isPredicable = 1, mayStore = 1, isNVStore = 1,
+ isNewValue = 1, opNewValue = 1 in
+class T_StoreAbsGP_NV <string mnemonic, Operand ImmOp, bits<2>MajOp, bit isAbs>
+ : NVInst_V4<(outs), (ins u0AlwaysExt:$addr, IntRegs:$src),
+ mnemonic # !if(isAbs, "(##", "(#")#"$addr) = $src.new",
+ [], "", V2LDST_tc_st_SLOT0> {
+ bits<19> addr;
+ bits<3> src;
+ bits<16> offsetBits;
+
+ string ImmOpStr = !cast<string>(ImmOp);
+ let offsetBits = !if (!eq(ImmOpStr, "u16_3Imm"), addr{18-3},
+ !if (!eq(ImmOpStr, "u16_2Imm"), addr{17-2},
+ !if (!eq(ImmOpStr, "u16_1Imm"), addr{16-1},
+ /* u16_0Imm */ addr{15-0})));
+ let IClass = 0b0100;
+
+ let Inst{27} = 1;
+ let Inst{26-25} = offsetBits{15-14};
+ let Inst{24-21} = 0b0101;
+ let Inst{20-16} = offsetBits{13-9};
+ let Inst{13} = offsetBits{8};
+ let Inst{12-11} = MajOp;
+ let Inst{10-8} = src;
+ let Inst{7-0} = offsetBits{7-0};
+ }
-multiclass ST_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
- bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME#_V4 : STInst2<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#mnemonic#"(##$absaddr) = $src2",
- []>,
- Requires<[HasV4T]>;
+//===----------------------------------------------------------------------===//
+// Template class for predicated new-value store instructions with
+// absolute addressing.
+//===----------------------------------------------------------------------===//
+let hasSideEffects = 0, isPredicated = 1, mayStore = 1, isNVStore = 1,
+ isNewValue = 1, opNewValue = 2, opExtentBits = 6, opExtendable = 1 in
+class T_StoreAbs_NV_Pred <string mnemonic, bits<2> MajOp, bit isNot, bit isNew>
+ : NVInst_V4<(outs), (ins PredRegs:$src1, u6Ext:$absaddr, IntRegs:$src2),
+ !if(isNot, "if (!$src1", "if ($src1")#!if(isNew, ".new) ",
+ ") ")#mnemonic#"(#$absaddr) = $src2.new",
+ [], "", ST_tc_st_SLOT0>, AddrModeRel {
+ bits<2> src1;
+ bits<6> absaddr;
+ bits<3> src2;
+
+ let isPredicatedNew = isNew;
+ let isPredicatedFalse = isNot;
+
+ let IClass = 0b1010;
+
+ let Inst{27-24} = 0b1111;
+ let Inst{23-21} = 0b101;
+ let Inst{17-16} = absaddr{5-4};
+ let Inst{13} = isNew;
+ let Inst{12-11} = MajOp;
+ let Inst{10-8} = src2;
+ let Inst{7} = 0b1;
+ let Inst{6-3} = absaddr{3-0};
+ let Inst{2} = isNot;
+ let Inst{1-0} = src1;
}
-multiclass ST_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 0>;
- // Predicate new
- defm _cdn#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 1>;
- }
+//===----------------------------------------------------------------------===//
+// Template class for non-predicated new-value store instructions with
+// absolute addressing.
+//===----------------------------------------------------------------------===//
+class T_StoreAbs_NV <string mnemonic, Operand ImmOp, bits<2> MajOp>
+ : T_StoreAbsGP_NV <mnemonic, ImmOp, MajOp, 1>, AddrModeRel {
+
+ string ImmOpStr = !cast<string>(ImmOp);
+ let opExtentBits = !if (!eq(ImmOpStr, "u16_3Imm"), 19,
+ !if (!eq(ImmOpStr, "u16_2Imm"), 18,
+ !if (!eq(ImmOpStr, "u16_1Imm"), 17,
+ /* u16_0Imm */ 16)));
+
+ let opExtentAlign = !if (!eq(ImmOpStr, "u16_3Imm"), 3,
+ !if (!eq(ImmOpStr, "u16_2Imm"), 2,
+ !if (!eq(ImmOpStr, "u16_1Imm"), 1,
+ /* u16_0Imm */ 0)));
}
-let isNVStorable = 1, isExtended = 1, neverHasSideEffects = 1 in
-multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC> {
+//===----------------------------------------------------------------------===//
+// Multiclass for new-value store instructions with absolute addressing.
+//===----------------------------------------------------------------------===//
+let validSubTargets = HasV4SubT, addrMode = Absolute, isExtended = 1 in
+multiclass ST_Abs_NV <string mnemonic, string CextOp, Operand ImmOp,
+ bits<2> MajOp> {
let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
let opExtendable = 0, isPredicable = 1 in
- def NAME#_V4 : STInst2<(outs),
- (ins u0AlwaysExt:$absaddr, RC:$src),
- mnemonic#"(##$absaddr) = $src",
- []>,
- Requires<[HasV4T]>;
+ def S2_#NAME#newabs : T_StoreAbs_NV <mnemonic, ImmOp, MajOp>;
- let opExtendable = 1, isPredicated = 1 in {
- defm Pt : ST_Abs_Pred<mnemonic, RC, 0>;
- defm NotPt : ST_Abs_Pred<mnemonic, RC, 1>;
- }
+ // Predicated
+ def S4_p#NAME#newt_abs : T_StoreAbs_NV_Pred <mnemonic, MajOp, 0, 0>;
+ def S4_p#NAME#newf_abs : T_StoreAbs_NV_Pred <mnemonic, MajOp, 1, 0>;
+
+ // .new Predicated
+ def S4_p#NAME#newtnew_abs : T_StoreAbs_NV_Pred <mnemonic, MajOp, 0, 1>;
+ def S4_p#NAME#newfnew_abs : T_StoreAbs_NV_Pred <mnemonic, MajOp, 1, 1>;
}
}
-multiclass ST_Abs_Predbase_nv<string mnemonic, RegisterClass RC, bit isNot,
- bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME#_nv_V4 : NVInst_V4<(outs),
- (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#mnemonic#"(##$absaddr) = $src2.new",
- []>,
- Requires<[HasV4T]>;
-}
+//===----------------------------------------------------------------------===//
+// Stores with absolute addressing
+//===----------------------------------------------------------------------===//
+let accessSize = ByteAccess, isCodeGenOnly = 0 in
+defm storerb : ST_Abs <"memb", "STrib", IntRegs, u16_0Imm, 0b00>,
+ ST_Abs_NV <"memb", "STrib", u16_0Imm, 0b00>;
-multiclass ST_Abs_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 0>;
- // Predicate new
- defm _cdn#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 1>;
- }
-}
+let accessSize = HalfWordAccess, isCodeGenOnly = 0 in
+defm storerh : ST_Abs <"memh", "STrih", IntRegs, u16_1Imm, 0b01>,
+ ST_Abs_NV <"memh", "STrih", u16_1Imm, 0b01>;
-let mayStore = 1, isNVStore = 1, isExtended = 1, neverHasSideEffects = 1 in
-multiclass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> {
- let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
- let opExtendable = 0, isPredicable = 1 in
- def NAME#_nv_V4 : NVInst_V4<(outs),
- (ins u0AlwaysExt:$absaddr, RC:$src),
- mnemonic#"(##$absaddr) = $src.new",
- []>,
- Requires<[HasV4T]>;
+let accessSize = WordAccess, isCodeGenOnly = 0 in
+defm storeri : ST_Abs <"memw", "STriw", IntRegs, u16_2Imm, 0b10>,
+ ST_Abs_NV <"memw", "STriw", u16_2Imm, 0b10>;
- let opExtendable = 1, isPredicated = 1 in {
- defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>;
- defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>;
- }
+let isNVStorable = 0, accessSize = DoubleWordAccess, isCodeGenOnly = 0 in
+defm storerd : ST_Abs <"memd", "STrid", DoubleRegs, u16_3Imm, 0b11>;
+
+let isNVStorable = 0, accessSize = HalfWordAccess, isCodeGenOnly = 0 in
+defm storerf : ST_Abs <"memh", "STrif", IntRegs, u16_1Imm, 0b01, 1>;
+
+//===----------------------------------------------------------------------===//
+// GP-relative stores.
+// mem[bhwd](#global)=Rt
+// Once predicated, these instructions map to absolute addressing mode.
+// if ([!]Pv[.new]) mem[bhwd](##global)=Rt
+//===----------------------------------------------------------------------===//
+
+let validSubTargets = HasV4SubT in
+class T_StoreGP <string mnemonic, string BaseOp, RegisterClass RC,
+ Operand ImmOp, bits<2> MajOp, bit isHalf = 0>
+ : T_StoreAbsGP <mnemonic, RC, ImmOp, MajOp, globaladdress, 0, isHalf> {
+ // Set BaseOpcode same as absolute addressing instructions so that
+ // non-predicated GP-Rel instructions can have relate with predicated
+ // Absolute instruction.
+ let BaseOpcode = BaseOp#_abs;
+ }
+
+let validSubTargets = HasV4SubT in
+multiclass ST_GP <string mnemonic, string BaseOp, Operand ImmOp,
+ bits<2> MajOp, bit isHalf = 0> {
+ // Set BaseOpcode same as absolute addressing instructions so that
+ // non-predicated GP-Rel instructions can have relate with predicated
+ // Absolute instruction.
+ let BaseOpcode = BaseOp#_abs in {
+ def NAME#gp : T_StoreAbsGP <mnemonic, IntRegs, ImmOp, MajOp,
+ globaladdress, 0, isHalf>;
+ // New-value store
+ def NAME#newgp : T_StoreAbsGP_NV <mnemonic, ImmOp, MajOp, 0> ;
}
}
-let addrMode = Absolute in {
- let accessSize = ByteAccess in
- defm STrib_abs : ST_Abs<"memb", "STrib", IntRegs>,
- ST_Abs_nv<"memb", "STrib", IntRegs>, AddrModeRel;
+let accessSize = ByteAccess in
+defm S2_storerb : ST_GP<"memb", "STrib", u16_0Imm, 0b00>, NewValueRel;
- let accessSize = HalfWordAccess in
- defm STrih_abs : ST_Abs<"memh", "STrih", IntRegs>,
- ST_Abs_nv<"memh", "STrih", IntRegs>, AddrModeRel;
+let accessSize = HalfWordAccess in
+defm S2_storerh : ST_GP<"memh", "STrih", u16_1Imm, 0b01>, NewValueRel;
- let accessSize = WordAccess in
- defm STriw_abs : ST_Abs<"memw", "STriw", IntRegs>,
- ST_Abs_nv<"memw", "STriw", IntRegs>, AddrModeRel;
+let accessSize = WordAccess in
+defm S2_storeri : ST_GP<"memw", "STriw", u16_2Imm, 0b10>, NewValueRel;
- let accessSize = DoubleWordAccess, isNVStorable = 0 in
- defm STrid_abs : ST_Abs<"memd", "STrid", DoubleRegs>, AddrModeRel;
-}
+let isNVStorable = 0, accessSize = DoubleWordAccess in
+def S2_storerdgp : T_StoreGP <"memd", "STrid", DoubleRegs,
+ u16_3Imm, 0b11>, PredNewRel;
+
+let isNVStorable = 0, accessSize = HalfWordAccess in
+def S2_storerfgp : T_StoreGP <"memh", "STrif", IntRegs,
+ u16_1Imm, 0b01, 1>, PredNewRel;
let Predicates = [HasV4T], AddedComplexity = 30 in {
def : Pat<(truncstorei8 (i32 IntRegs:$src1),
(HexagonCONST32 tglobaladdr:$absaddr)),
- (STrib_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
+ (S2_storerbabs tglobaladdr: $absaddr, IntRegs: $src1)>;
def : Pat<(truncstorei16 (i32 IntRegs:$src1),
(HexagonCONST32 tglobaladdr:$absaddr)),
- (STrih_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
+ (S2_storerhabs tglobaladdr: $absaddr, IntRegs: $src1)>;
def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32 tglobaladdr:$absaddr)),
- (STriw_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
+ (S2_storeriabs tglobaladdr: $absaddr, IntRegs: $src1)>;
def : Pat<(store (i64 DoubleRegs:$src1),
(HexagonCONST32 tglobaladdr:$absaddr)),
- (STrid_abs_V4 tglobaladdr: $absaddr, DoubleRegs: $src1)>;
-}
-
-//===----------------------------------------------------------------------===//
-// multiclass for store instructions with GP-relative addressing mode.
-// mem[bhwd](#global)=Rt
-// if ([!]Pv[.new]) mem[bhwd](##global) = Rt
-//===----------------------------------------------------------------------===//
-let mayStore = 1, isNVStorable = 1 in
-multiclass ST_GP<string mnemonic, string BaseOp, RegisterClass RC> {
- let BaseOpcode = BaseOp, isPredicable = 1 in
- def NAME#_V4 : STInst2<(outs),
- (ins globaladdress:$global, RC:$src),
- mnemonic#"(#$global) = $src",
- []>;
-
- // When GP-relative instructions are predicated, their addressing mode is
- // changed to absolute and they are always constant extended.
- let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1,
- isPredicated = 1 in {
- defm Pt : ST_Abs_Pred <mnemonic, RC, 0>;
- defm NotPt : ST_Abs_Pred <mnemonic, RC, 1>;
- }
-}
-
-let mayStore = 1, isNVStore = 1 in
-multiclass ST_GP_nv<string mnemonic, string BaseOp, RegisterClass RC> {
- let BaseOpcode = BaseOp, isPredicable = 1 in
- def NAME#_nv_V4 : NVInst_V4<(outs),
- (ins u0AlwaysExt:$global, RC:$src),
- mnemonic#"(#$global) = $src.new",
- []>,
- Requires<[HasV4T]>;
-
- // When GP-relative instructions are predicated, their addressing mode is
- // changed to absolute and they are always constant extended.
- let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1,
- isPredicated = 1 in {
- defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>;
- defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>;
- }
-}
-
-let validSubTargets = HasV4SubT, neverHasSideEffects = 1 in {
- let isNVStorable = 0 in
- defm STd_GP : ST_GP <"memd", "STd_GP", DoubleRegs>, PredNewRel;
-
- defm STb_GP : ST_GP<"memb", "STb_GP", IntRegs>,
- ST_GP_nv<"memb", "STb_GP", IntRegs>, NewValueRel;
- defm STh_GP : ST_GP<"memh", "STh_GP", IntRegs>,
- ST_GP_nv<"memh", "STh_GP", IntRegs>, NewValueRel;
- defm STw_GP : ST_GP<"memw", "STw_GP", IntRegs>,
- ST_GP_nv<"memw", "STw_GP", IntRegs>, NewValueRel;
+ (S2_storerdabs tglobaladdr: $absaddr, DoubleRegs: $src1)>;
}
// 64 bit atomic store
def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
(i64 DoubleRegs:$src1)),
- (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
+ (S2_storerdgp tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
Requires<[HasV4T]>;
// Map from store(globaladdress) -> memd(#foo)
let AddedComplexity = 100 in
def : Pat <(store (i64 DoubleRegs:$src1),
(HexagonCONST32_GP tglobaladdr:$global)),
- (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>;
+ (S2_storerdgp tglobaladdr:$global, (i64 DoubleRegs:$src1))>;
// 8 bit atomic store
def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
(i32 IntRegs:$src1)),
- (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+ (S2_storerbgp tglobaladdr:$global, (i32 IntRegs:$src1))>;
// Map from store(globaladdress) -> memb(#foo)
let AddedComplexity = 100 in
def : Pat<(truncstorei8 (i32 IntRegs:$src1),
(HexagonCONST32_GP tglobaladdr:$global)),
- (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+ (S2_storerbgp tglobaladdr:$global, (i32 IntRegs:$src1))>;
// Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
// to "r0 = 1; memw(#foo) = r0"
let AddedComplexity = 100 in
def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
- (STb_GP_V4 tglobaladdr:$global, (TFRI 1))>;
+ (S2_storerbgp tglobaladdr:$global, (A2_tfrsi 1))>;
def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
(i32 IntRegs:$src1)),
- (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+ (S2_storerhgp tglobaladdr:$global, (i32 IntRegs:$src1))>;
// Map from store(globaladdress) -> memh(#foo)
let AddedComplexity = 100 in
def : Pat<(truncstorei16 (i32 IntRegs:$src1),
(HexagonCONST32_GP tglobaladdr:$global)),
- (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+ (S2_storerhgp tglobaladdr:$global, (i32 IntRegs:$src1))>;
// 32 bit atomic store
def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
(i32 IntRegs:$src1)),
- (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+ (S2_storerigp tglobaladdr:$global, (i32 IntRegs:$src1))>;
// Map from store(globaladdress) -> memw(#foo)
let AddedComplexity = 100 in
def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
- (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
+ (S2_storerigp tglobaladdr:$global, (i32 IntRegs:$src1))>;
//===----------------------------------------------------------------------===//
-// Multiclass for the load instructions with absolute addressing mode.
+// Template class for non predicated load instructions with
+// absolute addressing mode.
//===----------------------------------------------------------------------===//
-multiclass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
- bit isPredNew> {
- let isPredicatedNew = isPredNew in
- def NAME : LDInst2<(outs RC:$dst),
- (ins PredRegs:$src1, u0AlwaysExt:$absaddr),
- !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
- ") ")#"$dst = "#mnemonic#"(##$absaddr)",
- []>,
- Requires<[HasV4T]>;
-}
+let isPredicable = 1, hasSideEffects = 0, validSubTargets = HasV4SubT in
+class T_LoadAbsGP <string mnemonic, RegisterClass RC, Operand ImmOp,
+ bits<3> MajOp, Operand AddrOp, bit isAbs>
+ : LDInst <(outs RC:$dst), (ins AddrOp:$addr),
+ "$dst = "#mnemonic# !if(isAbs, "(##", "(#")#"$addr)",
+ [], "", V2LDST_tc_ld_SLOT01> {
+ bits<5> dst;
+ bits<19> addr;
+ bits<16> offsetBits;
+
+ string ImmOpStr = !cast<string>(ImmOp);
+ let offsetBits = !if (!eq(ImmOpStr, "u16_3Imm"), addr{18-3},
+ !if (!eq(ImmOpStr, "u16_2Imm"), addr{17-2},
+ !if (!eq(ImmOpStr, "u16_1Imm"), addr{16-1},
+ /* u16_0Imm */ addr{15-0})));
+
+ let IClass = 0b0100;
+
+ let Inst{27} = 0b1;
+ let Inst{26-25} = offsetBits{15-14};
+ let Inst{24} = 0b1;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = offsetBits{13-9};
+ let Inst{13-5} = offsetBits{8-0};
+ let Inst{4-0} = dst;
+ }
+
+class T_LoadAbs <string mnemonic, RegisterClass RC, Operand ImmOp,
+ bits<3> MajOp>
+ : T_LoadAbsGP <mnemonic, RC, ImmOp, MajOp, u0AlwaysExt, 1>, AddrModeRel {
-multiclass LD_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
- let isPredicatedFalse = PredNot in {
- defm _c#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 0>;
- // Predicate new
- defm _cdn#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 1>;
+ string ImmOpStr = !cast<string>(ImmOp);
+ let opExtentBits = !if (!eq(ImmOpStr, "u16_3Imm"), 19,
+ !if (!eq(ImmOpStr, "u16_2Imm"), 18,
+ !if (!eq(ImmOpStr, "u16_1Imm"), 17,
+ /* u16_0Imm */ 16)));
+
+ let opExtentAlign = !if (!eq(ImmOpStr, "u16_3Imm"), 3,
+ !if (!eq(ImmOpStr, "u16_2Imm"), 2,
+ !if (!eq(ImmOpStr, "u16_1Imm"), 1,
+ /* u16_0Imm */ 0)));
}
+//===----------------------------------------------------------------------===//
+// Template class for predicated load instructions with
+// absolute addressing mode.
+//===----------------------------------------------------------------------===//
+let isPredicated = 1, hasNewValue = 1, opExtentBits = 6, opExtendable = 2 in
+class T_LoadAbs_Pred <string mnemonic, RegisterClass RC, bits<3> MajOp,
+ bit isPredNot, bit isPredNew>
+ : LDInst <(outs RC:$dst), (ins PredRegs:$src1, u6Ext:$absaddr),
+ !if(isPredNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
+ ") ")#"$dst = "#mnemonic#"(#$absaddr)">, AddrModeRel {
+ bits<5> dst;
+ bits<2> src1;
+ bits<6> absaddr;
+
+ let isPredicatedNew = isPredNew;
+ let isPredicatedFalse = isPredNot;
+
+ let IClass = 0b1001;
+
+ let Inst{27-24} = 0b1111;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = absaddr{5-1};
+ let Inst{13} = 0b1;
+ let Inst{12} = isPredNew;
+ let Inst{11} = isPredNot;
+ let Inst{10-9} = src1;
+ let Inst{8} = absaddr{0};
+ let Inst{7} = 0b1;
+ let Inst{4-0} = dst;
+ }
+
+//===----------------------------------------------------------------------===//
+// Multiclass for the load instructions with absolute addressing mode.
+//===----------------------------------------------------------------------===//
+multiclass LD_Abs_Pred<string mnemonic, RegisterClass RC, bits<3> MajOp,
+ bit PredNot> {
+ def _abs : T_LoadAbs_Pred <mnemonic, RC, MajOp, PredNot, 0>;
+ // Predicate new
+ def new_abs : T_LoadAbs_Pred <mnemonic, RC, MajOp, PredNot, 1>;
}
-let isExtended = 1, neverHasSideEffects = 1 in
-multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> {
+let addrMode = Absolute, isExtended = 1 in
+multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC,
+ Operand ImmOp, bits<3> MajOp> {
let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
- let opExtendable = 1, isPredicable = 1 in
- def NAME#_V4 : LDInst2<(outs RC:$dst),
- (ins u0AlwaysExt:$absaddr),
- "$dst = "#mnemonic#"(##$absaddr)",
- []>,
- Requires<[HasV4T]>;
+ let opExtendable = 1, isPredicable = 1 in
+ def L4_#NAME#_abs: T_LoadAbs <mnemonic, RC, ImmOp, MajOp>;
- let opExtendable = 2, isPredicated = 1 in {
- defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>;
- defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>;
- }
+ // Predicated
+ defm L4_p#NAME#t : LD_Abs_Pred<mnemonic, RC, MajOp, 0>;
+ defm L4_p#NAME#f : LD_Abs_Pred<mnemonic, RC, MajOp, 1>;
}
}
-let addrMode = Absolute in {
- let accessSize = ByteAccess in {
- defm LDrib_abs : LD_Abs<"memb", "LDrib", IntRegs>, AddrModeRel;
- defm LDriub_abs : LD_Abs<"memub", "LDriub", IntRegs>, AddrModeRel;
- }
- let accessSize = HalfWordAccess in {
- defm LDrih_abs : LD_Abs<"memh", "LDrih", IntRegs>, AddrModeRel;
- defm LDriuh_abs : LD_Abs<"memuh", "LDriuh", IntRegs>, AddrModeRel;
+let accessSize = ByteAccess, hasNewValue = 1, isCodeGenOnly = 0 in {
+ defm loadrb : LD_Abs<"memb", "LDrib", IntRegs, u16_0Imm, 0b000>;
+ defm loadrub : LD_Abs<"memub", "LDriub", IntRegs, u16_0Imm, 0b001>;
+}
+
+let accessSize = HalfWordAccess, hasNewValue = 1, isCodeGenOnly = 0 in {
+ defm loadrh : LD_Abs<"memh", "LDrih", IntRegs, u16_1Imm, 0b010>;
+ defm loadruh : LD_Abs<"memuh", "LDriuh", IntRegs, u16_1Imm, 0b011>;
+}
+
+let accessSize = WordAccess, hasNewValue = 1, isCodeGenOnly = 0 in
+defm loadri : LD_Abs<"memw", "LDriw", IntRegs, u16_2Imm, 0b100>;
+
+let accessSize = DoubleWordAccess, isCodeGenOnly = 0 in
+defm loadrd : LD_Abs<"memd", "LDrid", DoubleRegs, u16_3Imm, 0b110>;
+
+//===----------------------------------------------------------------------===//
+// multiclass for load instructions with GP-relative addressing mode.
+// Rx=mem[bhwd](##global)
+// Once predicated, these instructions map to absolute addressing mode.
+// if ([!]Pv[.new]) Rx=mem[bhwd](##global)
+//===----------------------------------------------------------------------===//
+
+class T_LoadGP <string mnemonic, string BaseOp, RegisterClass RC, Operand ImmOp,
+ bits<3> MajOp>
+ : T_LoadAbsGP <mnemonic, RC, ImmOp, MajOp, globaladdress, 0>, PredNewRel {
+ let BaseOpcode = BaseOp#_abs;
}
- let accessSize = WordAccess in
- defm LDriw_abs : LD_Abs<"memw", "LDriw", IntRegs>, AddrModeRel;
- let accessSize = DoubleWordAccess in
- defm LDrid_abs : LD_Abs<"memd", "LDrid", DoubleRegs>, AddrModeRel;
+let accessSize = ByteAccess, hasNewValue = 1 in {
+ def L2_loadrbgp : T_LoadGP<"memb", "LDrib", IntRegs, u16_0Imm, 0b000>;
+ def L2_loadrubgp : T_LoadGP<"memub", "LDriub", IntRegs, u16_0Imm, 0b001>;
+}
+
+let accessSize = HalfWordAccess, hasNewValue = 1 in {
+ def L2_loadrhgp : T_LoadGP<"memh", "LDrih", IntRegs, u16_1Imm, 0b010>;
+ def L2_loadruhgp : T_LoadGP<"memuh", "LDriuh", IntRegs, u16_1Imm, 0b011>;
}
+let accessSize = WordAccess, hasNewValue = 1 in
+def L2_loadrigp : T_LoadGP<"memw", "LDriw", IntRegs, u16_2Imm, 0b100>;
+
+let accessSize = DoubleWordAccess in
+def L2_loadrdgp : T_LoadGP<"memd", "LDrid", DoubleRegs, u16_3Imm, 0b110>;
+
let Predicates = [HasV4T], AddedComplexity = 30 in {
def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))),
- (LDriw_abs_V4 tglobaladdr: $absaddr)>;
+ (L4_loadri_abs tglobaladdr: $absaddr)>;
def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
- (LDrib_abs_V4 tglobaladdr:$absaddr)>;
+ (L4_loadrb_abs tglobaladdr:$absaddr)>;
def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
- (LDriub_abs_V4 tglobaladdr:$absaddr)>;
+ (L4_loadrub_abs tglobaladdr:$absaddr)>;
def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
- (LDrih_abs_V4 tglobaladdr:$absaddr)>;
+ (L4_loadrh_abs tglobaladdr:$absaddr)>;
def : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
- (LDriuh_abs_V4 tglobaladdr:$absaddr)>;
-}
-
-//===----------------------------------------------------------------------===//
-// multiclass for load instructions with GP-relative addressing mode.
-// Rx=mem[bhwd](##global)
-// if ([!]Pv[.new]) Rx=mem[bhwd](##global)
-//===----------------------------------------------------------------------===//
-let neverHasSideEffects = 1, validSubTargets = HasV4SubT in
-multiclass LD_GP<string mnemonic, string BaseOp, RegisterClass RC> {
- let BaseOpcode = BaseOp in {
- let isPredicable = 1 in
- def NAME#_V4 : LDInst2<(outs RC:$dst),
- (ins globaladdress:$global),
- "$dst = "#mnemonic#"(#$global)",
- []>;
-
- let isExtended = 1, opExtendable = 2, isPredicated = 1 in {
- defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>;
- defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>;
- }
- }
+ (L4_loadruh_abs tglobaladdr:$absaddr)>;
}
-defm LDd_GP : LD_GP<"memd", "LDd_GP", DoubleRegs>, PredNewRel;
-defm LDb_GP : LD_GP<"memb", "LDb_GP", IntRegs>, PredNewRel;
-defm LDub_GP : LD_GP<"memub", "LDub_GP", IntRegs>, PredNewRel;
-defm LDh_GP : LD_GP<"memh", "LDh_GP", IntRegs>, PredNewRel;
-defm LDuh_GP : LD_GP<"memuh", "LDuh_GP", IntRegs>, PredNewRel;
-defm LDw_GP : LD_GP<"memw", "LDw_GP", IntRegs>, PredNewRel;
-
def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
- (i64 (LDd_GP_V4 tglobaladdr:$global))>;
+ (i64 (L2_loadrdgp tglobaladdr:$global))>;
def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
- (i32 (LDw_GP_V4 tglobaladdr:$global))>;
+ (i32 (L2_loadrigp tglobaladdr:$global))>;
def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
- (i32 (LDuh_GP_V4 tglobaladdr:$global))>;
+ (i32 (L2_loadruhgp tglobaladdr:$global))>;
def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
- (i32 (LDub_GP_V4 tglobaladdr:$global))>;
+ (i32 (L2_loadrubgp tglobaladdr:$global))>;
// Map from load(globaladdress) -> memw(#foo + 0)
let AddedComplexity = 100 in
def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
- (i64 (LDd_GP_V4 tglobaladdr:$global))>;
+ (i64 (L2_loadrdgp tglobaladdr:$global))>;
// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd
let AddedComplexity = 100 in
def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
- (i1 (TFR_PdRs (i32 (LDb_GP_V4 tglobaladdr:$global))))>;
+ (i1 (C2_tfrrp (i32 (L2_loadrbgp tglobaladdr:$global))))>;
// When the Interprocedural Global Variable optimizer realizes that a certain
// global variable takes only two constant values, it shrinks the global to
// a boolean. Catch those loads here in the following 3 patterns.
let AddedComplexity = 100 in
def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP_V4 tglobaladdr:$global))>;
+ (i32 (L2_loadrbgp tglobaladdr:$global))>;
let AddedComplexity = 100 in
def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP_V4 tglobaladdr:$global))>;
+ (i32 (L2_loadrbgp tglobaladdr:$global))>;
// Map from load(globaladdress) -> memb(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP_V4 tglobaladdr:$global))>;
+ (i32 (L2_loadrbgp tglobaladdr:$global))>;
// Map from load(globaladdress) -> memb(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDb_GP_V4 tglobaladdr:$global))>;
+ (i32 (L2_loadrbgp tglobaladdr:$global))>;
let AddedComplexity = 100 in
def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDub_GP_V4 tglobaladdr:$global))>;
+ (i32 (L2_loadrubgp tglobaladdr:$global))>;
// Map from load(globaladdress) -> memub(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDub_GP_V4 tglobaladdr:$global))>;
+ (i32 (L2_loadrubgp tglobaladdr:$global))>;
// Map from load(globaladdress) -> memh(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDh_GP_V4 tglobaladdr:$global))>;
+ (i32 (L2_loadrhgp tglobaladdr:$global))>;
// Map from load(globaladdress) -> memh(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDh_GP_V4 tglobaladdr:$global))>;
+ (i32 (L2_loadrhgp tglobaladdr:$global))>;
// Map from load(globaladdress) -> memuh(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDuh_GP_V4 tglobaladdr:$global))>;
+ (i32 (L2_loadruhgp tglobaladdr:$global))>;
// Map from load(globaladdress) -> memw(#foo)
let AddedComplexity = 100 in
def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
- (i32 (LDw_GP_V4 tglobaladdr:$global))>;
+ (i32 (L2_loadrigp tglobaladdr:$global))>;
// Transfer global address into a register
@@ -3073,7 +3798,7 @@ def : Pat<(HexagonCONST32_GP tblockaddress:$src1),
Requires<[HasV4T]>;
let isExtended = 1, opExtendable = 2, AddedComplexity=50,
-neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
+hasSideEffects = 0, isPredicated = 1, validSubTargets = HasV4SubT in
def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst),
(ins PredRegs:$src1, s16Ext:$src2),
"if($src1) $dst = #$src2",
@@ -3081,7 +3806,7 @@ def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst),
Requires<[HasV4T]>;
let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1,
-neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
+hasSideEffects = 0, isPredicated = 1, validSubTargets = HasV4SubT in
def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
(ins PredRegs:$src1, s16Ext:$src2),
"if(!$src1) $dst = #$src2",
@@ -3089,7 +3814,7 @@ def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
Requires<[HasV4T]>;
let isExtended = 1, opExtendable = 2, AddedComplexity=50,
-neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
+hasSideEffects = 0, isPredicated = 1, validSubTargets = HasV4SubT in
def TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst),
(ins PredRegs:$src1, s16Ext:$src2),
"if($src1.new) $dst = #$src2",
@@ -3097,7 +3822,7 @@ def TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst),
Requires<[HasV4T]>;
let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1,
-neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
+hasSideEffects = 0, isPredicated = 1, validSubTargets = HasV4SubT in
def TFRI_cdnNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
(ins PredRegs:$src1, s16Ext:$src2),
"if(!$src1.new) $dst = #$src2",
@@ -3157,30 +3882,30 @@ def : Pat <(i32 (zextloadi8 (add IntRegs:$src1,
let Predicates = [HasV4T], AddedComplexity = 30 in {
def : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
- (STrib_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
+ (S2_storerbabs u0AlwaysExtPred:$src2, IntRegs: $src1)>;
def : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
- (STrih_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
+ (S2_storerhabs u0AlwaysExtPred:$src2, IntRegs: $src1)>;
def : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
- (STriw_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
+ (S2_storeriabs u0AlwaysExtPred:$src2, IntRegs: $src1)>;
}
let Predicates = [HasV4T], AddedComplexity = 30 in {
def : Pat<(i32 (load u0AlwaysExtPred:$src)),
- (LDriw_abs_V4 u0AlwaysExtPred:$src)>;
+ (L4_loadri_abs u0AlwaysExtPred:$src)>;
def : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)),
- (LDrib_abs_V4 u0AlwaysExtPred:$src)>;
+ (L4_loadrb_abs u0AlwaysExtPred:$src)>;
def : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)),
- (LDriub_abs_V4 u0AlwaysExtPred:$src)>;
+ (L4_loadrub_abs u0AlwaysExtPred:$src)>;
def : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)),
- (LDrih_abs_V4 u0AlwaysExtPred:$src)>;
+ (L4_loadrh_abs u0AlwaysExtPred:$src)>;
def : Pat<(i32 (zextloadi16 u0AlwaysExtPred:$src)),
- (LDriuh_abs_V4 u0AlwaysExtPred:$src)>;
+ (L4_loadruh_abs u0AlwaysExtPred:$src)>;
}
// Indexed store word - global address.
@@ -3194,11 +3919,11 @@ def STriw_offset_ext_V4 : STInst<(outs),
Requires<[HasV4T]>;
def : Pat<(i64 (ctlz (i64 DoubleRegs:$src1))),
- (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTLZ64_rr DoubleRegs:$src1))))>,
+ (i64 (A4_combineir (i32 0), (i32 (CTLZ64_rr DoubleRegs:$src1))))>,
Requires<[HasV4T]>;
def : Pat<(i64 (cttz (i64 DoubleRegs:$src1))),
- (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTTZ64_rr DoubleRegs:$src1))))>,
+ (i64 (A4_combineir (i32 0), (i32 (CTTZ64_rr DoubleRegs:$src1))))>,
Requires<[HasV4T]>;
@@ -3207,49 +3932,49 @@ def : Pat<(i64 (cttz (i64 DoubleRegs:$src1))),
// zextloadi8.
let Predicates = [HasV4T], AddedComplexity = 120 in {
def: Pat <(i64 (extloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
- (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 tglobaladdr:$addr)))>;
+ (i64 (A4_combineir 0, (L4_loadrb_abs tglobaladdr:$addr)))>;
def: Pat <(i64 (zextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
- (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 tglobaladdr:$addr)))>;
+ (i64 (A4_combineir 0, (L4_loadrub_abs tglobaladdr:$addr)))>;
def: Pat <(i64 (sextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
- (i64 (SXTW (LDrib_abs_V4 tglobaladdr:$addr)))>;
+ (i64 (A2_sxtw (L4_loadrb_abs tglobaladdr:$addr)))>;
def: Pat <(i64 (extloadi8 FoldGlobalAddr:$addr)),
- (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 FoldGlobalAddr:$addr)))>;
+ (i64 (A4_combineir 0, (L4_loadrb_abs FoldGlobalAddr:$addr)))>;
def: Pat <(i64 (zextloadi8 FoldGlobalAddr:$addr)),
- (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 FoldGlobalAddr:$addr)))>;
+ (i64 (A4_combineir 0, (L4_loadrub_abs FoldGlobalAddr:$addr)))>;
def: Pat <(i64 (sextloadi8 FoldGlobalAddr:$addr)),
- (i64 (SXTW (LDrib_abs_V4 FoldGlobalAddr:$addr)))>;
+ (i64 (A2_sxtw (L4_loadrb_abs FoldGlobalAddr:$addr)))>;
}
// i16 -> i64 loads
// We need a complexity of 120 here to override preceding handling of
// zextloadi16.
let AddedComplexity = 120 in {
def: Pat <(i64 (extloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
- (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 tglobaladdr:$addr)))>,
+ (i64 (A4_combineir 0, (L4_loadrh_abs tglobaladdr:$addr)))>,
Requires<[HasV4T]>;
def: Pat <(i64 (zextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
- (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 tglobaladdr:$addr)))>,
+ (i64 (A4_combineir 0, (L4_loadruh_abs tglobaladdr:$addr)))>,
Requires<[HasV4T]>;
def: Pat <(i64 (sextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
- (i64 (SXTW (LDrih_abs_V4 tglobaladdr:$addr)))>,
+ (i64 (A2_sxtw (L4_loadrh_abs tglobaladdr:$addr)))>,
Requires<[HasV4T]>;
def: Pat <(i64 (extloadi16 FoldGlobalAddr:$addr)),
- (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 FoldGlobalAddr:$addr)))>,
+ (i64 (A4_combineir 0, (L4_loadrh_abs FoldGlobalAddr:$addr)))>,
Requires<[HasV4T]>;
def: Pat <(i64 (zextloadi16 FoldGlobalAddr:$addr)),
- (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 FoldGlobalAddr:$addr)))>,
+ (i64 (A4_combineir 0, (L4_loadruh_abs FoldGlobalAddr:$addr)))>,
Requires<[HasV4T]>;
def: Pat <(i64 (sextloadi16 FoldGlobalAddr:$addr)),
- (i64 (SXTW (LDrih_abs_V4 FoldGlobalAddr:$addr)))>,
+ (i64 (A2_sxtw (L4_loadrh_abs FoldGlobalAddr:$addr)))>,
Requires<[HasV4T]>;
}
// i32->i64 loads
@@ -3257,27 +3982,27 @@ def: Pat <(i64 (sextloadi16 FoldGlobalAddr:$addr)),
// zextloadi32.
let AddedComplexity = 120 in {
def: Pat <(i64 (extloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
- (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>,
+ (i64 (A4_combineir 0, (L4_loadri_abs tglobaladdr:$addr)))>,
Requires<[HasV4T]>;
def: Pat <(i64 (zextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
- (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>,
+ (i64 (A4_combineir 0, (L4_loadri_abs tglobaladdr:$addr)))>,
Requires<[HasV4T]>;
def: Pat <(i64 (sextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
- (i64 (SXTW (LDriw_abs_V4 tglobaladdr:$addr)))>,
+ (i64 (A2_sxtw (L4_loadri_abs tglobaladdr:$addr)))>,
Requires<[HasV4T]>;
def: Pat <(i64 (extloadi32 FoldGlobalAddr:$addr)),
- (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
+ (i64 (A4_combineir 0, (L4_loadri_abs FoldGlobalAddr:$addr)))>,
Requires<[HasV4T]>;
def: Pat <(i64 (zextloadi32 FoldGlobalAddr:$addr)),
- (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
+ (i64 (A4_combineir 0, (L4_loadri_abs FoldGlobalAddr:$addr)))>,
Requires<[HasV4T]>;
def: Pat <(i64 (sextloadi32 FoldGlobalAddr:$addr)),
- (i64 (SXTW (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
+ (i64 (A2_sxtw (L4_loadri_abs FoldGlobalAddr:$addr)))>,
Requires<[HasV4T]>;
}
@@ -3294,104 +4019,457 @@ def STrih_offset_ext_V4 : STInst<(outs),
let AddedComplexity = 100 in
def : Pat<(store (i64 DoubleRegs:$src1),
FoldGlobalAddrGP:$addr),
- (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
+ (S2_storerdabs FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
Requires<[HasV4T]>;
def : Pat<(atomic_store_64 FoldGlobalAddrGP:$addr,
(i64 DoubleRegs:$src1)),
- (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
+ (S2_storerdabs FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
Requires<[HasV4T]>;
// Map from store(globaladdress + x) -> memb(#foo + x)
let AddedComplexity = 100 in
def : Pat<(truncstorei8 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
- (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
+ (S2_storerbabs FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
Requires<[HasV4T]>;
def : Pat<(atomic_store_8 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
- (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
+ (S2_storerbabs FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
Requires<[HasV4T]>;
// Map from store(globaladdress + x) -> memh(#foo + x)
let AddedComplexity = 100 in
def : Pat<(truncstorei16 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
- (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
+ (S2_storerhabs FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
Requires<[HasV4T]>;
def : Pat<(atomic_store_16 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
- (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
+ (S2_storerhabs FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
Requires<[HasV4T]>;
// Map from store(globaladdress + x) -> memw(#foo + x)
let AddedComplexity = 100 in
def : Pat<(store (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
- (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
+ (S2_storeriabs FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
Requires<[HasV4T]>;
def : Pat<(atomic_store_32 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
- (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
+ (S2_storeriabs FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
Requires<[HasV4T]>;
// Map from load(globaladdress + x) -> memd(#foo + x)
let AddedComplexity = 100 in
def : Pat<(i64 (load FoldGlobalAddrGP:$addr)),
- (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
+ (i64 (L4_loadrd_abs FoldGlobalAddrGP:$addr))>,
Requires<[HasV4T]>;
def : Pat<(atomic_load_64 FoldGlobalAddrGP:$addr),
- (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
+ (i64 (L4_loadrd_abs FoldGlobalAddrGP:$addr))>,
Requires<[HasV4T]>;
// Map from load(globaladdress + x) -> memb(#foo + x)
let AddedComplexity = 100 in
def : Pat<(i32 (extloadi8 FoldGlobalAddrGP:$addr)),
- (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
+ (i32 (L4_loadrb_abs FoldGlobalAddrGP:$addr))>,
Requires<[HasV4T]>;
// Map from load(globaladdress + x) -> memb(#foo + x)
let AddedComplexity = 100 in
def : Pat<(i32 (sextloadi8 FoldGlobalAddrGP:$addr)),
- (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
+ (i32 (L4_loadrb_abs FoldGlobalAddrGP:$addr))>,
Requires<[HasV4T]>;
//let AddedComplexity = 100 in
let AddedComplexity = 100 in
def : Pat<(i32 (extloadi16 FoldGlobalAddrGP:$addr)),
- (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
+ (i32 (L4_loadrh_abs FoldGlobalAddrGP:$addr))>,
Requires<[HasV4T]>;
// Map from load(globaladdress + x) -> memh(#foo + x)
let AddedComplexity = 100 in
def : Pat<(i32 (sextloadi16 FoldGlobalAddrGP:$addr)),
- (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
+ (i32 (L4_loadrh_abs FoldGlobalAddrGP:$addr))>,
Requires<[HasV4T]>;
// Map from load(globaladdress + x) -> memuh(#foo + x)
let AddedComplexity = 100 in
def : Pat<(i32 (zextloadi16 FoldGlobalAddrGP:$addr)),
- (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
+ (i32 (L4_loadruh_abs FoldGlobalAddrGP:$addr))>,
Requires<[HasV4T]>;
def : Pat<(atomic_load_16 FoldGlobalAddrGP:$addr),
- (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
+ (i32 (L4_loadruh_abs FoldGlobalAddrGP:$addr))>,
Requires<[HasV4T]>;
// Map from load(globaladdress + x) -> memub(#foo + x)
let AddedComplexity = 100 in
def : Pat<(i32 (zextloadi8 FoldGlobalAddrGP:$addr)),
- (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
+ (i32 (L4_loadrub_abs FoldGlobalAddrGP:$addr))>,
Requires<[HasV4T]>;
def : Pat<(atomic_load_8 FoldGlobalAddrGP:$addr),
- (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
+ (i32 (L4_loadrub_abs FoldGlobalAddrGP:$addr))>,
Requires<[HasV4T]>;
// Map from load(globaladdress + x) -> memw(#foo + x)
let AddedComplexity = 100 in
def : Pat<(i32 (load FoldGlobalAddrGP:$addr)),
- (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,
+ (i32 (L4_loadri_abs FoldGlobalAddrGP:$addr))>,
Requires<[HasV4T]>;
def : Pat<(atomic_load_32 FoldGlobalAddrGP:$addr),
- (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,
+ (i32 (L4_loadri_abs FoldGlobalAddrGP:$addr))>,
Requires<[HasV4T]>;
+
+//===----------------------------------------------------------------------===//
+// :raw for of boundscheck:hi:lo insns
+//===----------------------------------------------------------------------===//
+
+// A4_boundscheck_lo: Detect if a register is within bounds.
+let hasSideEffects = 0, isCodeGenOnly = 0 in
+def A4_boundscheck_lo: ALU64Inst <
+ (outs PredRegs:$Pd),
+ (ins DoubleRegs:$Rss, DoubleRegs:$Rtt),
+ "$Pd = boundscheck($Rss, $Rtt):raw:lo"> {
+ bits<2> Pd;
+ bits<5> Rss;
+ bits<5> Rtt;
+
+ let IClass = 0b1101;
+
+ let Inst{27-23} = 0b00100;
+ let Inst{13} = 0b1;
+ let Inst{7-5} = 0b100;
+ let Inst{1-0} = Pd;
+ let Inst{20-16} = Rss;
+ let Inst{12-8} = Rtt;
+ }
+
+// A4_boundscheck_hi: Detect if a register is within bounds.
+let hasSideEffects = 0, isCodeGenOnly = 0 in
+def A4_boundscheck_hi: ALU64Inst <
+ (outs PredRegs:$Pd),
+ (ins DoubleRegs:$Rss, DoubleRegs:$Rtt),
+ "$Pd = boundscheck($Rss, $Rtt):raw:hi"> {
+ bits<2> Pd;
+ bits<5> Rss;
+ bits<5> Rtt;
+
+ let IClass = 0b1101;
+
+ let Inst{27-23} = 0b00100;
+ let Inst{13} = 0b1;
+ let Inst{7-5} = 0b101;
+ let Inst{1-0} = Pd;
+ let Inst{20-16} = Rss;
+ let Inst{12-8} = Rtt;
+ }
+
+let hasSideEffects = 0 in
+def A4_boundscheck : MInst <
+ (outs PredRegs:$Pd), (ins IntRegs:$Rs, DoubleRegs:$Rtt),
+ "$Pd=boundscheck($Rs,$Rtt)">;
+
+// A4_tlbmatch: Detect if a VA/ASID matches a TLB entry.
+let isPredicateLate = 1, hasSideEffects = 0, isCodeGenOnly = 0 in
+def A4_tlbmatch : ALU64Inst<(outs PredRegs:$Pd),
+ (ins DoubleRegs:$Rs, IntRegs:$Rt),
+ "$Pd = tlbmatch($Rs, $Rt)",
+ [], "", ALU64_tc_2early_SLOT23> {
+ bits<2> Pd;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1101;
+ let Inst{27-23} = 0b00100;
+ let Inst{20-16} = Rs;
+ let Inst{13} = 0b1;
+ let Inst{12-8} = Rt;
+ let Inst{7-5} = 0b011;
+ let Inst{1-0} = Pd;
+ }
+
+// We need custom lowering of ISD::PREFETCH into HexagonISD::DCFETCH
+// because the SDNode ISD::PREFETCH has properties MayLoad and MayStore.
+// We don't really want either one here.
+def SDTHexagonDCFETCH : SDTypeProfile<0, 2, [SDTCisPtrTy<0>,SDTCisInt<1>]>;
+def HexagonDCFETCH : SDNode<"HexagonISD::DCFETCH", SDTHexagonDCFETCH,
+ [SDNPHasChain]>;
+
+// Use LD0Inst for dcfetch, but set "mayLoad" to 0 because this doesn't
+// really do a load.
+let hasSideEffects = 1, mayLoad = 0, isCodeGenOnly = 0 in
+def Y2_dcfetchbo : LD0Inst<(outs), (ins IntRegs:$Rs, u11_3Imm:$u11_3),
+ "dcfetch($Rs + #$u11_3)",
+ [(HexagonDCFETCH IntRegs:$Rs, u11_3ImmPred:$u11_3)],
+ "", LD_tc_ld_SLOT0> {
+ bits<5> Rs;
+ bits<14> u11_3;
+
+ let IClass = 0b1001;
+ let Inst{27-21} = 0b0100000;
+ let Inst{20-16} = Rs;
+ let Inst{13} = 0b0;
+ let Inst{10-0} = u11_3{13-3};
+}
+
+//===----------------------------------------------------------------------===//
+// Compound instructions
+//===----------------------------------------------------------------------===//
+
+let isBranch = 1, hasSideEffects = 0, isExtentSigned = 1,
+ isPredicated = 1, isPredicatedNew = 1, isExtendable = 1,
+ opExtentBits = 11, opExtentAlign = 2, opExtendable = 1,
+ isTerminator = 1, validSubTargets = HasV4SubT in
+class CJInst_tstbit_R0<string px, bit np, string tnt>
+ : InstHexagon<(outs), (ins IntRegs:$Rs, brtarget:$r9_2),
+ ""#px#" = tstbit($Rs, #0); if ("
+ #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2",
+ [], "", COMPOUND, TypeCOMPOUND> {
+ bits<4> Rs;
+ bits<11> r9_2;
+
+ // np: !p[01]
+ let isPredicatedFalse = np;
+ // tnt: Taken/Not Taken
+ let isBrTaken = !if (!eq(tnt, "t"), "true", "false");
+ let isTaken = !if (!eq(tnt, "t"), 1, 0);
+
+ let IClass = 0b0001;
+ let Inst{27-26} = 0b00;
+ let Inst{25} = !if (!eq(px, "!p1"), 1,
+ !if (!eq(px, "p1"), 1, 0));
+ let Inst{24-23} = 0b11;
+ let Inst{22} = np;
+ let Inst{21-20} = r9_2{10-9};
+ let Inst{19-16} = Rs;
+ let Inst{13} = !if (!eq(tnt, "t"), 1, 0);
+ let Inst{9-8} = 0b11;
+ let Inst{7-1} = r9_2{8-2};
+}
+
+let Defs = [PC, P0], Uses = [P0], isCodeGenOnly = 0 in {
+ def J4_tstbit0_tp0_jump_nt : CJInst_tstbit_R0<"p0", 0, "nt">;
+ def J4_tstbit0_tp0_jump_t : CJInst_tstbit_R0<"p0", 0, "t">;
+ def J4_tstbit0_fp0_jump_nt : CJInst_tstbit_R0<"p0", 1, "nt">;
+ def J4_tstbit0_fp0_jump_t : CJInst_tstbit_R0<"p0", 1, "t">;
+}
+
+let Defs = [PC, P1], Uses = [P1], isCodeGenOnly = 0 in {
+ def J4_tstbit0_tp1_jump_nt : CJInst_tstbit_R0<"p1", 0, "nt">;
+ def J4_tstbit0_tp1_jump_t : CJInst_tstbit_R0<"p1", 0, "t">;
+ def J4_tstbit0_fp1_jump_nt : CJInst_tstbit_R0<"p1", 1, "nt">;
+ def J4_tstbit0_fp1_jump_t : CJInst_tstbit_R0<"p1", 1, "t">;
+}
+
+
+let isBranch = 1, hasSideEffects = 0,
+ isExtentSigned = 1, isPredicated = 1, isPredicatedNew = 1,
+ isExtendable = 1, opExtentBits = 11, opExtentAlign = 2,
+ opExtendable = 2, isTerminator = 1, validSubTargets = HasV4SubT in
+class CJInst_RR<string px, string op, bit np, string tnt>
+ : InstHexagon<(outs), (ins IntRegs:$Rs, IntRegs:$Rt, brtarget:$r9_2),
+ ""#px#" = cmp."#op#"($Rs, $Rt); if ("
+ #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2",
+ [], "", COMPOUND, TypeCOMPOUND> {
+ bits<4> Rs;
+ bits<4> Rt;
+ bits<11> r9_2;
+
+ // np: !p[01]
+ let isPredicatedFalse = np;
+ // tnt: Taken/Not Taken
+ let isBrTaken = !if (!eq(tnt, "t"), "true", "false");
+ let isTaken = !if (!eq(tnt, "t"), 1, 0);
+
+ let IClass = 0b0001;
+ let Inst{27-23} = !if (!eq(op, "eq"), 0b01000,
+ !if (!eq(op, "gt"), 0b01001,
+ !if (!eq(op, "gtu"), 0b01010, 0)));
+ let Inst{22} = np;
+ let Inst{21-20} = r9_2{10-9};
+ let Inst{19-16} = Rs;
+ let Inst{13} = !if (!eq(tnt, "t"), 1, 0);
+ // px: Predicate reg 0/1
+ let Inst{12} = !if (!eq(px, "!p1"), 1,
+ !if (!eq(px, "p1"), 1, 0));
+ let Inst{11-8} = Rt;
+ let Inst{7-1} = r9_2{8-2};
+}
+
+// P[10] taken/not taken.
+multiclass T_tnt_CJInst_RR<string op, bit np> {
+ let Defs = [PC, P0], Uses = [P0] in {
+ def NAME#p0_jump_nt : CJInst_RR<"p0", op, np, "nt">;
+ def NAME#p0_jump_t : CJInst_RR<"p0", op, np, "t">;
+ }
+ let Defs = [PC, P1], Uses = [P1] in {
+ def NAME#p1_jump_nt : CJInst_RR<"p1", op, np, "nt">;
+ def NAME#p1_jump_t : CJInst_RR<"p1", op, np, "t">;
+ }
+}
+// Predicate / !Predicate
+multiclass T_pnp_CJInst_RR<string op>{
+ defm J4_cmp#NAME#_t : T_tnt_CJInst_RR<op, 0>;
+ defm J4_cmp#NAME#_f : T_tnt_CJInst_RR<op, 1>;
+}
+// TypeCJ Instructions compare RR and jump
+let isCodeGenOnly = 0 in {
+defm eq : T_pnp_CJInst_RR<"eq">;
+defm gt : T_pnp_CJInst_RR<"gt">;
+defm gtu : T_pnp_CJInst_RR<"gtu">;
+}
+
+let isBranch = 1, hasSideEffects = 0, isExtentSigned = 1,
+ isPredicated = 1, isPredicatedNew = 1, isExtendable = 1, opExtentBits = 11,
+ opExtentAlign = 2, opExtendable = 2, isTerminator = 1,
+ validSubTargets = HasV4SubT in
+class CJInst_RU5<string px, string op, bit np, string tnt>
+ : InstHexagon<(outs), (ins IntRegs:$Rs, u5Imm:$U5, brtarget:$r9_2),
+ ""#px#" = cmp."#op#"($Rs, #$U5); if ("
+ #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2",
+ [], "", COMPOUND, TypeCOMPOUND> {
+ bits<4> Rs;
+ bits<5> U5;
+ bits<11> r9_2;
+
+ // np: !p[01]
+ let isPredicatedFalse = np;
+ // tnt: Taken/Not Taken
+ let isBrTaken = !if (!eq(tnt, "t"), "true", "false");
+ let isTaken = !if (!eq(tnt, "t"), 1, 0);
+
+ let IClass = 0b0001;
+ let Inst{27-26} = 0b00;
+ // px: Predicate reg 0/1
+ let Inst{25} = !if (!eq(px, "!p1"), 1,
+ !if (!eq(px, "p1"), 1, 0));
+ let Inst{24-23} = !if (!eq(op, "eq"), 0b00,
+ !if (!eq(op, "gt"), 0b01,
+ !if (!eq(op, "gtu"), 0b10, 0)));
+ let Inst{22} = np;
+ let Inst{21-20} = r9_2{10-9};
+ let Inst{19-16} = Rs;
+ let Inst{13} = !if (!eq(tnt, "t"), 1, 0);
+ let Inst{12-8} = U5;
+ let Inst{7-1} = r9_2{8-2};
+}
+// P[10] taken/not taken.
+multiclass T_tnt_CJInst_RU5<string op, bit np> {
+ let Defs = [PC, P0], Uses = [P0] in {
+ def NAME#p0_jump_nt : CJInst_RU5<"p0", op, np, "nt">;
+ def NAME#p0_jump_t : CJInst_RU5<"p0", op, np, "t">;
+ }
+ let Defs = [PC, P1], Uses = [P1] in {
+ def NAME#p1_jump_nt : CJInst_RU5<"p1", op, np, "nt">;
+ def NAME#p1_jump_t : CJInst_RU5<"p1", op, np, "t">;
+ }
+}
+// Predicate / !Predicate
+multiclass T_pnp_CJInst_RU5<string op>{
+ defm J4_cmp#NAME#i_t : T_tnt_CJInst_RU5<op, 0>;
+ defm J4_cmp#NAME#i_f : T_tnt_CJInst_RU5<op, 1>;
+}
+// TypeCJ Instructions compare RI and jump
+let isCodeGenOnly = 0 in {
+defm eq : T_pnp_CJInst_RU5<"eq">;
+defm gt : T_pnp_CJInst_RU5<"gt">;
+defm gtu : T_pnp_CJInst_RU5<"gtu">;
+}
+
+let isBranch = 1, hasSideEffects = 0, isExtentSigned = 1,
+ isPredicated = 1, isPredicatedFalse = 1, isPredicatedNew = 1,
+ isExtendable = 1, opExtentBits = 11, opExtentAlign = 2, opExtendable = 1,
+ isTerminator = 1, validSubTargets = HasV4SubT in
+class CJInst_Rn1<string px, string op, bit np, string tnt>
+ : InstHexagon<(outs), (ins IntRegs:$Rs, brtarget:$r9_2),
+ ""#px#" = cmp."#op#"($Rs,#-1); if ("
+ #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2",
+ [], "", COMPOUND, TypeCOMPOUND> {
+ bits<4> Rs;
+ bits<11> r9_2;
+
+ // np: !p[01]
+ let isPredicatedFalse = np;
+ // tnt: Taken/Not Taken
+ let isBrTaken = !if (!eq(tnt, "t"), "true", "false");
+ let isTaken = !if (!eq(tnt, "t"), 1, 0);
+
+ let IClass = 0b0001;
+ let Inst{27-26} = 0b00;
+ let Inst{25} = !if (!eq(px, "!p1"), 1,
+ !if (!eq(px, "p1"), 1, 0));
+
+ let Inst{24-23} = 0b11;
+ let Inst{22} = np;
+ let Inst{21-20} = r9_2{10-9};
+ let Inst{19-16} = Rs;
+ let Inst{13} = !if (!eq(tnt, "t"), 1, 0);
+ let Inst{9-8} = !if (!eq(op, "eq"), 0b00,
+ !if (!eq(op, "gt"), 0b01, 0));
+ let Inst{7-1} = r9_2{8-2};
+}
+
+// P[10] taken/not taken.
+multiclass T_tnt_CJInst_Rn1<string op, bit np> {
+ let Defs = [PC, P0], Uses = [P0] in {
+ def NAME#p0_jump_nt : CJInst_Rn1<"p0", op, np, "nt">;
+ def NAME#p0_jump_t : CJInst_Rn1<"p0", op, np, "t">;
+ }
+ let Defs = [PC, P1], Uses = [P1] in {
+ def NAME#p1_jump_nt : CJInst_Rn1<"p1", op, np, "nt">;
+ def NAME#p1_jump_t : CJInst_Rn1<"p1", op, np, "t">;
+ }
+}
+// Predicate / !Predicate
+multiclass T_pnp_CJInst_Rn1<string op>{
+ defm J4_cmp#NAME#n1_t : T_tnt_CJInst_Rn1<op, 0>;
+ defm J4_cmp#NAME#n1_f : T_tnt_CJInst_Rn1<op, 1>;
+}
+// TypeCJ Instructions compare -1 and jump
+let isCodeGenOnly = 0 in {
+defm eq : T_pnp_CJInst_Rn1<"eq">;
+defm gt : T_pnp_CJInst_Rn1<"gt">;
+}
+
+// J4_jumpseti: Direct unconditional jump and set register to immediate.
+let Defs = [PC], isBranch = 1, hasSideEffects = 0, hasNewValue = 1,
+ isExtentSigned = 1, opNewValue = 0, isExtendable = 1, opExtentBits = 11,
+ opExtentAlign = 2, opExtendable = 2, validSubTargets = HasV4SubT,
+ isCodeGenOnly = 0 in
+def J4_jumpseti: CJInst <
+ (outs IntRegs:$Rd),
+ (ins u6Imm:$U6, brtarget:$r9_2),
+ "$Rd = #$U6 ; jump $r9_2"> {
+ bits<4> Rd;
+ bits<6> U6;
+ bits<11> r9_2;
+
+ let IClass = 0b0001;
+ let Inst{27-24} = 0b0110;
+ let Inst{21-20} = r9_2{10-9};
+ let Inst{19-16} = Rd;
+ let Inst{13-8} = U6;
+ let Inst{7-1} = r9_2{8-2};
+ }
+
+// J4_jumpsetr: Direct unconditional jump and transfer register.
+let Defs = [PC], isBranch = 1, hasSideEffects = 0, hasNewValue = 1,
+ isExtentSigned = 1, opNewValue = 0, isExtendable = 1, opExtentBits = 11,
+ opExtentAlign = 2, opExtendable = 2, validSubTargets = HasV4SubT,
+ isCodeGenOnly = 0 in
+def J4_jumpsetr: CJInst <
+ (outs IntRegs:$Rd),
+ (ins IntRegs:$Rs, brtarget:$r9_2),
+ "$Rd = $Rs ; jump $r9_2"> {
+ bits<4> Rd;
+ bits<4> Rs;
+ bits<11> r9_2;
+
+ let IClass = 0b0001;
+ let Inst{27-24} = 0b0111;
+ let Inst{21-20} = r9_2{10-9};
+ let Inst{11-8} = Rd;
+ let Inst{19-16} = Rs;
+ let Inst{7-1} = r9_2{8-2};
+ }
diff --git a/lib/Target/Hexagon/HexagonInstrInfoV5.td b/lib/Target/Hexagon/HexagonInstrInfoV5.td
index 9da607455811..5674aa3ccd83 100644
--- a/lib/Target/Hexagon/HexagonInstrInfoV5.td
+++ b/lib/Target/Hexagon/HexagonInstrInfoV5.td
@@ -1,3 +1,42 @@
+//=- HexagonInstrInfoV5.td - Target Desc. for Hexagon Target -*- tablegen -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the Hexagon V5 instructions in TableGen format.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// XTYPE/MPY
+//===----------------------------------------------------------------------===//
+
+let isCodeGenOnly = 0 in
+def S2_asr_i_p_rnd : S_2OpInstImm<"asr", 0b110, 0b111, u6Imm,
+ [(set I64:$dst,
+ (sra (i64 (add (i64 (sra I64:$src1, u6ImmPred:$src2)), 1)),
+ (i32 1)))], 1>,
+ Requires<[HasV5T]> {
+ bits<6> src2;
+ let Inst{13-8} = src2;
+}
+
+let isCodeGenOnly = 0 in
+def C4_fastcorner9 : T_LOGICAL_2OP<"fastcorner9", 0b000, 0, 0>,
+ Requires<[HasV5T]> {
+ let Inst{13,7,4} = 0b111;
+}
+
+let isCodeGenOnly = 0 in
+def C4_fastcorner9_not : T_LOGICAL_2OP<"!fastcorner9", 0b000, 0, 0>,
+ Requires<[HasV5T]> {
+ let Inst{20,13,7,4} = 0b1111;
+}
+
def SDTHexagonFCONST32 : SDTypeProfile<1, 1, [
SDTCisVT<0, f32>,
SDTCisPtrTy<1>]>;
@@ -37,7 +76,7 @@ def TFRI_f : ALU32_ri<(outs IntRegs:$dst), (ins f32Ext:$src1),
Requires<[HasV5T]>;
let isExtended = 1, opExtendable = 2, isPredicated = 1,
-neverHasSideEffects = 1, validSubTargets = HasV5SubT in
+hasSideEffects = 0, validSubTargets = HasV5SubT in
def TFRI_cPt_f : ALU32_ri<(outs IntRegs:$dst),
(ins PredRegs:$src1, f32Ext:$src2),
"if ($src1) $dst = #$src2",
@@ -45,13 +84,405 @@ def TFRI_cPt_f : ALU32_ri<(outs IntRegs:$dst),
Requires<[HasV5T]>;
let isExtended = 1, opExtendable = 2, isPredicated = 1, isPredicatedFalse = 1,
-neverHasSideEffects = 1, validSubTargets = HasV5SubT in
+hasSideEffects = 0, validSubTargets = HasV5SubT in
def TFRI_cNotPt_f : ALU32_ri<(outs IntRegs:$dst),
(ins PredRegs:$src1, f32Ext:$src2),
"if (!$src1) $dst =#$src2",
[]>,
Requires<[HasV5T]>;
+def SDTHexagonI32I64: SDTypeProfile<1, 1, [SDTCisVT<0, i32>,
+ SDTCisVT<1, i64>]>;
+
+def HexagonPOPCOUNT: SDNode<"HexagonISD::POPCOUNT", SDTHexagonI32I64>;
+
+let hasNewValue = 1, validSubTargets = HasV5SubT, isCodeGenOnly = 0 in
+def S5_popcountp : ALU64_rr<(outs IntRegs:$Rd), (ins DoubleRegs:$Rss),
+ "$Rd = popcount($Rss)",
+ [(set I32:$Rd, (HexagonPOPCOUNT I64:$Rss))], "", S_2op_tc_2_SLOT23>,
+ Requires<[HasV5T]> {
+ bits<5> Rd;
+ bits<5> Rss;
+
+ let IClass = 0b1000;
+
+ let Inst{27-21} = 0b1000011;
+ let Inst{7-5} = 0b011;
+ let Inst{4-0} = Rd;
+ let Inst{20-16} = Rss;
+ }
+
+let isFP = 1, hasNewValue = 1, opNewValue = 0 in
+class T_MInstFloat <string mnemonic, bits<3> MajOp, bits<3> MinOp>
+ : MInst<(outs IntRegs:$Rd),
+ (ins IntRegs:$Rs, IntRegs:$Rt),
+ "$Rd = "#mnemonic#"($Rs, $Rt)", [],
+ "" , M_tc_3or4x_SLOT23 > ,
+ Requires<[HasV5T]> {
+ bits<5> Rd;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1110;
+
+ let Inst{27-24} = 0b1011;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = Rs;
+ let Inst{13} = 0b0;
+ let Inst{12-8} = Rt;
+ let Inst{7-5} = MinOp;
+ let Inst{4-0} = Rd;
+ }
+
+let isCommutable = 1, isCodeGenOnly = 0 in {
+ def F2_sfadd : T_MInstFloat < "sfadd", 0b000, 0b000>;
+ def F2_sfmpy : T_MInstFloat < "sfmpy", 0b010, 0b000>;
+}
+
+let isCodeGenOnly = 0 in
+def F2_sfsub : T_MInstFloat < "sfsub", 0b000, 0b001>;
+
+let Itinerary = M_tc_3x_SLOT23, isCodeGenOnly = 0 in {
+ def F2_sfmax : T_MInstFloat < "sfmax", 0b100, 0b000>;
+ def F2_sfmin : T_MInstFloat < "sfmin", 0b100, 0b001>;
+}
+
+let isCodeGenOnly = 0 in {
+def F2_sffixupn : T_MInstFloat < "sffixupn", 0b110, 0b000>;
+def F2_sffixupd : T_MInstFloat < "sffixupd", 0b110, 0b001>;
+}
+
+// F2_sfrecipa: Reciprocal approximation for division.
+let isPredicateLate = 1, isFP = 1,
+hasSideEffects = 0, hasNewValue = 1, isCodeGenOnly = 0 in
+def F2_sfrecipa: MInst <
+ (outs IntRegs:$Rd, PredRegs:$Pe),
+ (ins IntRegs:$Rs, IntRegs:$Rt),
+ "$Rd, $Pe = sfrecipa($Rs, $Rt)">,
+ Requires<[HasV5T]> {
+ bits<5> Rd;
+ bits<2> Pe;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1110;
+ let Inst{27-21} = 0b1011111;
+ let Inst{20-16} = Rs;
+ let Inst{13} = 0b0;
+ let Inst{12-8} = Rt;
+ let Inst{7} = 0b1;
+ let Inst{6-5} = Pe;
+ let Inst{4-0} = Rd;
+ }
+
+// F2_dfcmpeq: Floating point compare for equal.
+let isCompare = 1, isFP = 1 in
+class T_fcmp <string mnemonic, RegisterClass RC, bits<3> MinOp,
+ list<dag> pattern = [] >
+ : ALU64Inst <(outs PredRegs:$dst), (ins RC:$src1, RC:$src2),
+ "$dst = "#mnemonic#"($src1, $src2)", pattern,
+ "" , ALU64_tc_2early_SLOT23 > ,
+ Requires<[HasV5T]> {
+ bits<2> dst;
+ bits<5> src1;
+ bits<5> src2;
+
+ let IClass = 0b1101;
+
+ let Inst{27-21} = 0b0010111;
+ let Inst{20-16} = src1;
+ let Inst{12-8} = src2;
+ let Inst{7-5} = MinOp;
+ let Inst{1-0} = dst;
+ }
+
+class T_fcmp64 <string mnemonic, PatFrag OpNode, bits<3> MinOp>
+ : T_fcmp <mnemonic, DoubleRegs, MinOp,
+ [(set I1:$dst, (OpNode F64:$src1, F64:$src2))]> {
+ let IClass = 0b1101;
+ let Inst{27-21} = 0b0010111;
+}
+
+class T_fcmp32 <string mnemonic, PatFrag OpNode, bits<3> MinOp>
+ : T_fcmp <mnemonic, IntRegs, MinOp,
+ [(set I1:$dst, (OpNode F32:$src1, F32:$src2))]> {
+ let IClass = 0b1100;
+ let Inst{27-21} = 0b0111111;
+}
+
+let isCodeGenOnly = 0 in {
+def F2_dfcmpeq : T_fcmp64<"dfcmp.eq", setoeq, 0b000>;
+def F2_dfcmpgt : T_fcmp64<"dfcmp.gt", setogt, 0b001>;
+def F2_dfcmpge : T_fcmp64<"dfcmp.ge", setoge, 0b010>;
+def F2_dfcmpuo : T_fcmp64<"dfcmp.uo", setuo, 0b011>;
+
+def F2_sfcmpge : T_fcmp32<"sfcmp.ge", setoge, 0b000>;
+def F2_sfcmpuo : T_fcmp32<"sfcmp.uo", setuo, 0b001>;
+def F2_sfcmpeq : T_fcmp32<"sfcmp.eq", setoeq, 0b011>;
+def F2_sfcmpgt : T_fcmp32<"sfcmp.gt", setogt, 0b100>;
+}
+
+// F2 convert template classes:
+let isFP = 1 in
+class F2_RDD_RSS_CONVERT<string mnemonic, bits<3> MinOp,
+ SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
+ string chop ="">
+ : SInst <(outs DoubleRegs:$Rdd), (ins DoubleRegs:$Rss),
+ "$Rdd = "#mnemonic#"($Rss)"#chop,
+ [(set RCOut:$Rdd, (Op RCIn:$Rss))], "",
+ S_2op_tc_3or4x_SLOT23> {
+ bits<5> Rdd;
+ bits<5> Rss;
+
+ let IClass = 0b1000;
+
+ let Inst{27-21} = 0b0000111;
+ let Inst{20-16} = Rss;
+ let Inst{7-5} = MinOp;
+ let Inst{4-0} = Rdd;
+ }
+
+let isFP = 1 in
+class F2_RDD_RS_CONVERT<string mnemonic, bits<3> MinOp,
+ SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
+ string chop ="">
+ : SInst <(outs DoubleRegs:$Rdd), (ins IntRegs:$Rs),
+ "$Rdd = "#mnemonic#"($Rs)"#chop,
+ [(set RCOut:$Rdd, (Op RCIn:$Rs))], "",
+ S_2op_tc_3or4x_SLOT23> {
+ bits<5> Rdd;
+ bits<5> Rs;
+
+ let IClass = 0b1000;
+
+ let Inst{27-21} = 0b0100100;
+ let Inst{20-16} = Rs;
+ let Inst{7-5} = MinOp;
+ let Inst{4-0} = Rdd;
+ }
+
+let isFP = 1, hasNewValue = 1 in
+class F2_RD_RSS_CONVERT<string mnemonic, bits<3> MinOp,
+ SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
+ string chop ="">
+ : SInst <(outs IntRegs:$Rd), (ins DoubleRegs:$Rss),
+ "$Rd = "#mnemonic#"($Rss)"#chop,
+ [(set RCOut:$Rd, (Op RCIn:$Rss))], "",
+ S_2op_tc_3or4x_SLOT23> {
+ bits<5> Rd;
+ bits<5> Rss;
+
+ let IClass = 0b1000;
+
+ let Inst{27-24} = 0b1000;
+ let Inst{23-21} = MinOp;
+ let Inst{20-16} = Rss;
+ let Inst{7-5} = 0b001;
+ let Inst{4-0} = Rd;
+ }
+
+let isFP = 1, hasNewValue = 1 in
+class F2_RD_RS_CONVERT<string mnemonic, bits<3> MajOp, bits<3> MinOp,
+ SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
+ string chop ="">
+ : SInst <(outs IntRegs:$Rd), (ins IntRegs:$Rs),
+ "$Rd = "#mnemonic#"($Rs)"#chop,
+ [(set RCOut:$Rd, (Op RCIn:$Rs))], "",
+ S_2op_tc_3or4x_SLOT23> {
+ bits<5> Rd;
+ bits<5> Rs;
+
+ let IClass = 0b1000;
+
+ let Inst{27-24} = 0b1011;
+ let Inst{23-21} = MajOp;
+ let Inst{20-16} = Rs;
+ let Inst{7-5} = MinOp;
+ let Inst{4-0} = Rd;
+ }
+
+// Convert single precision to double precision and vice-versa.
+let isCodeGenOnly = 0 in {
+def F2_conv_sf2df : F2_RDD_RS_CONVERT <"convert_sf2df", 0b000,
+ fextend, F64, F32>;
+
+def F2_conv_df2sf : F2_RD_RSS_CONVERT <"convert_df2sf", 0b000,
+ fround, F32, F64>;
+
+// Convert Integer to Floating Point.
+def F2_conv_d2sf : F2_RD_RSS_CONVERT <"convert_d2sf", 0b010,
+ sint_to_fp, F32, I64>;
+def F2_conv_ud2sf : F2_RD_RSS_CONVERT <"convert_ud2sf", 0b001,
+ uint_to_fp, F32, I64>;
+def F2_conv_uw2sf : F2_RD_RS_CONVERT <"convert_uw2sf", 0b001, 0b000,
+ uint_to_fp, F32, I32>;
+def F2_conv_w2sf : F2_RD_RS_CONVERT <"convert_w2sf", 0b010, 0b000,
+ sint_to_fp, F32, I32>;
+def F2_conv_d2df : F2_RDD_RSS_CONVERT <"convert_d2df", 0b011,
+ sint_to_fp, F64, I64>;
+def F2_conv_ud2df : F2_RDD_RSS_CONVERT <"convert_ud2df", 0b010,
+ uint_to_fp, F64, I64>;
+def F2_conv_uw2df : F2_RDD_RS_CONVERT <"convert_uw2df", 0b001,
+ uint_to_fp, F64, I32>;
+def F2_conv_w2df : F2_RDD_RS_CONVERT <"convert_w2df", 0b010,
+ sint_to_fp, F64, I32>;
+
+// Convert Floating Point to Integer - default.
+def F2_conv_df2uw_chop : F2_RD_RSS_CONVERT <"convert_df2uw", 0b101,
+ fp_to_uint, I32, F64, ":chop">;
+def F2_conv_df2w_chop : F2_RD_RSS_CONVERT <"convert_df2w", 0b111,
+ fp_to_sint, I32, F64, ":chop">;
+def F2_conv_sf2uw_chop : F2_RD_RS_CONVERT <"convert_sf2uw", 0b011, 0b001,
+ fp_to_uint, I32, F32, ":chop">;
+def F2_conv_sf2w_chop : F2_RD_RS_CONVERT <"convert_sf2w", 0b100, 0b001,
+ fp_to_sint, I32, F32, ":chop">;
+def F2_conv_df2d_chop : F2_RDD_RSS_CONVERT <"convert_df2d", 0b110,
+ fp_to_sint, I64, F64, ":chop">;
+def F2_conv_df2ud_chop : F2_RDD_RSS_CONVERT <"convert_df2ud", 0b111,
+ fp_to_uint, I64, F64, ":chop">;
+def F2_conv_sf2d_chop : F2_RDD_RS_CONVERT <"convert_sf2d", 0b110,
+ fp_to_sint, I64, F32, ":chop">;
+def F2_conv_sf2ud_chop : F2_RDD_RS_CONVERT <"convert_sf2ud", 0b101,
+ fp_to_uint, I64, F32, ":chop">;
+
+// Convert Floating Point to Integer: non-chopped.
+let AddedComplexity = 20, Predicates = [HasV5T, IEEERndNearV5T] in {
+ def F2_conv_df2d : F2_RDD_RSS_CONVERT <"convert_df2d", 0b000,
+ fp_to_sint, I64, F64>;
+ def F2_conv_df2ud : F2_RDD_RSS_CONVERT <"convert_df2ud", 0b001,
+ fp_to_uint, I64, F64>;
+ def F2_conv_sf2ud : F2_RDD_RS_CONVERT <"convert_sf2ud", 0b011,
+ fp_to_uint, I64, F32>;
+ def F2_conv_sf2d : F2_RDD_RS_CONVERT <"convert_sf2d", 0b100,
+ fp_to_sint, I64, F32>;
+ def F2_conv_df2uw : F2_RD_RSS_CONVERT <"convert_df2uw", 0b011,
+ fp_to_uint, I32, F64>;
+ def F2_conv_df2w : F2_RD_RSS_CONVERT <"convert_df2w", 0b100,
+ fp_to_sint, I32, F64>;
+ def F2_conv_sf2uw : F2_RD_RS_CONVERT <"convert_sf2uw", 0b011, 0b000,
+ fp_to_uint, I32, F32>;
+ def F2_conv_sf2w : F2_RD_RS_CONVERT <"convert_sf2w", 0b100, 0b000,
+ fp_to_sint, I32, F32>;
+}
+}
+
+// Fix up radicand.
+let isFP = 1, hasNewValue = 1, isCodeGenOnly = 0 in
+def F2_sffixupr: SInst<(outs IntRegs:$Rd), (ins IntRegs:$Rs),
+ "$Rd = sffixupr($Rs)",
+ [], "" , S_2op_tc_3or4x_SLOT23>, Requires<[HasV5T]> {
+ bits<5> Rd;
+ bits<5> Rs;
+
+ let IClass = 0b1000;
+
+ let Inst{27-21} = 0b1011101;
+ let Inst{20-16} = Rs;
+ let Inst{7-5} = 0b000;
+ let Inst{4-0} = Rd;
+ }
+
+// F2_sffma: Floating-point fused multiply add.
+let isFP = 1, hasNewValue = 1 in
+class T_sfmpy_acc <bit isSub, bit isLib>
+ : MInst<(outs IntRegs:$Rx),
+ (ins IntRegs:$dst2, IntRegs:$Rs, IntRegs:$Rt),
+ "$Rx "#!if(isSub, "-=","+=")#" sfmpy($Rs, $Rt)"#!if(isLib, ":lib",""),
+ [], "$dst2 = $Rx" , M_tc_3_SLOT23 > ,
+ Requires<[HasV5T]> {
+ bits<5> Rx;
+ bits<5> Rs;
+ bits<5> Rt;
+
+ let IClass = 0b1110;
+
+ let Inst{27-21} = 0b1111000;
+ let Inst{20-16} = Rs;
+ let Inst{13} = 0b0;
+ let Inst{12-8} = Rt;
+ let Inst{7} = 0b1;
+ let Inst{6} = isLib;
+ let Inst{5} = isSub;
+ let Inst{4-0} = Rx;
+ }
+
+let isCodeGenOnly = 0 in {
+def F2_sffma: T_sfmpy_acc <0, 0>;
+def F2_sffms: T_sfmpy_acc <1, 0>;
+def F2_sffma_lib: T_sfmpy_acc <0, 1>;
+def F2_sffms_lib: T_sfmpy_acc <1, 1>;
+}
+
+// Floating-point fused multiply add w/ additional scaling (2**pu).
+let isFP = 1, hasNewValue = 1, isCodeGenOnly = 0 in
+def F2_sffma_sc: MInst <
+ (outs IntRegs:$Rx),
+ (ins IntRegs:$dst2, IntRegs:$Rs, IntRegs:$Rt, PredRegs:$Pu),
+ "$Rx += sfmpy($Rs, $Rt, $Pu):scale" ,
+ [], "$dst2 = $Rx" , M_tc_3_SLOT23 > ,
+ Requires<[HasV5T]> {
+ bits<5> Rx;
+ bits<5> Rs;
+ bits<5> Rt;
+ bits<2> Pu;
+
+ let IClass = 0b1110;
+
+ let Inst{27-21} = 0b1111011;
+ let Inst{20-16} = Rs;
+ let Inst{13} = 0b0;
+ let Inst{12-8} = Rt;
+ let Inst{7} = 0b1;
+ let Inst{6-5} = Pu;
+ let Inst{4-0} = Rx;
+ }
+
+// Classify floating-point value
+let isFP = 1, isCodeGenOnly = 0 in
+ def F2_sfclass : T_TEST_BIT_IMM<"sfclass", 0b111>;
+
+let isFP = 1, isCodeGenOnly = 0 in
+def F2_dfclass: ALU64Inst<(outs PredRegs:$Pd), (ins DoubleRegs:$Rss, u5Imm:$u5),
+ "$Pd = dfclass($Rss, #$u5)",
+ [], "" , ALU64_tc_2early_SLOT23 > , Requires<[HasV5T]> {
+ bits<2> Pd;
+ bits<5> Rss;
+ bits<5> u5;
+
+ let IClass = 0b1101;
+ let Inst{27-21} = 0b1100100;
+ let Inst{20-16} = Rss;
+ let Inst{12-10} = 0b000;
+ let Inst{9-5} = u5;
+ let Inst{4-3} = 0b10;
+ let Inst{1-0} = Pd;
+ }
+
+// Instructions to create floating point constant
+let hasNewValue = 1, opNewValue = 0 in
+class T_fimm <string mnemonic, RegisterClass RC, bits<4> RegType, bit isNeg>
+ : ALU64Inst<(outs RC:$dst), (ins u10Imm:$src),
+ "$dst = "#mnemonic#"(#$src)"#!if(isNeg, ":neg", ":pos"),
+ [], "", ALU64_tc_3x_SLOT23>, Requires<[HasV5T]> {
+ bits<5> dst;
+ bits<10> src;
+
+ let IClass = 0b1101;
+ let Inst{27-24} = RegType;
+ let Inst{23} = 0b0;
+ let Inst{22} = isNeg;
+ let Inst{21} = src{9};
+ let Inst{13-5} = src{8-0};
+ let Inst{4-0} = dst;
+ }
+
+let isCodeGenOnly = 0 in {
+def F2_sfimm_p : T_fimm <"sfmake", IntRegs, 0b0110, 0>;
+def F2_sfimm_n : T_fimm <"sfmake", IntRegs, 0b0110, 1>;
+def F2_dfimm_p : T_fimm <"dfmake", DoubleRegs, 0b1001, 0>;
+def F2_dfimm_n : T_fimm <"dfmake", DoubleRegs, 0b1001, 1>;
+}
+
// Convert single precision to double precision and vice-versa.
def CONVERT_sf2df : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
"$dst = convert_sf2df($src)",
@@ -290,36 +721,36 @@ def : Pat<(i1 (setule (f64 DoubleRegs:$src1), (fpimm:$src2))),
// ne.
def : Pat<(i1 (setone (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
- (i1 (NOT_p (FCMPOEQ32_rr IntRegs:$src1, IntRegs:$src2)))>,
+ (i1 (C2_not (FCMPOEQ32_rr IntRegs:$src1, IntRegs:$src2)))>,
Requires<[HasV5T]>;
def : Pat<(i1 (setone (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
- (i1 (NOT_p (FCMPOEQ64_rr DoubleRegs:$src1, DoubleRegs:$src2)))>,
+ (i1 (C2_not (FCMPOEQ64_rr DoubleRegs:$src1, DoubleRegs:$src2)))>,
Requires<[HasV5T]>;
def : Pat<(i1 (setune (f32 IntRegs:$src1), (f32 IntRegs:$src2))),
- (i1 (NOT_p (FCMPUEQ32_rr IntRegs:$src1, IntRegs:$src2)))>,
+ (i1 (C2_not (FCMPUEQ32_rr IntRegs:$src1, IntRegs:$src2)))>,
Requires<[HasV5T]>;
def : Pat<(i1 (setune (f64 DoubleRegs:$src1), (f64 DoubleRegs:$src2))),
- (i1 (NOT_p (FCMPUEQ64_rr DoubleRegs:$src1, DoubleRegs:$src2)))>,
+ (i1 (C2_not (FCMPUEQ64_rr DoubleRegs:$src1, DoubleRegs:$src2)))>,
Requires<[HasV5T]>;
def : Pat<(i1 (setone (f32 IntRegs:$src1), (fpimm:$src2))),
- (i1 (NOT_p (FCMPOEQ32_rr IntRegs:$src1, (f32 (TFRI_f fpimm:$src2)))))>,
+ (i1 (C2_not (FCMPOEQ32_rr IntRegs:$src1, (f32 (TFRI_f fpimm:$src2)))))>,
Requires<[HasV5T]>;
def : Pat<(i1 (setone (f64 DoubleRegs:$src1), (fpimm:$src2))),
- (i1 (NOT_p (FCMPOEQ64_rr DoubleRegs:$src1,
+ (i1 (C2_not (FCMPOEQ64_rr DoubleRegs:$src1,
(f64 (CONST64_Float_Real fpimm:$src2)))))>,
Requires<[HasV5T]>;
def : Pat<(i1 (setune (f32 IntRegs:$src1), (fpimm:$src2))),
- (i1 (NOT_p (FCMPUEQ32_rr IntRegs:$src1, (f32 (TFRI_f fpimm:$src2)))))>,
+ (i1 (C2_not (FCMPUEQ32_rr IntRegs:$src1, (f32 (TFRI_f fpimm:$src2)))))>,
Requires<[HasV5T]>;
def : Pat<(i1 (setune (f64 DoubleRegs:$src1), (fpimm:$src2))),
- (i1 (NOT_p (FCMPUEQ64_rr DoubleRegs:$src1,
+ (i1 (C2_not (FCMPUEQ64_rr DoubleRegs:$src1,
(f64 (CONST64_Float_Real fpimm:$src2)))))>,
Requires<[HasV5T]>;
@@ -458,30 +889,21 @@ def CONVERT_sf2ud_nchop : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src),
// Bitcast is different than [fp|sint|uint]_to_[sint|uint|fp].
def : Pat <(i32 (bitconvert (f32 IntRegs:$src))),
- (i32 (TFR IntRegs:$src))>,
+ (i32 (A2_tfr IntRegs:$src))>,
Requires<[HasV5T]>;
def : Pat <(f32 (bitconvert (i32 IntRegs:$src))),
- (f32 (TFR IntRegs:$src))>,
+ (f32 (A2_tfr IntRegs:$src))>,
Requires<[HasV5T]>;
def : Pat <(i64 (bitconvert (f64 DoubleRegs:$src))),
- (i64 (TFR64 DoubleRegs:$src))>,
+ (i64 (A2_tfrp DoubleRegs:$src))>,
Requires<[HasV5T]>;
def : Pat <(f64 (bitconvert (i64 DoubleRegs:$src))),
- (f64 (TFR64 DoubleRegs:$src))>,
+ (f64 (A2_tfrp DoubleRegs:$src))>,
Requires<[HasV5T]>;
-// Floating point fused multiply-add.
-def FMADD_dp : ALU64_acc<(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3),
- "$dst += dfmpy($src2, $src3)",
- [(set (f64 DoubleRegs:$dst),
- (fma DoubleRegs:$src2, DoubleRegs:$src3, DoubleRegs:$src1))],
- "$src1 = $dst">,
- Requires<[HasV5T]>;
-
def FMADD_sp : ALU64_acc<(outs IntRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
"$dst += sfmpy($src2, $src3)",
@@ -492,15 +914,6 @@ def FMADD_sp : ALU64_acc<(outs IntRegs:$dst),
// Floating point max/min.
-let AddedComplexity = 100 in
-def FMAX_dp : ALU64_rr<(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1, DoubleRegs:$src2),
- "$dst = dfmax($src1, $src2)",
- [(set DoubleRegs:$dst, (f64 (select (i1 (setolt DoubleRegs:$src2,
- DoubleRegs:$src1)),
- DoubleRegs:$src1,
- DoubleRegs:$src2)))]>,
- Requires<[HasV5T]>;
let AddedComplexity = 100 in
def FMAX_sp : ALU64_rr<(outs IntRegs:$dst),
@@ -513,16 +926,6 @@ def FMAX_sp : ALU64_rr<(outs IntRegs:$dst),
Requires<[HasV5T]>;
let AddedComplexity = 100 in
-def FMIN_dp : ALU64_rr<(outs DoubleRegs:$dst),
- (ins DoubleRegs:$src1, DoubleRegs:$src2),
- "$dst = dfmin($src1, $src2)",
- [(set DoubleRegs:$dst, (f64 (select (i1 (setogt DoubleRegs:$src2,
- DoubleRegs:$src1)),
- DoubleRegs:$src1,
- DoubleRegs:$src2)))]>,
- Requires<[HasV5T]>;
-
-let AddedComplexity = 100 in
def FMIN_sp : ALU64_rr<(outs IntRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2),
"$dst = sfmin($src1, $src2)",
@@ -615,19 +1018,19 @@ def : Pat <(i32 (fp_to_sint (f64 DoubleRegs:$src1))),
Requires<[HasV5T]>;
def : Pat <(fabs (f32 IntRegs:$src1)),
- (CLRBIT_31 (f32 IntRegs:$src1), 31)>,
+ (S2_clrbit_i (f32 IntRegs:$src1), 31)>,
Requires<[HasV5T]>;
def : Pat <(fneg (f32 IntRegs:$src1)),
- (TOGBIT_31 (f32 IntRegs:$src1), 31)>,
+ (S2_togglebit_i (f32 IntRegs:$src1), 31)>,
Requires<[HasV5T]>;
/*
def : Pat <(fabs (f64 DoubleRegs:$src1)),
- (CLRBIT_31 (f32 (EXTRACT_SUBREG DoubleRegs:$src1, subreg_hireg)), 31)>,
+ (S2_clrbit_i (f32 (EXTRACT_SUBREG DoubleRegs:$src1, subreg_hireg)), 31)>,
Requires<[HasV5T]>;
def : Pat <(fabs (f64 DoubleRegs:$src1)),
- (CLRBIT_31 (f32 (EXTRACT_SUBREG DoubleRegs:$src1, subreg_hireg)), 31)>,
+ (S2_clrbit_i (f32 (EXTRACT_SUBREG DoubleRegs:$src1, subreg_hireg)), 31)>,
Requires<[HasV5T]>;
*/
diff --git a/lib/Target/Hexagon/HexagonIntrinsics.td b/lib/Target/Hexagon/HexagonIntrinsics.td
index 99f59d5ea669..7d3f9d92cbd4 100644
--- a/lib/Target/Hexagon/HexagonIntrinsics.td
+++ b/lib/Target/Hexagon/HexagonIntrinsics.td
@@ -1843,13 +1843,18 @@ class si_MInst_didi<string opc, Intrinsic IntID>
!strconcat("$dst = ", !strconcat(opc , "($src1, $src2)")),
[(set IntRegs:$dst, (IntID DoubleRegs:$src1, DoubleRegs:$src2))]>;
+
+class T_RI_pat <InstHexagon MI, Intrinsic IntID>
+ : Pat<(IntID (i32 IntRegs:$Rs), imm:$It),
+ (MI IntRegs:$Rs, imm:$It)>;
+
//
// LDInst classes.
//
-let mayLoad = 1, neverHasSideEffects = 1 in
+let mayLoad = 1, hasSideEffects = 0 in
class di_LDInstPI_diu4<string opc, Intrinsic IntID>
: LDInstPI<(outs IntRegs:$dst, DoubleRegs:$dst2),
- (ins IntRegs:$src1, IntRegs:$src2, CRRegs:$src3, s4Imm:$offset),
+ (ins IntRegs:$src1, IntRegs:$src2, CtrRegs:$src3, s4Imm:$offset),
"$dst2 = memd($src1++#$offset:circ($src3))",
[],
"$src1 = $dst">;
diff --git a/lib/Target/Hexagon/HexagonIntrinsicsDerived.td b/lib/Target/Hexagon/HexagonIntrinsicsDerived.td
index 2788101d5a66..df89378603a4 100644
--- a/lib/Target/Hexagon/HexagonIntrinsicsDerived.td
+++ b/lib/Target/Hexagon/HexagonIntrinsicsDerived.td
@@ -13,13 +13,13 @@
//
def : Pat <(mul DoubleRegs:$src1, DoubleRegs:$src2),
(i64
- (COMBINE_rr
+ (A2_combinew
(HEXAGON_M2_maci
(HEXAGON_M2_maci
(i32
(EXTRACT_SUBREG
(i64
- (MPYU64 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
+ (M2_dpmpyuu_s0 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1),
subreg_loreg)),
(i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2),
subreg_loreg)))),
@@ -31,7 +31,8 @@ def : Pat <(mul DoubleRegs:$src1, DoubleRegs:$src2),
(i32
(EXTRACT_SUBREG
(i64
- (MPYU64 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg)),
+ (M2_dpmpyuu_s0
+ (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg)),
(i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2),
subreg_loreg)))), subreg_loreg))))>;
diff --git a/lib/Target/Hexagon/HexagonIntrinsicsV4.td b/lib/Target/Hexagon/HexagonIntrinsicsV4.td
index dd28ebb57231..77b148b9f2bd 100644
--- a/lib/Target/Hexagon/HexagonIntrinsicsV4.td
+++ b/lib/Target/Hexagon/HexagonIntrinsicsV4.td
@@ -217,12 +217,13 @@ def Hexagon_A4_combineri : di_ALU32_sis8 <"combine", int_hexagon_A4_combineri>;
// ALU32 / PRED / Conditional Sign Extend.
// ALU32 / PRED / Conditional Zero Extend.
// ALU32 / PRED / Compare.
-def Hexagon_C4_cmpneq : qi_neg_ALU32_sisi <"cmp.eq", int_hexagon_C4_cmpneq>;
-def Hexagon_C4_cmpneqi : qi_neg_ALU32_sis10 <"cmp.eq", int_hexagon_C4_cmpneqi>;
-def Hexagon_C4_cmplte : qi_neg_ALU32_sisi <"cmp.gt", int_hexagon_C4_cmplte>;
def Hexagon_C4_cmpltei : qi_neg_ALU32_sis10 <"cmp.gt", int_hexagon_C4_cmpltei>;
+def Hexagon_C4_cmplte : qi_neg_ALU32_sisi <"cmp.gt", int_hexagon_C4_cmplte>;
def Hexagon_C4_cmplteu : qi_neg_ALU32_sisi <"cmp.gtu",int_hexagon_C4_cmplteu>;
-def Hexagon_C4_cmplteui: qi_neg_ALU32_siu9 <"cmp.gtu",int_hexagon_C4_cmplteui>;
+
+def: T_RI_pat<C4_cmpneqi, int_hexagon_C4_cmpneqi>;
+def: T_RI_pat<C4_cmpltei, int_hexagon_C4_cmpltei>;
+def: T_RI_pat<C4_cmplteui, int_hexagon_C4_cmplteui>;
// ALU32 / PRED / cmpare To General Register.
def Hexagon_A4_rcmpneq : si_neg_ALU32_sisi <"cmp.eq", int_hexagon_A4_rcmpneq>;
diff --git a/lib/Target/Hexagon/HexagonMCInstLower.cpp b/lib/Target/Hexagon/HexagonMCInstLower.cpp
index 5e4346d40213..3f5d6d84a108 100644
--- a/lib/Target/Hexagon/HexagonMCInstLower.cpp
+++ b/lib/Target/Hexagon/HexagonMCInstLower.cpp
@@ -42,7 +42,6 @@ static MCOperand GetSymbolRef(const MachineOperand& MO, const MCSymbol* Symbol,
void llvm::HexagonLowerToMC(const MachineInstr* MI, HexagonMCInst& MCI,
HexagonAsmPrinter& AP) {
MCI.setOpcode(MI->getOpcode());
- MCI.setDesc(MI->getDesc());
for (unsigned i = 0, e = MI->getNumOperands(); i < e; i++) {
const MachineOperand &MO = MI->getOperand(i);
diff --git a/lib/Target/Hexagon/HexagonMachineFunctionInfo.h b/lib/Target/Hexagon/HexagonMachineFunctionInfo.h
index d799bdbd5f19..cb18df6ed198 100644
--- a/lib/Target/Hexagon/HexagonMachineFunctionInfo.h
+++ b/lib/Target/Hexagon/HexagonMachineFunctionInfo.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef HexagonMACHINEFUNCTIONINFO_H
-#define HexagonMACHINEFUNCTIONINFO_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONMACHINEFUNCTIONINFO_H
+#define LLVM_LIB_TARGET_HEXAGON_HEXAGONMACHINEFUNCTIONINFO_H
#include "llvm/CodeGen/MachineFunction.h"
#include <map>
diff --git a/lib/Target/Hexagon/HexagonMachineScheduler.cpp b/lib/Target/Hexagon/HexagonMachineScheduler.cpp
index 6fcaa2057404..97c626fdf7af 100644
--- a/lib/Target/Hexagon/HexagonMachineScheduler.cpp
+++ b/lib/Target/Hexagon/HexagonMachineScheduler.cpp
@@ -145,7 +145,7 @@ void VLIWMachineScheduler::schedule() {
<< "********** MI Converging Scheduling VLIW BB#" << BB->getNumber()
<< " " << BB->getName()
<< " in_func " << BB->getParent()->getFunction()->getName()
- << " at loop depth " << MLI.getLoopDepth(BB)
+ << " at loop depth " << MLI->getLoopDepth(BB)
<< " \n");
buildDAGWithRegPressure();
@@ -208,8 +208,12 @@ void ConvergingVLIWScheduler::initialize(ScheduleDAGMI *dag) {
const TargetMachine &TM = DAG->MF.getTarget();
delete Top.HazardRec;
delete Bot.HazardRec;
- Top.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG);
- Bot.HazardRec = TM.getInstrInfo()->CreateTargetMIHazardRecognizer(Itin, DAG);
+ Top.HazardRec =
+ TM.getSubtargetImpl()->getInstrInfo()->CreateTargetMIHazardRecognizer(
+ Itin, DAG);
+ Bot.HazardRec =
+ TM.getSubtargetImpl()->getInstrInfo()->CreateTargetMIHazardRecognizer(
+ Itin, DAG);
delete Top.ResourceModel;
delete Bot.ResourceModel;
diff --git a/lib/Target/Hexagon/HexagonMachineScheduler.h b/lib/Target/Hexagon/HexagonMachineScheduler.h
index 8c4108609606..1e023c32bb8c 100644
--- a/lib/Target/Hexagon/HexagonMachineScheduler.h
+++ b/lib/Target/Hexagon/HexagonMachineScheduler.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef HEXAGONASMPRINTER_H
-#define HEXAGONASMPRINTER_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONMACHINESCHEDULER_H
+#define LLVM_LIB_TARGET_HEXAGON_HEXAGONMACHINESCHEDULER_H
#include "llvm/ADT/PriorityQueue.h"
#include "llvm/Analysis/AliasAnalysis.h"
@@ -56,7 +56,9 @@ class VLIWResourceModel {
public:
VLIWResourceModel(const TargetMachine &TM, const TargetSchedModel *SM) :
SchedModel(SM), TotalPackets(0) {
- ResourcesModel = TM.getInstrInfo()->CreateTargetScheduleState(&TM, nullptr);
+ ResourcesModel =
+ TM.getSubtargetImpl()->getInstrInfo()->CreateTargetScheduleState(
+ *TM.getSubtargetImpl());
// This hard requirement could be relaxed,
// but for now do not let it proceed.
@@ -99,7 +101,7 @@ public:
/// Schedule - This is called back from ScheduleDAGInstrs::Run() when it's
/// time to do some work.
- virtual void schedule() override;
+ void schedule() override;
/// Perform platform-specific DAG postprocessing.
void postprocessDAG();
};
@@ -207,15 +209,15 @@ public:
: DAG(nullptr), SchedModel(nullptr), Top(TopQID, "TopQ"),
Bot(BotQID, "BotQ") {}
- virtual void initialize(ScheduleDAGMI *dag) override;
+ void initialize(ScheduleDAGMI *dag) override;
- virtual SUnit *pickNode(bool &IsTopNode) override;
+ SUnit *pickNode(bool &IsTopNode) override;
- virtual void schedNode(SUnit *SU, bool IsTopNode) override;
+ void schedNode(SUnit *SU, bool IsTopNode) override;
- virtual void releaseTopNode(SUnit *SU) override;
+ void releaseTopNode(SUnit *SU) override;
- virtual void releaseBottomNode(SUnit *SU) override;
+ void releaseBottomNode(SUnit *SU) override;
unsigned ReportPackets() {
return Top.ResourceModel->getTotalPackets() +
diff --git a/lib/Target/Hexagon/HexagonNewValueJump.cpp b/lib/Target/Hexagon/HexagonNewValueJump.cpp
index b7c03a72779f..7edba92e7e0d 100644
--- a/lib/Target/Hexagon/HexagonNewValueJump.cpp
+++ b/lib/Target/Hexagon/HexagonNewValueJump.cpp
@@ -176,7 +176,7 @@ static bool commonChecksToProhibitNewValueJump(bool afterRA,
return false;
// if call in path, bail out.
- if (MII->getOpcode() == Hexagon::CALLv3)
+ if (MII->getOpcode() == Hexagon::J2_call)
return false;
// if NVJ is running prior to RA, do the following checks.
@@ -199,8 +199,7 @@ static bool commonChecksToProhibitNewValueJump(bool afterRA,
// of registers by individual passes in the backend. At this time,
// we don't know the scope of usage and definitions of these
// instructions.
- if (MII->getOpcode() == Hexagon::TFR_condset_rr ||
- MII->getOpcode() == Hexagon::TFR_condset_ii ||
+ if (MII->getOpcode() == Hexagon::TFR_condset_ii ||
MII->getOpcode() == Hexagon::TFR_condset_ri ||
MII->getOpcode() == Hexagon::TFR_condset_ir ||
MII->getOpcode() == Hexagon::LDriw_pred ||
@@ -228,8 +227,8 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII,
int64_t v = MI->getOperand(2).getImm();
if (!(isUInt<5>(v) ||
- ((MI->getOpcode() == Hexagon::CMPEQri ||
- MI->getOpcode() == Hexagon::CMPGTri) &&
+ ((MI->getOpcode() == Hexagon::C2_cmpeqi ||
+ MI->getOpcode() == Hexagon::C2_cmpgti) &&
(v == -1))))
return false;
}
@@ -299,11 +298,11 @@ static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg,
taken = true;
switch (MI->getOpcode()) {
- case Hexagon::CMPEQrr:
+ case Hexagon::C2_cmpeq:
return taken ? Hexagon::CMPEQrr_t_Jumpnv_t_V4
: Hexagon::CMPEQrr_t_Jumpnv_nt_V4;
- case Hexagon::CMPEQri: {
+ case Hexagon::C2_cmpeqi: {
if (reg >= 0)
return taken ? Hexagon::CMPEQri_t_Jumpnv_t_V4
: Hexagon::CMPEQri_t_Jumpnv_nt_V4;
@@ -312,7 +311,7 @@ static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg,
: Hexagon::CMPEQn1_t_Jumpnv_nt_V4;
}
- case Hexagon::CMPGTrr: {
+ case Hexagon::C2_cmpgt: {
if (secondRegNewified)
return taken ? Hexagon::CMPLTrr_t_Jumpnv_t_V4
: Hexagon::CMPLTrr_t_Jumpnv_nt_V4;
@@ -321,7 +320,7 @@ static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg,
: Hexagon::CMPGTrr_t_Jumpnv_nt_V4;
}
- case Hexagon::CMPGTri: {
+ case Hexagon::C2_cmpgti: {
if (reg >= 0)
return taken ? Hexagon::CMPGTri_t_Jumpnv_t_V4
: Hexagon::CMPGTri_t_Jumpnv_nt_V4;
@@ -330,7 +329,7 @@ static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg,
: Hexagon::CMPGTn1_t_Jumpnv_nt_V4;
}
- case Hexagon::CMPGTUrr: {
+ case Hexagon::C2_cmpgtu: {
if (secondRegNewified)
return taken ? Hexagon::CMPLTUrr_t_Jumpnv_t_V4
: Hexagon::CMPLTUrr_t_Jumpnv_nt_V4;
@@ -339,7 +338,7 @@ static unsigned getNewValueJumpOpcode(MachineInstr *MI, int reg,
: Hexagon::CMPGTUrr_t_Jumpnv_nt_V4;
}
- case Hexagon::CMPGTUri:
+ case Hexagon::C2_cmpgtui:
return taken ? Hexagon::CMPGTUri_t_Jumpnv_t_V4
: Hexagon::CMPGTUri_t_Jumpnv_nt_V4;
@@ -362,9 +361,9 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
LiveVariables &LVs = getAnalysis<LiveVariables>();
#endif
- QII = static_cast<const HexagonInstrInfo *>(MF.getTarget().getInstrInfo());
- QRI =
- static_cast<const HexagonRegisterInfo *>(MF.getTarget().getRegisterInfo());
+ QII = static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());
+ QRI = static_cast<const HexagonRegisterInfo *>(
+ MF.getSubtarget().getRegisterInfo());
MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
if (!QRI->Subtarget.hasV4TOps() ||
@@ -413,12 +412,12 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
DEBUG(dbgs() << "Instr: "; MI->dump(); dbgs() << "\n");
if (!foundJump &&
- (MI->getOpcode() == Hexagon::JMP_t ||
- MI->getOpcode() == Hexagon::JMP_f ||
- MI->getOpcode() == Hexagon::JMP_tnew_t ||
- MI->getOpcode() == Hexagon::JMP_tnew_nt ||
- MI->getOpcode() == Hexagon::JMP_fnew_t ||
- MI->getOpcode() == Hexagon::JMP_fnew_nt)) {
+ (MI->getOpcode() == Hexagon::J2_jumpt ||
+ MI->getOpcode() == Hexagon::J2_jumpf ||
+ MI->getOpcode() == Hexagon::J2_jumptnewpt ||
+ MI->getOpcode() == Hexagon::J2_jumptnew ||
+ MI->getOpcode() == Hexagon::J2_jumpfnewpt ||
+ MI->getOpcode() == Hexagon::J2_jumpfnew)) {
// This is where you would insert your compare and
// instr that feeds compare
jmpPos = MII;
@@ -454,9 +453,9 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
jmpTarget = MI->getOperand(1).getMBB();
foundJump = true;
- if (MI->getOpcode() == Hexagon::JMP_f ||
- MI->getOpcode() == Hexagon::JMP_fnew_t ||
- MI->getOpcode() == Hexagon::JMP_fnew_nt) {
+ if (MI->getOpcode() == Hexagon::J2_jumpf ||
+ MI->getOpcode() == Hexagon::J2_jumpfnewpt ||
+ MI->getOpcode() == Hexagon::J2_jumpfnew) {
invertPredicate = true;
}
continue;
@@ -545,7 +544,7 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
if (isSecondOpReg) {
// In case of CMPLT, or CMPLTU, or EQ with the second register
// to newify, swap the operands.
- if (cmpInstr->getOpcode() == Hexagon::CMPEQrr &&
+ if (cmpInstr->getOpcode() == Hexagon::C2_cmpeq &&
feederReg == (unsigned) cmpOp2) {
unsigned tmp = cmpReg1;
bool tmpIsKill = MO1IsKill;
@@ -612,8 +611,8 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
.addReg(cmpOp2, getKillRegState(MO2IsKill))
.addMBB(jmpTarget);
- else if ((cmpInstr->getOpcode() == Hexagon::CMPEQri ||
- cmpInstr->getOpcode() == Hexagon::CMPGTri) &&
+ else if ((cmpInstr->getOpcode() == Hexagon::C2_cmpeqi ||
+ cmpInstr->getOpcode() == Hexagon::C2_cmpgti) &&
cmpOp2 == -1 )
// Corresponding new-value compare jump instructions don't have the
// operand for -1 immediate value.
diff --git a/lib/Target/Hexagon/HexagonOperands.td b/lib/Target/Hexagon/HexagonOperands.td
index c79d78f21080..5a6de0ae2746 100644
--- a/lib/Target/Hexagon/HexagonOperands.td
+++ b/lib/Target/Hexagon/HexagonOperands.td
@@ -39,6 +39,7 @@ let PrintMethod = "printImmOperand" in {
def u16_0Imm : Operand<i32>;
def u16_1Imm : Operand<i32>;
def u16_2Imm : Operand<i32>;
+ def u16_3Imm : Operand<i32>;
def u11_3Imm : Operand<i32>;
def u10Imm : Operand<i32>;
def u9Imm : Operand<i32>;
@@ -258,6 +259,13 @@ def u16_s8ImmPred : PatLeaf<(i32 imm), [{
return isShiftedUInt<16,8>(v);
}]>;
+def u11_3ImmPred : PatLeaf<(i32 imm), [{
+ // True if the immediate fits in a 14-bit unsigned field, and the lowest
+ // three bits are 0.
+ int64_t v = (int64_t)N->getSExtValue();
+ return isShiftedUInt<11,3>(v);
+}]>;
+
def u9ImmPred : PatLeaf<(i32 imm), [{
// u9ImmPred predicate - True if the immediate fits in a 9-bit unsigned
// field.
@@ -800,6 +808,12 @@ def u6_3ExtPred : PatLeaf<(i32 imm), [{
}
}]>;
+
+// This complex pattern exists only to create a machine instruction operand
+// of type "frame index". There doesn't seem to be a way to do that directly
+// in the patterns.
+def AddrFI : ComplexPattern<i32, 1, "SelectAddrFI", [frameindex], []>;
+
// Addressing modes.
def ADDRrr : ComplexPattern<i32, 2, "SelectADDRrr", [], []>;
@@ -856,3 +870,12 @@ def symbolHi32 : Operand<i32> {
def symbolLo32 : Operand<i32> {
let PrintMethod = "printSymbolLo";
}
+
+// Return true if for a 32 to 64-bit sign-extended load.
+def is_sext_i32 : PatLeaf<(i64 DoubleRegs:$src1), [{
+ LoadSDNode *LD = dyn_cast<LoadSDNode>(N);
+ if (!LD)
+ return false;
+ return LD->getExtensionType() == ISD::SEXTLOAD &&
+ LD->getMemoryVT().getScalarType() == MVT::i32;
+}]>;
diff --git a/lib/Target/Hexagon/HexagonPeephole.cpp b/lib/Target/Hexagon/HexagonPeephole.cpp
index 48b61590853a..e9b2ef6b3911 100644
--- a/lib/Target/Hexagon/HexagonPeephole.cpp
+++ b/lib/Target/Hexagon/HexagonPeephole.cpp
@@ -111,10 +111,8 @@ INITIALIZE_PASS(HexagonPeephole, "hexagon-peephole", "Hexagon Peephole",
false, false)
bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
- QII = static_cast<const HexagonInstrInfo *>(MF.getTarget().
- getInstrInfo());
- QRI = static_cast<const HexagonRegisterInfo *>(MF.getTarget().
- getRegisterInfo());
+ QII = static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());
+ QRI = MF.getTarget().getSubtarget<HexagonSubtarget>().getRegisterInfo();
MRI = &MF.getRegInfo();
DenseMap<unsigned, unsigned> PeepholeMap;
@@ -135,7 +133,7 @@ bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
MachineInstr *MI = MII;
// Look for sign extends:
// %vreg170<def> = SXTW %vreg166
- if (!DisableOptSZExt && MI->getOpcode() == Hexagon::SXTW) {
+ if (!DisableOptSZExt && MI->getOpcode() == Hexagon::A2_sxtw) {
assert (MI->getNumOperands() == 2);
MachineOperand &Dst = MI->getOperand(0);
MachineOperand &Src = MI->getOperand(1);
@@ -154,7 +152,7 @@ bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
// Look for %vreg170<def> = COMBINE_ir_V4 (0, %vreg169)
// %vreg170:DoublRegs, %vreg169:IntRegs
if (!DisableOptExtTo64 &&
- MI->getOpcode () == Hexagon::COMBINE_Ir_V4) {
+ MI->getOpcode () == Hexagon::A4_combineir) {
assert (MI->getNumOperands() == 3);
MachineOperand &Dst = MI->getOperand(0);
MachineOperand &Src1 = MI->getOperand(1);
@@ -171,7 +169,7 @@ bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
// %vregIntReg = COPY %vregDoubleReg1:subreg_loreg.
// and convert into
// %vregIntReg = COPY %vregDoubleReg0:subreg_hireg.
- if (MI->getOpcode() == Hexagon::LSRd_ri) {
+ if (MI->getOpcode() == Hexagon::S2_lsr_i_p) {
assert(MI->getNumOperands() == 3);
MachineOperand &Dst = MI->getOperand(0);
MachineOperand &Src1 = MI->getOperand(1);
@@ -186,7 +184,7 @@ bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
// Look for P=NOT(P).
if (!DisablePNotP &&
- (MI->getOpcode() == Hexagon::NOT_p)) {
+ (MI->getOpcode() == Hexagon::C2_not)) {
assert (MI->getNumOperands() == 2);
MachineOperand &Dst = MI->getOperand(0);
MachineOperand &Src = MI->getOperand(1);
@@ -271,10 +269,9 @@ bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
unsigned PR = 1, S1 = 2, S2 = 3; // Operand indices.
switch (Op) {
- case Hexagon::TFR_condset_rr:
+ case Hexagon::C2_mux:
+ case Hexagon::C2_muxii:
case Hexagon::TFR_condset_ii:
- case Hexagon::MUX_ii:
- case Hexagon::MUX_rr:
NewOp = Op;
break;
case Hexagon::TFR_condset_ri:
@@ -283,11 +280,11 @@ bool HexagonPeephole::runOnMachineFunction(MachineFunction &MF) {
case Hexagon::TFR_condset_ir:
NewOp = Hexagon::TFR_condset_ri;
break;
- case Hexagon::MUX_ri:
- NewOp = Hexagon::MUX_ir;
+ case Hexagon::C2_muxri:
+ NewOp = Hexagon::C2_muxir;
break;
- case Hexagon::MUX_ir:
- NewOp = Hexagon::MUX_ri;
+ case Hexagon::C2_muxir:
+ NewOp = Hexagon::C2_muxri;
break;
}
if (NewOp) {
diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/lib/Target/Hexagon/HexagonRegisterInfo.cpp
index fb466d3b5908..a64c9df9a047 100644
--- a/lib/Target/Hexagon/HexagonRegisterInfo.cpp
+++ b/lib/Target/Hexagon/HexagonRegisterInfo.cpp
@@ -128,12 +128,12 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
// Addressable stack objects are accessed using neg. offsets from %fp.
MachineFunction &MF = *MI.getParent()->getParent();
const HexagonInstrInfo &TII =
- *static_cast<const HexagonInstrInfo*>(MF.getTarget().getInstrInfo());
+ *static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo());
int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
MachineFrameInfo &MFI = *MF.getFrameInfo();
unsigned FrameReg = getFrameRegister(MF);
- const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
+ const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
if (!TFI->hasFP(MF)) {
// We will not reserve space on the stack for the lr and fp registers.
Offset -= 2 * Hexagon_WordSize;
@@ -159,15 +159,15 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
//
// r0 = add(r30, #10000)
// r0 = memw(r0)
- if ( (MI.getOpcode() == Hexagon::LDriw) ||
- (MI.getOpcode() == Hexagon::LDrid) ||
- (MI.getOpcode() == Hexagon::LDrih) ||
- (MI.getOpcode() == Hexagon::LDriuh) ||
- (MI.getOpcode() == Hexagon::LDrib) ||
- (MI.getOpcode() == Hexagon::LDriub) ||
+ if ( (MI.getOpcode() == Hexagon::L2_loadri_io) ||
+ (MI.getOpcode() == Hexagon::L2_loadrd_io) ||
+ (MI.getOpcode() == Hexagon::L2_loadrh_io) ||
+ (MI.getOpcode() == Hexagon::L2_loadruh_io) ||
+ (MI.getOpcode() == Hexagon::L2_loadrb_io) ||
+ (MI.getOpcode() == Hexagon::L2_loadrub_io) ||
(MI.getOpcode() == Hexagon::LDriw_f) ||
(MI.getOpcode() == Hexagon::LDrid_f)) {
- unsigned dstReg = (MI.getOpcode() == Hexagon::LDrid) ?
+ unsigned dstReg = (MI.getOpcode() == Hexagon::L2_loadrd_io) ?
getSubReg(MI.getOperand(0).getReg(), Hexagon::subreg_loreg) :
MI.getOperand(0).getReg();
@@ -176,7 +176,7 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset);
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
- TII.get(Hexagon::ADD_rr),
+ TII.get(Hexagon::A2_add),
dstReg).addReg(FrameReg).addReg(dstReg);
} else {
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
@@ -186,11 +186,10 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
MI.getOperand(FIOperandNum).ChangeToRegister(dstReg, false, false,true);
MI.getOperand(FIOperandNum+1).ChangeToImmediate(0);
- } else if ((MI.getOpcode() == Hexagon::STriw_indexed) ||
- (MI.getOpcode() == Hexagon::STriw) ||
- (MI.getOpcode() == Hexagon::STrid) ||
- (MI.getOpcode() == Hexagon::STrih) ||
- (MI.getOpcode() == Hexagon::STrib) ||
+ } else if ((MI.getOpcode() == Hexagon::S2_storeri_io) ||
+ (MI.getOpcode() == Hexagon::S2_storerd_io) ||
+ (MI.getOpcode() == Hexagon::S2_storerh_io) ||
+ (MI.getOpcode() == Hexagon::S2_storerb_io) ||
(MI.getOpcode() == Hexagon::STrid_f) ||
(MI.getOpcode() == Hexagon::STriw_f)) {
// For stores, we need a reserved register. Change
@@ -205,7 +204,7 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
TII.get(Hexagon::CONST32_Int_Real), resReg).addImm(Offset);
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
- TII.get(Hexagon::ADD_rr),
+ TII.get(Hexagon::A2_add),
resReg).addReg(FrameReg).addReg(resReg);
} else {
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
@@ -237,7 +236,7 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
TII.get(Hexagon::CONST32_Int_Real), ResReg).addImm(Offset);
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
- TII.get(Hexagon::ADD_rr), ResReg).addReg(FrameReg).
+ TII.get(Hexagon::A2_add), ResReg).addReg(FrameReg).
addReg(ResReg);
MI.getOperand(FIOperandNum).ChangeToRegister(ResReg, false, false,
true);
@@ -256,7 +255,7 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset);
BuildMI(*MI.getParent(), II, MI.getDebugLoc(),
- TII.get(Hexagon::ADD_rr),
+ TII.get(Hexagon::A2_add),
dstReg).addReg(FrameReg).addReg(dstReg);
// Can we delete MI??? r2 = add (r2, #0).
MI.getOperand(FIOperandNum).ChangeToRegister(dstReg, false, false,true);
@@ -278,7 +277,7 @@ unsigned HexagonRegisterInfo::getRARegister() const {
unsigned HexagonRegisterInfo::getFrameRegister(const MachineFunction
&MF) const {
- const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
+ const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
if (TFI->hasFP(MF)) {
return Hexagon::R30;
}
diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.h b/lib/Target/Hexagon/HexagonRegisterInfo.h
index 648b4af9e957..a83b5026467a 100644
--- a/lib/Target/Hexagon/HexagonRegisterInfo.h
+++ b/lib/Target/Hexagon/HexagonRegisterInfo.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef HexagonREGISTERINFO_H
-#define HexagonREGISTERINFO_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONREGISTERINFO_H
+#define LLVM_LIB_TARGET_HEXAGON_HEXAGONREGISTERINFO_H
#include "llvm/MC/MachineLocation.h"
#include "llvm/Target/TargetRegisterInfo.h"
diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.td b/lib/Target/Hexagon/HexagonRegisterInfo.td
index 8ea1b7e75db7..decd94722da1 100644
--- a/lib/Target/Hexagon/HexagonRegisterInfo.td
+++ b/lib/Target/Hexagon/HexagonRegisterInfo.td
@@ -13,90 +13,78 @@
let Namespace = "Hexagon" in {
- class HexagonReg<string n> : Register<n> {
+ class HexagonReg<bits<5> num, string n, list<string> alt = [],
+ list<Register> alias = []> : Register<n> {
field bits<5> Num;
+ let Aliases = alias;
+ let HWEncoding{4-0} = num;
}
- class HexagonDoubleReg<string n, list<Register> subregs> :
+ class HexagonDoubleReg<bits<5> num, string n, list<Register> subregs,
+ list<string> alt = []> :
RegisterWithSubRegs<n, subregs> {
field bits<5> Num;
+
+ let AltNames = alt;
+ let HWEncoding{4-0} = num;
}
// Registers are identified with 5-bit ID numbers.
// Ri - 32-bit integer registers.
- class Ri<bits<5> num, string n> : HexagonReg<n> {
+ class Ri<bits<5> num, string n, list<string> alt = []> : HexagonReg<num, n, alt> {
let Num = num;
}
// Rf - 32-bit floating-point registers.
- class Rf<bits<5> num, string n> : HexagonReg<n> {
+ class Rf<bits<5> num, string n> : HexagonReg<num, n> {
let Num = num;
}
// Rd - 64-bit registers.
class Rd<bits<5> num, string n, list<Register> subregs> :
- HexagonDoubleReg<n, subregs> {
+ HexagonDoubleReg<num, n, subregs> {
let Num = num;
let SubRegs = subregs;
}
// Rp - predicate registers
- class Rp<bits<5> num, string n> : HexagonReg<n> {
+ class Rp<bits<5> num, string n> : HexagonReg<num, n> {
let Num = num;
}
// Rc - control registers
- class Rc<bits<5> num, string n> : HexagonReg<n> {
+ class Rc<bits<5> num, string n,
+ list<string> alt = [], list<Register> alias = []> :
+ HexagonReg<num, n, alt, alias> {
+ let Num = num;
+ }
+
+ // Rcc - 64-bit control registers.
+ class Rcc<bits<5> num, string n, list<Register> subregs,
+ list<string> alt = []> :
+ HexagonDoubleReg<num, n, subregs, alt> {
let Num = num;
+ let SubRegs = subregs;
}
- // Rj - aliased integer registers
- class Rj<string n, Ri R>: HexagonReg<n> {
- let Num = R.Num;
- let Aliases = [R];
+ // Mx - address modifier registers
+ class Mx<bits<1> num, string n> : HexagonReg<{0b0000, num}, n> {
+ let Num = !cast<bits<5>>(num);
}
def subreg_loreg : SubRegIndex<32>;
def subreg_hireg : SubRegIndex<32, 32>;
+ def subreg_overflow : SubRegIndex<1, 0>;
// Integer registers.
- def R0 : Ri< 0, "r0">, DwarfRegNum<[0]>;
- def R1 : Ri< 1, "r1">, DwarfRegNum<[1]>;
- def R2 : Ri< 2, "r2">, DwarfRegNum<[2]>;
- def R3 : Ri< 3, "r3">, DwarfRegNum<[3]>;
- def R4 : Ri< 4, "r4">, DwarfRegNum<[4]>;
- def R5 : Ri< 5, "r5">, DwarfRegNum<[5]>;
- def R6 : Ri< 6, "r6">, DwarfRegNum<[6]>;
- def R7 : Ri< 7, "r7">, DwarfRegNum<[7]>;
- def R8 : Ri< 8, "r8">, DwarfRegNum<[8]>;
- def R9 : Ri< 9, "r9">, DwarfRegNum<[9]>;
- def R10 : Ri<10, "r10">, DwarfRegNum<[10]>;
- def R11 : Ri<11, "r11">, DwarfRegNum<[11]>;
- def R12 : Ri<12, "r12">, DwarfRegNum<[12]>;
- def R13 : Ri<13, "r13">, DwarfRegNum<[13]>;
- def R14 : Ri<14, "r14">, DwarfRegNum<[14]>;
- def R15 : Ri<15, "r15">, DwarfRegNum<[15]>;
- def R16 : Ri<16, "r16">, DwarfRegNum<[16]>;
- def R17 : Ri<17, "r17">, DwarfRegNum<[17]>;
- def R18 : Ri<18, "r18">, DwarfRegNum<[18]>;
- def R19 : Ri<19, "r19">, DwarfRegNum<[19]>;
- def R20 : Ri<20, "r20">, DwarfRegNum<[20]>;
- def R21 : Ri<21, "r21">, DwarfRegNum<[21]>;
- def R22 : Ri<22, "r22">, DwarfRegNum<[22]>;
- def R23 : Ri<23, "r23">, DwarfRegNum<[23]>;
- def R24 : Ri<24, "r24">, DwarfRegNum<[24]>;
- def R25 : Ri<25, "r25">, DwarfRegNum<[25]>;
- def R26 : Ri<26, "r26">, DwarfRegNum<[26]>;
- def R27 : Ri<27, "r27">, DwarfRegNum<[27]>;
- def R28 : Ri<28, "r28">, DwarfRegNum<[28]>;
- def R29 : Ri<29, "r29">, DwarfRegNum<[29]>;
- def R30 : Ri<30, "r30">, DwarfRegNum<[30]>;
- def R31 : Ri<31, "r31">, DwarfRegNum<[31]>;
-
- def SP : Rj<"sp", R29>, DwarfRegNum<[29]>;
- def FP : Rj<"fp", R30>, DwarfRegNum<[30]>;
- def LR : Rj<"lr", R31>, DwarfRegNum<[31]>;
+ foreach i = 0-28 in {
+ def R#i : Ri<i, "r"#i>, DwarfRegNum<[i]>;
+ }
+
+ def R29 : Ri<29, "r29", ["sp"]>, DwarfRegNum<[29]>;
+ def R30 : Ri<30, "r30", ["fp"]>, DwarfRegNum<[30]>;
+ def R31 : Ri<31, "r31", ["lr"]>, DwarfRegNum<[31]>;
// Aliases of the R* registers used to hold 64-bit int values (doubles).
let SubRegIndices = [subreg_loreg, subreg_hireg], CoveredBySubRegs = 1 in {
@@ -124,20 +112,52 @@ let Namespace = "Hexagon" in {
def P2 : Rp<2, "p2">, DwarfRegNum<[65]>;
def P3 : Rp<3, "p3">, DwarfRegNum<[66]>;
- // Control registers.
- def SA0 : Rc<0, "sa0">, DwarfRegNum<[67]>;
- def LC0 : Rc<1, "lc0">, DwarfRegNum<[68]>;
-
- def SA1 : Rc<2, "sa1">, DwarfRegNum<[69]>;
- def LC1 : Rc<3, "lc1">, DwarfRegNum<[70]>;
+ // Modifier registers.
+ // C6 and C7 can also be M0 and M1, but register names must be unique, even
+ // if belonging to different register classes.
+ def M0 : Mx<0, "m0">, DwarfRegNum<[72]>;
+ def M1 : Mx<1, "m1">, DwarfRegNum<[73]>;
- def M0 : Rc<6, "m0">, DwarfRegNum<[71]>;
- def M1 : Rc<7, "m1">, DwarfRegNum<[72]>;
+ // Fake register to represent USR.OVF bit. Artihmetic/saturating instruc-
+ // tions modify this bit, and multiple such instructions are allowed in the
+ // same packet. We need to ignore output dependencies on this bit, but not
+ // on the entire USR.
+ def USR_OVF : Rc<?, "usr.ovf">;
- def PC : Rc<9, "pc">, DwarfRegNum<[32]>; // is the Dwarf number correct?
- def GP : Rc<11, "gp">, DwarfRegNum<[33]>; // is the Dwarf number correct?
+ // Control registers.
+ def SA0 : Rc<0, "sa0", ["c0"]>, DwarfRegNum<[67]>;
+ def LC0 : Rc<1, "lc0", ["c1"]>, DwarfRegNum<[68]>;
+ def SA1 : Rc<2, "sa1", ["c2"]>, DwarfRegNum<[69]>;
+ def LC1 : Rc<3, "lc1", ["c3"]>, DwarfRegNum<[70]>;
+ def P3_0 : Rc<4, "p3:0", ["c4"], [P0, P1, P2, P3]>,
+ DwarfRegNum<[71]>;
+ def C6 : Rc<6, "c6", [], [M0]>, DwarfRegNum<[72]>;
+ def C7 : Rc<7, "c7", [], [M1]>, DwarfRegNum<[73]>;
+
+ def USR : Rc<8, "usr", ["c8"]>, DwarfRegNum<[74]> {
+ let SubRegIndices = [subreg_overflow];
+ let SubRegs = [USR_OVF];
+ }
+ def PC : Rc<9, "pc">, DwarfRegNum<[75]>;
+ def UGP : Rc<10, "ugp", ["c10"]>, DwarfRegNum<[76]>;
+ def GP : Rc<11, "gp">, DwarfRegNum<[77]>;
+ def CS0 : Rc<12, "cs0", ["c12"]>, DwarfRegNum<[78]>;
+ def CS1 : Rc<13, "cs1", ["c13"]>, DwarfRegNum<[79]>;
+ def UPCL : Rc<14, "upcyclelo", ["c14"]>, DwarfRegNum<[80]>;
+ def UPCH : Rc<15, "upcyclehi", ["c15"]>, DwarfRegNum<[81]>;
}
+ // Control registers pairs.
+ let SubRegIndices = [subreg_loreg, subreg_hireg], CoveredBySubRegs = 1 in {
+ def C1_0 : Rcc<0, "c1:0", [SA0, LC0], ["lc0:sa0"]>, DwarfRegNum<[67]>;
+ def C3_2 : Rcc<2, "c3:2", [SA1, LC1], ["lc1:sa1"]>, DwarfRegNum<[69]>;
+ def C7_6 : Rcc<6, "c7:6", [C6, C7], ["m1:0"]>, DwarfRegNum<[72]>;
+ def C9_8 : Rcc<8, "c9:8", [USR, PC]>, DwarfRegNum<[74]>;
+ def C11_10 : Rcc<10, "c11:10", [UGP, GP]>, DwarfRegNum<[76]>;
+ def CS : Rcc<12, "c13:12", [CS0, CS1], ["cs1:0"]>, DwarfRegNum<[78]>;
+ def UPC : Rcc<14, "c15:14", [UPCL, UPCH]>, DwarfRegNum<[80]>;
+ }
+
// Register classes.
//
// FIXME: the register order should be defined in terms of the preferred
@@ -159,9 +179,29 @@ def PredRegs : RegisterClass<"Hexagon", [i1], 32, (add (sequence "P%u", 0, 3))>
let Size = 32;
}
-def CRRegs : RegisterClass<"Hexagon", [i32], 32,
- (add (sequence "LC%u", 0, 1),
- (sequence "SA%u", 0, 1),
- (sequence "M%u", 0, 1), PC, GP)> {
- let Size = 32;
+let Size = 32 in
+def ModRegs : RegisterClass<"Hexagon", [i32], 32, (add M0, M1)>;
+
+let Size = 32, isAllocatable = 0 in
+def CtrRegs : RegisterClass<"Hexagon", [i32], 32,
+ (add LC0, SA0, LC1, SA1,
+ P3_0,
+ M0, M1, C6, C7, CS0, CS1, UPCL, UPCH,
+ USR, USR_OVF, UGP, GP, PC)>;
+
+let Size = 64, isAllocatable = 0 in
+def CtrRegs64 : RegisterClass<"Hexagon", [i64], 64,
+ (add C1_0, C3_2, C7_6, C9_8, C11_10, CS, UPC)>;
+
+def VolatileV3 {
+ list<Register> Regs = [D0, D1, D2, D3, D4, D5, D6, D7,
+ R28, R31,
+ P0, P1, P2, P3,
+ M0, M1,
+ LC0, LC1, SA0, SA1, USR, USR_OVF];
}
+
+def PositiveHalfWord : PatLeaf<(i32 IntRegs:$a),
+[{
+ return isPositiveHalfWord(N);
+}]>;
diff --git a/lib/Target/Hexagon/HexagonSelectionDAGInfo.h b/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
index b40b30320cf1..8ac2e43f9294 100644
--- a/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
+++ b/lib/Target/Hexagon/HexagonSelectionDAGInfo.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef HexagonSELECTIONDAGINFO_H
-#define HexagonSELECTIONDAGINFO_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONSELECTIONDAGINFO_H
+#define LLVM_LIB_TARGET_HEXAGON_HEXAGONSELECTIONDAGINFO_H
#include "llvm/Target/TargetSelectionDAGInfo.h"
diff --git a/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp b/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp
index 247207f992dc..8fdd493a75dc 100644
--- a/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp
+++ b/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp
@@ -68,12 +68,13 @@ char HexagonSplitConst32AndConst64::ID = 0;
bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) {
const HexagonTargetObjectFile &TLOF =
- (const HexagonTargetObjectFile &)
- QTM.getTargetLowering()->getObjFileLowering();
+ (const HexagonTargetObjectFile &)QTM.getSubtargetImpl()
+ ->getTargetLowering()
+ ->getObjFileLowering();
if (TLOF.IsSmallDataEnabled())
return true;
- const TargetInstrInfo *TII = QTM.getInstrInfo();
+ const TargetInstrInfo *TII = QTM.getSubtargetImpl()->getInstrInfo();
// Loop over all of the basic blocks
for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
@@ -138,10 +139,10 @@ bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) {
else if (Opc == Hexagon::CONST64_Int_Real) {
int DestReg = MI->getOperand(0).getReg();
int64_t ImmValue = MI->getOperand(1).getImm ();
- unsigned DestLo =
- QTM.getRegisterInfo()->getSubReg (DestReg, Hexagon::subreg_loreg);
- unsigned DestHi =
- QTM.getRegisterInfo()->getSubReg (DestReg, Hexagon::subreg_hireg);
+ unsigned DestLo = QTM.getSubtargetImpl()->getRegisterInfo()->getSubReg(
+ DestReg, Hexagon::subreg_loreg);
+ unsigned DestHi = QTM.getSubtargetImpl()->getRegisterInfo()->getSubReg(
+ DestReg, Hexagon::subreg_hireg);
int32_t LowWord = (ImmValue & 0xFFFFFFFF);
int32_t HighWord = (ImmValue >> 32) & 0xFFFFFFFF;
diff --git a/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp b/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp
index 9601090af469..a304e655f0b1 100644
--- a/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp
+++ b/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp
@@ -80,7 +80,7 @@ char HexagonSplitTFRCondSets::ID = 0;
bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) {
- const TargetInstrInfo *TII = QTM.getInstrInfo();
+ const TargetInstrInfo *TII = QTM.getSubtargetImpl()->getInstrInfo();
// Loop over all of the basic blocks.
for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
@@ -92,21 +92,19 @@ bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) {
MachineInstr *MI = MII;
int Opc1, Opc2;
switch(MI->getOpcode()) {
- case Hexagon::TFR_condset_rr:
case Hexagon::TFR_condset_rr_f:
case Hexagon::TFR_condset_rr64_f: {
int DestReg = MI->getOperand(0).getReg();
int SrcReg1 = MI->getOperand(2).getReg();
int SrcReg2 = MI->getOperand(3).getReg();
- if (MI->getOpcode() == Hexagon::TFR_condset_rr ||
- MI->getOpcode() == Hexagon::TFR_condset_rr_f) {
- Opc1 = Hexagon::TFR_cPt;
- Opc2 = Hexagon::TFR_cNotPt;
+ if (MI->getOpcode() == Hexagon::TFR_condset_rr_f) {
+ Opc1 = Hexagon::A2_tfrt;
+ Opc2 = Hexagon::A2_tfrf;
}
else if (MI->getOpcode() == Hexagon::TFR_condset_rr64_f) {
- Opc1 = Hexagon::TFR64_cPt;
- Opc2 = Hexagon::TFR64_cNotPt;
+ Opc1 = Hexagon::A2_tfrpt;
+ Opc2 = Hexagon::A2_tfrpf;
}
// Minor optimization: do not emit the predicated copy if the source
@@ -132,12 +130,12 @@ bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) {
// is the same register.
if (DestReg != SrcReg1) {
BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Hexagon::TFR_cPt), DestReg).
+ TII->get(Hexagon::A2_tfrt), DestReg).
addReg(MI->getOperand(1).getReg()).addReg(SrcReg1);
}
if (MI->getOpcode() == Hexagon::TFR_condset_ri ) {
BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Hexagon::TFRI_cNotPt), DestReg).
+ TII->get(Hexagon::C2_cmoveif), DestReg).
addReg(MI->getOperand(1).getReg()).
addImm(MI->getOperand(3).getImm());
} else if (MI->getOpcode() == Hexagon::TFR_condset_ri_f ) {
@@ -158,7 +156,7 @@ bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) {
if (MI->getOpcode() == Hexagon::TFR_condset_ir ) {
BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Hexagon::TFRI_cPt), DestReg).
+ TII->get(Hexagon::C2_cmoveit), DestReg).
addReg(MI->getOperand(1).getReg()).
addImm(MI->getOperand(2).getImm());
} else if (MI->getOpcode() == Hexagon::TFR_condset_ir_f ) {
@@ -172,7 +170,7 @@ bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) {
// the destination is the same register.
if (DestReg != SrcReg2) {
BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Hexagon::TFR_cNotPt), DestReg).
+ TII->get(Hexagon::A2_tfrf), DestReg).
addReg(MI->getOperand(1).getReg()).addReg(SrcReg2);
}
MII = MBB->erase(MI);
@@ -188,10 +186,10 @@ bool HexagonSplitTFRCondSets::runOnMachineFunction(MachineFunction &Fn) {
int Immed1 = MI->getOperand(2).getImm();
int Immed2 = MI->getOperand(3).getImm();
BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Hexagon::TFRI_cPt),
+ TII->get(Hexagon::C2_cmoveit),
DestReg).addReg(SrcReg1).addImm(Immed1);
BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Hexagon::TFRI_cNotPt),
+ TII->get(Hexagon::C2_cmoveif),
DestReg).addReg(SrcReg1).addImm(Immed2);
} else if (MI->getOpcode() == Hexagon::TFR_condset_ii_f ) {
BuildMI(*MBB, MII, MI->getDebugLoc(),
diff --git a/lib/Target/Hexagon/HexagonSubtarget.h b/lib/Target/Hexagon/HexagonSubtarget.h
index b184e62b4d0d..34e327f7c3a1 100644
--- a/lib/Target/Hexagon/HexagonSubtarget.h
+++ b/lib/Target/Hexagon/HexagonSubtarget.h
@@ -11,12 +11,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef Hexagon_SUBTARGET_H
-#define Hexagon_SUBTARGET_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONSUBTARGET_H
+#define LLVM_LIB_TARGET_HEXAGON_HEXAGONSUBTARGET_H
#include "HexagonFrameLowering.h"
-#include "HexagonInstrInfo.h"
#include "HexagonISelLowering.h"
+#include "HexagonInstrInfo.h"
#include "HexagonSelectionDAGInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/Target/TargetMachine.h"
@@ -56,19 +56,25 @@ public:
HexagonSubtarget(StringRef TT, StringRef CPU, StringRef FS,
const TargetMachine &TM);
- /// getInstrItins - Return the instruction itineraies based on subtarget
+ /// getInstrItins - Return the instruction itineraries based on subtarget
/// selection.
- const InstrItineraryData &getInstrItineraryData() const { return InstrItins; }
- const HexagonInstrInfo *getInstrInfo() const { return &InstrInfo; }
- const HexagonRegisterInfo *getRegisterInfo() const {
+ const InstrItineraryData *getInstrItineraryData() const override {
+ return &InstrItins;
+ }
+ const HexagonInstrInfo *getInstrInfo() const override { return &InstrInfo; }
+ const HexagonRegisterInfo *getRegisterInfo() const override {
return &InstrInfo.getRegisterInfo();
}
- const HexagonTargetLowering *getTargetLowering() const { return &TLInfo; }
- const HexagonFrameLowering *getFrameLowering() const {
+ const HexagonTargetLowering *getTargetLowering() const override {
+ return &TLInfo;
+ }
+ const HexagonFrameLowering *getFrameLowering() const override {
return &FrameLowering;
}
- const HexagonSelectionDAGInfo *getSelectionDAGInfo() const { return &TSInfo; }
- const DataLayout *getDataLayout() const { return &DL; }
+ const HexagonSelectionDAGInfo *getSelectionDAGInfo() const override {
+ return &TSInfo;
+ }
+ const DataLayout *getDataLayout() const override { return &DL; }
HexagonSubtarget &initializeSubtargetDependencies(StringRef CPU,
StringRef FS);
diff --git a/lib/Target/Hexagon/HexagonTargetMachine.cpp b/lib/Target/Hexagon/HexagonTargetMachine.cpp
index 78314100d18a..52aff2787bac 100644
--- a/lib/Target/Hexagon/HexagonTargetMachine.cpp
+++ b/lib/Target/Hexagon/HexagonTargetMachine.cpp
@@ -70,10 +70,13 @@ HexagonTargetMachine::HexagonTargetMachine(const Target &T, StringRef TT,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
+ TLOF(make_unique<HexagonTargetObjectFile>()),
Subtarget(TT, CPU, FS, *this) {
initAsmInfo();
}
+HexagonTargetMachine::~HexagonTargetMachine() {}
+
namespace {
/// Hexagon Code Generator Pass Configuration Options.
class HexagonPassConfig : public TargetPassConfig {
@@ -100,10 +103,10 @@ public:
}
bool addInstSelector() override;
- bool addPreRegAlloc() override;
- bool addPostRegAlloc() override;
- bool addPreSched2() override;
- bool addPreEmitPass() override;
+ void addPreRegAlloc() override;
+ void addPostRegAlloc() override;
+ void addPreSched2() override;
+ void addPreEmitPass() override;
};
} // namespace
@@ -128,51 +131,45 @@ bool HexagonPassConfig::addInstSelector() {
return false;
}
-bool HexagonPassConfig::addPreRegAlloc() {
+void HexagonPassConfig::addPreRegAlloc() {
if (getOptLevel() != CodeGenOpt::None)
if (!DisableHardwareLoops)
- addPass(createHexagonHardwareLoops());
- return false;
+ addPass(createHexagonHardwareLoops(), false);
}
-bool HexagonPassConfig::addPostRegAlloc() {
+void HexagonPassConfig::addPostRegAlloc() {
const HexagonTargetMachine &TM = getHexagonTargetMachine();
if (getOptLevel() != CodeGenOpt::None)
if (!DisableHexagonCFGOpt)
- addPass(createHexagonCFGOptimizer(TM));
- return false;
+ addPass(createHexagonCFGOptimizer(TM), false);
}
-bool HexagonPassConfig::addPreSched2() {
+void HexagonPassConfig::addPreSched2() {
const HexagonTargetMachine &TM = getHexagonTargetMachine();
- addPass(createHexagonCopyToCombine());
+ addPass(createHexagonCopyToCombine(), false);
if (getOptLevel() != CodeGenOpt::None)
- addPass(&IfConverterID);
+ addPass(&IfConverterID, false);
addPass(createHexagonSplitConst32AndConst64(TM));
- printAndVerify("After hexagon split const32/64 pass");
- return true;
}
-bool HexagonPassConfig::addPreEmitPass() {
+void HexagonPassConfig::addPreEmitPass() {
const HexagonTargetMachine &TM = getHexagonTargetMachine();
bool NoOpt = (getOptLevel() == CodeGenOpt::None);
if (!NoOpt)
- addPass(createHexagonNewValueJump());
+ addPass(createHexagonNewValueJump(), false);
// Expand Spill code for predicate registers.
- addPass(createHexagonExpandPredSpillCode(TM));
+ addPass(createHexagonExpandPredSpillCode(TM), false);
// Split up TFRcondsets into conditional transfers.
- addPass(createHexagonSplitTFRCondSets(TM));
+ addPass(createHexagonSplitTFRCondSets(TM), false);
// Create Packets.
if (!NoOpt) {
if (!DisableHardwareLoops)
- addPass(createHexagonFixupHwLoops());
- addPass(createHexagonPacketizer());
+ addPass(createHexagonFixupHwLoops(), false);
+ addPass(createHexagonPacketizer(), false);
}
-
- return false;
}
diff --git a/lib/Target/Hexagon/HexagonTargetMachine.h b/lib/Target/Hexagon/HexagonTargetMachine.h
index d88178e052e7..4a9f44732a6b 100644
--- a/lib/Target/Hexagon/HexagonTargetMachine.h
+++ b/lib/Target/Hexagon/HexagonTargetMachine.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef HexagonTARGETMACHINE_H
-#define HexagonTARGETMACHINE_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETMACHINE_H
+#define LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETMACHINE_H
#include "HexagonInstrInfo.h"
#include "HexagonSubtarget.h"
@@ -23,6 +23,7 @@ namespace llvm {
class Module;
class HexagonTargetMachine : public LLVMTargetMachine {
+ std::unique_ptr<TargetLoweringObjectFile> TLOF;
HexagonSubtarget Subtarget;
public:
@@ -30,34 +31,18 @@ public:
StringRef FS, const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL);
+ ~HexagonTargetMachine() override;
- const HexagonInstrInfo *getInstrInfo() const override {
- return getSubtargetImpl()->getInstrInfo();
- }
const HexagonSubtarget *getSubtargetImpl() const override {
return &Subtarget;
}
- const HexagonRegisterInfo *getRegisterInfo() const override {
- return getSubtargetImpl()->getRegisterInfo();
- }
- const InstrItineraryData* getInstrItineraryData() const override {
- return &getSubtargetImpl()->getInstrItineraryData();
- }
- const HexagonTargetLowering* getTargetLowering() const override {
- return getSubtargetImpl()->getTargetLowering();
- }
- const HexagonFrameLowering* getFrameLowering() const override {
- return getSubtargetImpl()->getFrameLowering();
- }
- const HexagonSelectionDAGInfo* getSelectionDAGInfo() const override {
- return getSubtargetImpl()->getSelectionDAGInfo();
- }
- const DataLayout *getDataLayout() const override {
- return getSubtargetImpl()->getDataLayout();
- }
static unsigned getModuleMatchQuality(const Module &M);
TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
+
+ TargetLoweringObjectFile *getObjFileLowering() const override {
+ return TLOF.get();
+ }
};
extern bool flag_aligned_memcpy;
diff --git a/lib/Target/Hexagon/HexagonTargetObjectFile.cpp b/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
index c97526eed210..f4ab5e2b5c42 100644
--- a/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
+++ b/lib/Target/Hexagon/HexagonTargetObjectFile.cpp
@@ -31,7 +31,7 @@ static cl::opt<int> SmallDataThreshold("hexagon-small-data-threshold",
void HexagonTargetObjectFile::Initialize(MCContext &Ctx,
const TargetMachine &TM) {
TargetLoweringObjectFileELF::Initialize(Ctx, TM);
-
+ InitializeELF(TM.Options.UseInitArray);
SmallDataSection =
getContext().getELFSection(".sdata", ELF::SHT_PROGBITS,
@@ -79,7 +79,8 @@ IsGlobalInSmallSection(const GlobalValue *GV, const TargetMachine &TM,
if (Kind.isBSS() || Kind.isDataNoRel() || Kind.isCommon()) {
Type *Ty = GV->getType()->getElementType();
- return IsInSmallSection(TM.getDataLayout()->getTypeAllocSize(Ty));
+ return IsInSmallSection(
+ TM.getSubtargetImpl()->getDataLayout()->getTypeAllocSize(Ty));
}
return false;
diff --git a/lib/Target/Hexagon/HexagonTargetObjectFile.h b/lib/Target/Hexagon/HexagonTargetObjectFile.h
index 1bd1272befcf..c97420427240 100644
--- a/lib/Target/Hexagon/HexagonTargetObjectFile.h
+++ b/lib/Target/Hexagon/HexagonTargetObjectFile.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef HexagonTARGETOBJECTFILE_H
-#define HexagonTARGETOBJECTFILE_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETOBJECTFILE_H
+#define LLVM_LIB_TARGET_HEXAGON_HEXAGONTARGETOBJECTFILE_H
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/MC/MCSectionELF.h"
diff --git a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
index 87ce960a60cf..c9605278e045 100644
--- a/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
+++ b/lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
@@ -118,7 +118,6 @@ namespace {
public:
// Ctor.
HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI,
- MachineDominatorTree &MDT,
const MachineBranchProbabilityInfo *MBPI);
// initPacketizerState - initialize some internal flags.
@@ -146,23 +145,23 @@ namespace {
bool PromoteToDotNew(MachineInstr* MI, SDep::Kind DepType,
MachineBasicBlock::iterator &MII,
const TargetRegisterClass* RC);
- bool CanPromoteToDotNew(MachineInstr* MI, SUnit* PacketSU,
- unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit,
+ bool CanPromoteToDotNew(MachineInstr *MI, SUnit *PacketSU, unsigned DepReg,
+ const std::map<MachineInstr *, SUnit *> &MIToSUnit,
MachineBasicBlock::iterator &MII,
- const TargetRegisterClass* RC);
- bool CanPromoteToNewValue(MachineInstr* MI, SUnit* PacketSU,
- unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit,
- MachineBasicBlock::iterator &MII);
- bool CanPromoteToNewValueStore(MachineInstr* MI, MachineInstr* PacketMI,
- unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit);
- bool DemoteToDotOld(MachineInstr* MI);
- bool ArePredicatesComplements(MachineInstr* MI1, MachineInstr* MI2,
- std::map <MachineInstr*, SUnit*> MIToSUnit);
- bool RestrictingDepExistInPacket(MachineInstr*,
- unsigned, std::map <MachineInstr*, SUnit*>);
+ const TargetRegisterClass *RC);
+ bool
+ CanPromoteToNewValue(MachineInstr *MI, SUnit *PacketSU, unsigned DepReg,
+ const std::map<MachineInstr *, SUnit *> &MIToSUnit,
+ MachineBasicBlock::iterator &MII);
+ bool CanPromoteToNewValueStore(
+ MachineInstr *MI, MachineInstr *PacketMI, unsigned DepReg,
+ const std::map<MachineInstr *, SUnit *> &MIToSUnit);
+ bool DemoteToDotOld(MachineInstr *MI);
+ bool ArePredicatesComplements(
+ MachineInstr *MI1, MachineInstr *MI2,
+ const std::map<MachineInstr *, SUnit *> &MIToSUnit);
+ bool RestrictingDepExistInPacket(MachineInstr *, unsigned,
+ const std::map<MachineInstr *, SUnit *> &);
bool isNewifiable(MachineInstr* MI);
bool isCondInst(MachineInstr* MI);
bool tryAllocateResourcesForConstExt(MachineInstr* MI);
@@ -184,20 +183,19 @@ INITIALIZE_PASS_END(HexagonPacketizer, "packets", "Hexagon Packetizer",
// HexagonPacketizerList Ctor.
HexagonPacketizerList::HexagonPacketizerList(
- MachineFunction &MF, MachineLoopInfo &MLI,MachineDominatorTree &MDT,
- const MachineBranchProbabilityInfo *MBPI)
- : VLIWPacketizerList(MF, MLI, MDT, true){
+ MachineFunction &MF, MachineLoopInfo &MLI,
+ const MachineBranchProbabilityInfo *MBPI)
+ : VLIWPacketizerList(MF, MLI, true) {
this->MBPI = MBPI;
}
bool HexagonPacketizer::runOnMachineFunction(MachineFunction &Fn) {
- const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo();
+ const TargetInstrInfo *TII = Fn.getSubtarget().getInstrInfo();
MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>();
- MachineDominatorTree &MDT = getAnalysis<MachineDominatorTree>();
const MachineBranchProbabilityInfo *MBPI =
&getAnalysis<MachineBranchProbabilityInfo>();
// Instantiate the packetizer.
- HexagonPacketizerList Packetizer(Fn, MLI, MDT, MBPI);
+ HexagonPacketizerList Packetizer(Fn, MLI, MBPI);
// DFA state table should not be empty.
assert(Packetizer.getResourceTracker() && "Empty DFA table!");
@@ -266,7 +264,7 @@ bool HexagonPacketizer::runOnMachineFunction(MachineFunction &Fn) {
static bool IsIndirectCall(MachineInstr* MI) {
- return ((MI->getOpcode() == Hexagon::CALLR) ||
+ return ((MI->getOpcode() == Hexagon::J2_callr) ||
(MI->getOpcode() == Hexagon::CALLRv3));
}
@@ -275,7 +273,7 @@ static bool IsIndirectCall(MachineInstr* MI) {
void HexagonPacketizerList::reserveResourcesForConstExt(MachineInstr* MI) {
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
MachineFunction *MF = MI->getParent()->getParent();
- MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::IMMEXT_i),
+ MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::A4_ext),
MI->getDebugLoc());
if (ResourceTracker->canReserveResources(PseudoMI)) {
@@ -293,7 +291,7 @@ bool HexagonPacketizerList::canReserveResourcesForConstExt(MachineInstr *MI) {
assert((QII->isExtended(MI) || QII->isConstExtended(MI)) &&
"Should only be called for constant extended instructions");
MachineFunction *MF = MI->getParent()->getParent();
- MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::IMMEXT_i),
+ MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::A4_ext),
MI->getDebugLoc());
bool CanReserve = ResourceTracker->canReserveResources(PseudoMI);
MF->DeleteMachineInstr(PseudoMI);
@@ -305,7 +303,7 @@ bool HexagonPacketizerList::canReserveResourcesForConstExt(MachineInstr *MI) {
bool HexagonPacketizerList::tryAllocateResourcesForConstExt(MachineInstr* MI) {
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
MachineFunction *MF = MI->getParent()->getParent();
- MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::IMMEXT_i),
+ MachineInstr *PseudoMI = MF->CreateMachineInstr(QII->get(Hexagon::A4_ext),
MI->getDebugLoc());
if (ResourceTracker->canReserveResources(PseudoMI)) {
@@ -324,8 +322,8 @@ bool HexagonPacketizerList::IsCallDependent(MachineInstr* MI,
unsigned DepReg) {
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
- const HexagonRegisterInfo* QRI =
- (const HexagonRegisterInfo *) TM.getRegisterInfo();
+ const HexagonRegisterInfo *QRI =
+ (const HexagonRegisterInfo *)MF.getSubtarget().getRegisterInfo();
// Check for lr dependence
if (DepReg == QRI->getRARegister()) {
@@ -368,7 +366,7 @@ static bool IsRegDependence(const SDep::Kind DepType) {
}
static bool IsDirectJump(MachineInstr* MI) {
- return (MI->getOpcode() == Hexagon::JMP);
+ return (MI->getOpcode() == Hexagon::J2_jump);
}
static bool IsSchedBarrier(MachineInstr* MI) {
@@ -384,8 +382,8 @@ static bool IsControlFlow(MachineInstr* MI) {
}
static bool IsLoopN(MachineInstr *MI) {
- return (MI->getOpcode() == Hexagon::LOOP0_i ||
- MI->getOpcode() == Hexagon::LOOP0_r);
+ return (MI->getOpcode() == Hexagon::J2_loop0i ||
+ MI->getOpcode() == Hexagon::J2_loop0r);
}
/// DoesModifyCalleeSavedReg - Returns true if the instruction modifies a
@@ -536,9 +534,9 @@ static MachineOperand& GetStoreValueOperand(MachineInstr *MI) {
// if there is a new value store in the packet. Corollary, if there is
// already a store in a packet, there can not be a new value store.
// Arch Spec: 3.4.4.2
-bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI,
- MachineInstr *PacketMI, unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit) {
+bool HexagonPacketizerList::CanPromoteToNewValueStore(
+ MachineInstr *MI, MachineInstr *PacketMI, unsigned DepReg,
+ const std::map<MachineInstr *, SUnit *> &MIToSUnit) {
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
// Make sure we are looking at the store, that can be promoted.
if (!QII->mayBeNewStore(MI))
@@ -549,8 +547,8 @@ bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI,
GetStoreValueOperand(MI).getReg() != DepReg)
return false;
- const HexagonRegisterInfo* QRI =
- (const HexagonRegisterInfo *) TM.getRegisterInfo();
+ const HexagonRegisterInfo *QRI =
+ (const HexagonRegisterInfo *)MF.getSubtarget().getRegisterInfo();
const MCInstrDesc& MCID = PacketMI->getDesc();
// first operand is always the result
@@ -561,12 +559,12 @@ bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI,
for (std::vector<MachineInstr*>::iterator VI = CurrentPacketMIs.begin(),
VE = CurrentPacketMIs.end();
(VI != VE); ++VI) {
- SUnit* PacketSU = MIToSUnit[*VI];
+ SUnit *PacketSU = MIToSUnit.find(*VI)->second;
if (PacketSU->getInstr()->getDesc().mayStore() ||
// if we have mayStore = 1 set on ALLOCFRAME and DEALLOCFRAME,
// then we don't need this
- PacketSU->getInstr()->getOpcode() == Hexagon::ALLOCFRAME ||
- PacketSU->getInstr()->getOpcode() == Hexagon::DEALLOCFRAME)
+ PacketSU->getInstr()->getOpcode() == Hexagon::S2_allocframe ||
+ PacketSU->getInstr()->getOpcode() == Hexagon::L2_deallocframe)
return false;
}
@@ -661,7 +659,7 @@ bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI,
for (VI=CurrentPacketMIs.begin(), VE = CurrentPacketMIs.end();
(VI != VE); ++VI) {
- SUnit* TempSU = MIToSUnit[*VI];
+ SUnit *TempSU = MIToSUnit.find(*VI)->second;
MachineInstr* TempMI = TempSU->getInstr();
// Following condition is true for all the instructions until PacketMI is
@@ -717,15 +715,14 @@ bool HexagonPacketizerList::CanPromoteToNewValueStore( MachineInstr *MI,
// can this MI to promoted to either
// new value store or new value jump
-bool HexagonPacketizerList::CanPromoteToNewValue( MachineInstr *MI,
- SUnit *PacketSU, unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit,
- MachineBasicBlock::iterator &MII)
-{
+bool HexagonPacketizerList::CanPromoteToNewValue(
+ MachineInstr *MI, SUnit *PacketSU, unsigned DepReg,
+ const std::map<MachineInstr *, SUnit *> &MIToSUnit,
+ MachineBasicBlock::iterator &MII) {
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
- const HexagonRegisterInfo* QRI =
- (const HexagonRegisterInfo *) TM.getRegisterInfo();
+ const HexagonRegisterInfo *QRI =
+ (const HexagonRegisterInfo *)MF.getSubtarget().getRegisterInfo();
if (!QRI->Subtarget.hasV4TOps() ||
!QII->mayBeNewStore(MI))
return false;
@@ -746,12 +743,10 @@ bool HexagonPacketizerList::CanPromoteToNewValue( MachineInstr *MI,
// 1. dot new on predicate - V2/V3/V4
// 2. dot new on stores NV/ST - V4
// 3. dot new on jump NV/J - V4 -- This is generated in a pass.
-bool HexagonPacketizerList::CanPromoteToDotNew( MachineInstr *MI,
- SUnit *PacketSU, unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit,
- MachineBasicBlock::iterator &MII,
- const TargetRegisterClass* RC )
-{
+bool HexagonPacketizerList::CanPromoteToDotNew(
+ MachineInstr *MI, SUnit *PacketSU, unsigned DepReg,
+ const std::map<MachineInstr *, SUnit *> &MIToSUnit,
+ MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC) {
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
// Already a dot new instruction.
if (QII->isDotNewInst(MI) && !QII->mayBeNewStore(MI))
@@ -803,12 +798,12 @@ bool HexagonPacketizerList::CanPromoteToDotNew( MachineInstr *MI,
// The P3 from a) and d) will be complements after
// a)'s P3 is converted to .new form
// Anti Dep between c) and b) is irrelevant for this case
-bool HexagonPacketizerList::RestrictingDepExistInPacket (MachineInstr* MI,
- unsigned DepReg,
- std::map <MachineInstr*, SUnit*> MIToSUnit) {
+bool HexagonPacketizerList::RestrictingDepExistInPacket(
+ MachineInstr *MI, unsigned DepReg,
+ const std::map<MachineInstr *, SUnit *> &MIToSUnit) {
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
- SUnit* PacketSUDep = MIToSUnit[MI];
+ SUnit *PacketSUDep = MIToSUnit.find(MI)->second;
for (std::vector<MachineInstr*>::iterator VIN = CurrentPacketMIs.begin(),
VEN = CurrentPacketMIs.end(); (VIN != VEN); ++VIN) {
@@ -817,7 +812,7 @@ bool HexagonPacketizerList::RestrictingDepExistInPacket (MachineInstr* MI,
if(!QII->isPredicated(*VIN)) continue;
// Scheduling Unit for current insn in the packet
- SUnit* PacketSU = MIToSUnit[*VIN];
+ SUnit *PacketSU = MIToSUnit.find(*VIN)->second;
// Look at dependencies between current members of the packet
// and predicate defining instruction MI.
@@ -861,8 +856,9 @@ static unsigned getPredicatedRegister(MachineInstr *MI,
// Given two predicated instructions, this function detects whether
// the predicates are complements
-bool HexagonPacketizerList::ArePredicatesComplements (MachineInstr* MI1,
- MachineInstr* MI2, std::map <MachineInstr*, SUnit*> MIToSUnit) {
+bool HexagonPacketizerList::ArePredicatesComplements(
+ MachineInstr *MI1, MachineInstr *MI2,
+ const std::map<MachineInstr *, SUnit *> &MIToSUnit) {
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
@@ -873,7 +869,7 @@ bool HexagonPacketizerList::ArePredicatesComplements (MachineInstr* MI1,
return false;
// Scheduling unit for candidate
- SUnit* SU = MIToSUnit[MI1];
+ SUnit *SU = MIToSUnit.find(MI1)->second;
// One corner case deals with the following scenario:
// Trying to add
@@ -898,7 +894,7 @@ bool HexagonPacketizerList::ArePredicatesComplements (MachineInstr* MI1,
VEN = CurrentPacketMIs.end(); (VIN != VEN); ++VIN) {
// Scheduling Unit for current insn in the packet
- SUnit* PacketSU = MIToSUnit[*VIN];
+ SUnit *PacketSU = MIToSUnit.find(*VIN)->second;
// If this instruction in the packet is succeeded by the candidate...
if (PacketSU->isSucc(SU)) {
@@ -1007,8 +1003,8 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
MachineBasicBlock::iterator II = I;
const unsigned FrameSize = MF.getFrameInfo()->getStackSize();
- const HexagonRegisterInfo* QRI =
- (const HexagonRegisterInfo *) TM.getRegisterInfo();
+ const HexagonRegisterInfo *QRI =
+ (const HexagonRegisterInfo *)MF.getSubtarget().getRegisterInfo();
const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
// Inline asm cannot go in the packet.
@@ -1103,7 +1099,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
VI = CurrentPacketMIs.begin(),
VE = CurrentPacketMIs.end();
(VI != VE && maintainNewValueJump); ++VI) {
- SUnit* PacketSU = MIToSUnit[*VI];
+ SUnit *PacketSU = MIToSUnit.find(*VI)->second;
// NVJ can not be part of the dual jump - Arch Spec: section 7.8
if (PacketSU->getInstr()->getDesc().isCall()) {
@@ -1119,7 +1115,7 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
// first operand is also a reg), first reg is not defined in
// the same packet.
if (PacketSU->getInstr()->getDesc().mayStore() ||
- PacketSU->getInstr()->getOpcode() == Hexagon::ALLOCFRAME ||
+ PacketSU->getInstr()->getOpcode() == Hexagon::S2_allocframe ||
// Check #2.
(!secondRegMatch && NextMI->getOperand(1).isReg() &&
PacketSU->getInstr()->modifiesRegister(
@@ -1278,15 +1274,15 @@ bool HexagonPacketizerList::isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) {
}
// For V4, special case ALLOCFRAME. Even though there is dependency
- // between ALLOCAFRAME and subsequent store, allow it to be
+ // between ALLOCFRAME and subsequent store, allow it to be
// packetized in a same packet. This implies that the store is using
- // caller's SP. Hense, offset needs to be updated accordingly.
+ // caller's SP. Hence, offset needs to be updated accordingly.
else if (DepType == SDep::Data
&& QRI->Subtarget.hasV4TOps()
- && J->getOpcode() == Hexagon::ALLOCFRAME
- && (I->getOpcode() == Hexagon::STrid
- || I->getOpcode() == Hexagon::STriw
- || I->getOpcode() == Hexagon::STrib)
+ && J->getOpcode() == Hexagon::S2_allocframe
+ && (I->getOpcode() == Hexagon::S2_storerd_io
+ || I->getOpcode() == Hexagon::S2_storeri_io
+ || I->getOpcode() == Hexagon::S2_storerb_io)
&& I->getOperand(0).getReg() == QRI->getStackRegister()
&& QII->isValidOffset(I->getOpcode(),
I->getOperand(1).getImm() -
diff --git a/lib/Target/Hexagon/HexagonVarargsCallingConvention.h b/lib/Target/Hexagon/HexagonVarargsCallingConvention.h
index 668ca98402b2..edbe29a5344a 100644
--- a/lib/Target/Hexagon/HexagonVarargsCallingConvention.h
+++ b/lib/Target/Hexagon/HexagonVarargsCallingConvention.h
@@ -74,10 +74,14 @@ static bool CC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
}
const Type* ArgTy = LocVT.getTypeForEVT(State.getContext());
- unsigned Alignment =
- State.getTarget().getDataLayout()->getABITypeAlignment(ArgTy);
+ unsigned Alignment = State.getTarget()
+ .getSubtargetImpl()
+ ->getDataLayout()
+ ->getABITypeAlignment(ArgTy);
unsigned Size =
- State.getTarget().getDataLayout()->getTypeSizeInBits(ArgTy) / 8;
+ State.getTarget().getSubtargetImpl()->getDataLayout()->getTypeSizeInBits(
+ ArgTy) /
+ 8;
// If it's passed by value, then we need the size of the aggregate not of
// the pointer.
@@ -129,10 +133,14 @@ static bool RetCC_Hexagon32_VarArgs(unsigned ValNo, EVT ValVT,
}
const Type* ArgTy = LocVT.getTypeForEVT(State.getContext());
- unsigned Alignment =
- State.getTarget().getDataLayout()->getABITypeAlignment(ArgTy);
+ unsigned Alignment = State.getTarget()
+ .getSubtargetImpl()
+ ->getDataLayout()
+ ->getABITypeAlignment(ArgTy);
unsigned Size =
- State.getTarget().getDataLayout()->getTypeSizeInBits(ArgTy) / 8;
+ State.getTarget().getSubtargetImpl()->getDataLayout()->getTypeSizeInBits(
+ ArgTy) /
+ 8;
unsigned Offset3 = State.AllocateStack(Size, Alignment);
State.addLoc(CCValAssign::getMem(ValNo, ValVT.getSimpleVT(), Offset3,
diff --git a/lib/Target/Hexagon/InstPrinter/CMakeLists.txt b/lib/Target/Hexagon/InstPrinter/CMakeLists.txt
deleted file mode 100644
index 1ddaf9bac203..000000000000
--- a/lib/Target/Hexagon/InstPrinter/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-add_llvm_library(LLVMHexagonAsmPrinter
- HexagonInstPrinter.cpp
- )
diff --git a/lib/Target/Hexagon/LLVMBuild.txt b/lib/Target/Hexagon/LLVMBuild.txt
index a436b6e0454e..6ffd26a2022a 100644
--- a/lib/Target/Hexagon/LLVMBuild.txt
+++ b/lib/Target/Hexagon/LLVMBuild.txt
@@ -16,7 +16,7 @@
;===------------------------------------------------------------------------===;
[common]
-subdirectories = InstPrinter MCTargetDesc TargetInfo
+subdirectories = Disassembler MCTargetDesc TargetInfo
[component_0]
type = TargetGroup
@@ -28,5 +28,5 @@ has_asmprinter = 1
type = Library
name = HexagonCodeGen
parent = Hexagon
-required_libraries = Analysis AsmPrinter CodeGen Core HexagonAsmPrinter HexagonDesc HexagonInfo MC SelectionDAG Support Target
+required_libraries = Analysis AsmPrinter CodeGen Core HexagonDesc HexagonInfo MC SelectionDAG Support Target
add_to_library_groups = Hexagon
diff --git a/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt b/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt
index eeef3ef8c200..2a6124ee0c5a 100644
--- a/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt
+++ b/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt
@@ -1,5 +1,11 @@
add_llvm_library(LLVMHexagonDesc
+ HexagonAsmBackend.cpp
+ HexagonELFObjectWriter.cpp
+ HexagonInstPrinter.cpp
HexagonMCAsmInfo.cpp
+ HexagonMCCodeEmitter.cpp
HexagonMCInst.cpp
HexagonMCTargetDesc.cpp
)
+
+add_dependencies(LLVMHexagonDesc HexagonCommonTableGen)
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp
new file mode 100644
index 000000000000..bdccf880d65f
--- /dev/null
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp
@@ -0,0 +1,74 @@
+//===-- HexagonAsmBackend.cpp - Hexagon Assembler Backend -----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "HexagonMCTargetDesc.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCELFObjectWriter.h"
+
+using namespace llvm;
+
+namespace {
+
+class HexagonAsmBackend : public MCAsmBackend {
+public:
+ HexagonAsmBackend(Target const & /*T*/) {}
+
+ unsigned getNumFixupKinds() const override { return 0; }
+
+ void applyFixup(MCFixup const & /*Fixup*/, char * /*Data*/,
+ unsigned /*DataSize*/, uint64_t /*Value*/,
+ bool /*IsPCRel*/) const override {
+ return;
+ }
+
+ bool mayNeedRelaxation(MCInst const & /*Inst*/) const override {
+ return false;
+ }
+
+ bool fixupNeedsRelaxation(MCFixup const & /*Fixup*/, uint64_t /*Value*/,
+ MCRelaxableFragment const * /*DF*/,
+ MCAsmLayout const & /*Layout*/) const override {
+ llvm_unreachable("fixupNeedsRelaxation() unimplemented");
+ }
+
+ void relaxInstruction(MCInst const & /*Inst*/,
+ MCInst & /*Res*/) const override {
+ llvm_unreachable("relaxInstruction() unimplemented");
+ }
+
+ bool writeNopData(uint64_t /*Count*/,
+ MCObjectWriter * /*OW*/) const override {
+ return true;
+ }
+};
+} // end anonymous namespace
+
+namespace {
+class ELFHexagonAsmBackend : public HexagonAsmBackend {
+ uint8_t OSABI;
+
+public:
+ ELFHexagonAsmBackend(Target const &T, uint8_t OSABI)
+ : HexagonAsmBackend(T), OSABI(OSABI) {}
+
+ MCObjectWriter *createObjectWriter(raw_ostream &OS) const override {
+ StringRef CPU("HexagonV4");
+ return createHexagonELFObjectWriter(OS, OSABI, CPU);
+ }
+};
+} // end anonymous namespace
+
+namespace llvm {
+MCAsmBackend *createHexagonAsmBackend(Target const &T,
+ MCRegisterInfo const & /*MRI*/,
+ StringRef TT, StringRef /*CPU*/) {
+ uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(Triple(TT).getOS());
+ return new ELFHexagonAsmBackend(T, OSABI);
+}
+}
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h b/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
index f8be77cd3af5..8e02f799d7e4 100644
--- a/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
@@ -14,11 +14,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef HEXAGONBASEINFO_H
-#define HEXAGONBASEINFO_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONBASEINFO_H
+#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONBASEINFO_H
#include "HexagonMCTargetDesc.h"
#include "llvm/Support/ErrorHandling.h"
+#include <stdint.h>
namespace llvm {
@@ -189,6 +190,15 @@ namespace HexagonII {
MO_GPREL
};
+ enum class InstParseBits : uint32_t {
+ INST_PARSE_MASK = 0x0000c000,
+ INST_PARSE_PACKET_END = 0x0000c000,
+ INST_PARSE_LOOP_END = 0x00008000,
+ INST_PARSE_NOT_END = 0x00004000,
+ INST_PARSE_DUPLEX = 0x00000000,
+ INST_PARSE_EXTENDER = 0x00000000
+ };
+
} // End namespace HexagonII.
} // End namespace llvm.
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp
new file mode 100644
index 000000000000..56c9dc712a6e
--- /dev/null
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp
@@ -0,0 +1,62 @@
+//===-- HexagonELFObjectWriter.cpp - Hexagon Target Descriptions ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Hexagon.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCELFObjectWriter.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "hexagon-elf-writer"
+
+using namespace llvm;
+using namespace Hexagon;
+
+namespace {
+
+class HexagonELFObjectWriter : public MCELFObjectTargetWriter {
+private:
+ StringRef CPU;
+
+public:
+ HexagonELFObjectWriter(uint8_t OSABI, StringRef C);
+
+ virtual unsigned GetRelocType(MCValue const &Target, MCFixup const &Fixup,
+ bool IsPCRel) const override;
+};
+}
+
+HexagonELFObjectWriter::HexagonELFObjectWriter(uint8_t OSABI, StringRef C)
+ : MCELFObjectTargetWriter(/*Is64bit*/ false, OSABI, ELF::EM_HEXAGON,
+ /*HasRelocationAddend*/ true),
+ CPU(C) {}
+
+unsigned HexagonELFObjectWriter::GetRelocType(MCValue const &/*Target*/,
+ MCFixup const &Fixup,
+ bool IsPCRel) const {
+ unsigned Type = (unsigned)ELF::R_HEX_NONE;
+ llvm::MCFixupKind Kind = Fixup.getKind();
+
+ switch (Kind) {
+ default:
+ DEBUG(dbgs() << "unrecognized relocation " << Fixup.getKind() << "\n");
+ llvm_unreachable("Unimplemented Fixup kind!");
+ break;
+ case FK_Data_4:
+ Type = (IsPCRel) ? ELF::R_HEX_32_PCREL : ELF::R_HEX_32;
+ break;
+ }
+ return Type;
+}
+
+MCObjectWriter *llvm::createHexagonELFObjectWriter(raw_ostream &OS,
+ uint8_t OSABI,
+ StringRef CPU) {
+ MCELFObjectTargetWriter *MOTW = new HexagonELFObjectWriter(OSABI, CPU);
+ return createELFObjectWriter(MOTW, OS, /*IsLittleEndian*/ true);
+} \ No newline at end of file
diff --git a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp
index 9942a6067d19..5c6f0363f78a 100644
--- a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.cpp
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp
@@ -29,6 +29,45 @@ using namespace llvm;
#include "HexagonGenAsmWriter.inc"
const char HexagonInstPrinter::PacketPadding = '\t';
+// Return the minimum value that a constant extendable operand can have
+// without being extended.
+static int getMinValue(uint64_t TSFlags) {
+ unsigned isSigned =
+ (TSFlags >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
+ unsigned bits =
+ (TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
+
+ if (isSigned)
+ return -1U << (bits - 1);
+
+ return 0;
+}
+
+// Return the maximum value that a constant extendable operand can have
+// without being extended.
+static int getMaxValue(uint64_t TSFlags) {
+ unsigned isSigned =
+ (TSFlags >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
+ unsigned bits =
+ (TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
+
+ if (isSigned)
+ return ~(-1U << (bits - 1));
+
+ return ~(-1U << bits);
+}
+
+// Return true if the instruction must be extended.
+static bool isExtended(uint64_t TSFlags) {
+ return (TSFlags >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
+}
+
+// Currently just used in an assert statement
+static bool isExtendable(uint64_t TSFlags) LLVM_ATTRIBUTE_UNUSED;
+// Return true if the instruction may be extended based on the operand value.
+static bool isExtendable(uint64_t TSFlags) {
+ return (TSFlags >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;
+}
StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const {
return MII.getName(Opcode);
@@ -52,14 +91,14 @@ void HexagonInstPrinter::printInst(const HexagonMCInst *MI, raw_ostream &O,
// Ending a harware loop is different from ending an regular packet.
assert(MI->isPacketEnd() && "Loop-end must also end the packet");
- if (MI->isPacketStart()) {
+ if (MI->isPacketBegin()) {
// There must be a packet to end a loop.
// FIXME: when shuffling is always run, this shouldn't be needed.
HexagonMCInst Nop;
StringRef NoAnnot;
- Nop.setOpcode (Hexagon::NOP);
- Nop.setPacketStart (MI->isPacketStart());
+ Nop.setOpcode (Hexagon::A2_nop);
+ Nop.setPacketBegin (MI->isPacketBegin());
printInst (&Nop, O, NoAnnot);
}
@@ -71,7 +110,7 @@ void HexagonInstPrinter::printInst(const HexagonMCInst *MI, raw_ostream &O,
}
else {
// Prefix the insn opening the packet.
- if (MI->isPacketStart())
+ if (MI->isPacketBegin())
O << PacketPadding << startPacket << '\n';
printInstruction(MI, O);
@@ -116,9 +155,20 @@ void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo,
void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) const {
- const HexagonMCInst *HMCI = static_cast<const HexagonMCInst*>(MI);
- if (HMCI->isConstExtended())
+ const MCOperand &MO = MI->getOperand(OpNo);
+ const MCInstrDesc &MII = getMII().get(MI->getOpcode());
+
+ assert((isExtendable(MII.TSFlags) || isExtended(MII.TSFlags)) &&
+ "Expecting an extendable operand");
+
+ if (MO.isExpr() || isExtended(MII.TSFlags)) {
O << "#";
+ } else if (MO.isImm()) {
+ int ImmValue = MO.getImm();
+ if (ImmValue < getMinValue(MII.TSFlags) ||
+ ImmValue > getMaxValue(MII.TSFlags))
+ O << "#";
+ }
printOperand(MI, OpNo, O);
}
diff --git a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h b/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h
index 09e3f88434ed..55ae95cd06df 100644
--- a/lib/Target/Hexagon/InstPrinter/HexagonInstPrinter.h
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef HEXAGONINSTPRINTER_H
-#define HEXAGONINSTPRINTER_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_INSTPRINTER_HEXAGONINSTPRINTER_H
+#define LLVM_LIB_TARGET_HEXAGON_INSTPRINTER_HEXAGONINSTPRINTER_H
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
index 141e514ce412..ad5e0fb15e7f 100644
--- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.cpp
@@ -24,7 +24,6 @@ HexagonMCAsmInfo::HexagonMCAsmInfo(StringRef TT) {
Data64bitsDirective = nullptr; // .xword is only supported by V9.
ZeroDirective = "\t.skip\t";
CommentString = "//";
- HasLEB128 = true;
LCOMMDirectiveAlignmentType = LCOMM::ByteAlignment;
InlineAsmStart = "# InlineAsm Start";
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h
index 953d804b49ab..ab18f0b37ba6 100644
--- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCAsmInfo.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef HexagonMCASMINFO_H
-#define HexagonMCASMINFO_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCASMINFO_H
+#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCASMINFO_H
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCAsmInfoELF.h"
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
new file mode 100644
index 000000000000..487872a1f5dd
--- /dev/null
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
@@ -0,0 +1,88 @@
+//===-- HexagonMCCodeEmitter.cpp - Hexagon Target Descriptions ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Hexagon.h"
+#include "MCTargetDesc/HexagonBaseInfo.h"
+#include "MCTargetDesc/HexagonMCCodeEmitter.h"
+#include "MCTargetDesc/HexagonMCInst.h"
+#include "MCTargetDesc/HexagonMCTargetDesc.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+#define DEBUG_TYPE "mccodeemitter"
+
+using namespace llvm;
+using namespace Hexagon;
+
+STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
+
+namespace {
+/// \brief 10.6 Instruction Packets
+/// Possible values for instruction packet parse field.
+enum class ParseField { duplex = 0x0, last0 = 0x1, last1 = 0x2, end = 0x3 };
+/// \brief Returns the packet bits based on instruction position.
+uint32_t getPacketBits(HexagonMCInst const &HMI) {
+ unsigned const ParseFieldOffset = 14;
+ ParseField Field = HMI.isPacketEnd() ? ParseField::end : ParseField::last0;
+ return static_cast <uint32_t> (Field) << ParseFieldOffset;
+}
+void emitLittleEndian(uint64_t Binary, raw_ostream &OS) {
+ OS << static_cast<uint8_t>((Binary >> 0x00) & 0xff);
+ OS << static_cast<uint8_t>((Binary >> 0x08) & 0xff);
+ OS << static_cast<uint8_t>((Binary >> 0x10) & 0xff);
+ OS << static_cast<uint8_t>((Binary >> 0x18) & 0xff);
+}
+}
+
+HexagonMCCodeEmitter::HexagonMCCodeEmitter(MCInstrInfo const &aMII,
+ MCSubtargetInfo const &aMST,
+ MCContext &aMCT)
+ : MST(aMST), MCT(aMCT) {}
+
+void HexagonMCCodeEmitter::EncodeInstruction(MCInst const &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ MCSubtargetInfo const &STI) const {
+ HexagonMCInst const &HMB = static_cast<HexagonMCInst const &>(MI);
+ uint64_t Binary = getBinaryCodeForInstr(HMB, Fixups, STI) | getPacketBits(HMB);
+ assert(HMB.getDesc().getSize() == 4 && "All instructions should be 32bit");
+ emitLittleEndian(Binary, OS);
+ ++MCNumEmitted;
+}
+
+unsigned
+HexagonMCCodeEmitter::getMachineOpValue(MCInst const &MI, MCOperand const &MO,
+ SmallVectorImpl<MCFixup> &Fixups,
+ MCSubtargetInfo const &STI) const {
+ if (MO.isReg())
+ return MCT.getRegisterInfo()->getEncodingValue(MO.getReg());
+ if (MO.isImm())
+ return static_cast<unsigned>(MO.getImm());
+ llvm_unreachable("Only Immediates and Registers implemented right now");
+}
+
+MCSubtargetInfo const &HexagonMCCodeEmitter::getSubtargetInfo() const {
+ return MST;
+}
+
+MCCodeEmitter *llvm::createHexagonMCCodeEmitter(MCInstrInfo const &MII,
+ MCRegisterInfo const &MRI,
+ MCSubtargetInfo const &MST,
+ MCContext &MCT) {
+ return new HexagonMCCodeEmitter(MII, MST, MCT);
+}
+
+#include "HexagonGenMCCodeEmitter.inc"
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h
new file mode 100644
index 000000000000..96048adf34b7
--- /dev/null
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h
@@ -0,0 +1,60 @@
+//===-- HexagonMCCodeEmitter.h - Hexagon Target Descriptions ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Definition for classes that emit Hexagon machine code from MCInsts
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef HEXAGONMCCODEEMITTER_H
+#define HEXAGONMCCODEEMITTER_H
+
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+class HexagonMCCodeEmitter : public MCCodeEmitter {
+ MCSubtargetInfo const &MST;
+ MCContext &MCT;
+
+public:
+ HexagonMCCodeEmitter(MCInstrInfo const &aMII, MCSubtargetInfo const &aMST,
+ MCContext &aMCT);
+
+ MCSubtargetInfo const &getSubtargetInfo() const;
+
+ void EncodeInstruction(MCInst const &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups,
+ MCSubtargetInfo const &STI) const override;
+
+ // \brief TableGen'erated function for getting the
+ // binary encoding for an instruction.
+ uint64_t getBinaryCodeForInstr(MCInst const &MI,
+ SmallVectorImpl<MCFixup> &Fixups,
+ MCSubtargetInfo const &STI) const;
+
+ /// \brief Return binary encoding of operand.
+ unsigned getMachineOpValue(MCInst const &MI, MCOperand const &MO,
+ SmallVectorImpl<MCFixup> &Fixups,
+ MCSubtargetInfo const &STI) const;
+
+private:
+ HexagonMCCodeEmitter(HexagonMCCodeEmitter const &) LLVM_DELETED_FUNCTION;
+ void operator=(HexagonMCCodeEmitter const &) LLVM_DELETED_FUNCTION;
+}; // class HexagonMCCodeEmitter
+
+} // namespace llvm
+
+#endif /* HEXAGONMCCODEEMITTER_H */
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp
index 9260b4a27661..d8b9a2567eeb 100644
--- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.cpp
@@ -18,27 +18,77 @@
using namespace llvm;
+std::unique_ptr <MCInstrInfo const> HexagonMCInst::MCII;
+
+HexagonMCInst::HexagonMCInst() : MCInst() {}
+HexagonMCInst::HexagonMCInst(MCInstrDesc const &mcid) : MCInst() {}
+
+void HexagonMCInst::AppendImplicitOperands(MCInst &MCI) {
+ MCI.addOperand(MCOperand::CreateImm(0));
+ MCI.addOperand(MCOperand::CreateInst(nullptr));
+}
+
+std::bitset<16> HexagonMCInst::GetImplicitBits(MCInst const &MCI) {
+ SanityCheckImplicitOperands(MCI);
+ std::bitset<16> Bits(MCI.getOperand(MCI.getNumOperands() - 2).getImm());
+ return Bits;
+}
+
+void HexagonMCInst::SetImplicitBits(MCInst &MCI, std::bitset<16> Bits) {
+ SanityCheckImplicitOperands(MCI);
+ MCI.getOperand(MCI.getNumOperands() - 2).setImm(Bits.to_ulong());
+}
+
+void HexagonMCInst::setPacketBegin(bool f) {
+ std::bitset<16> Bits(GetImplicitBits(*this));
+ Bits.set(packetBeginIndex, f);
+ SetImplicitBits(*this, Bits);
+}
+
+bool HexagonMCInst::isPacketBegin() const {
+ std::bitset<16> Bits(GetImplicitBits(*this));
+ return Bits.test(packetBeginIndex);
+}
+
+void HexagonMCInst::setPacketEnd(bool f) {
+ std::bitset<16> Bits(GetImplicitBits(*this));
+ Bits.set(packetEndIndex, f);
+ SetImplicitBits(*this, Bits);
+}
+
+bool HexagonMCInst::isPacketEnd() const {
+ std::bitset<16> Bits(GetImplicitBits(*this));
+ return Bits.test(packetEndIndex);
+}
+
+void HexagonMCInst::resetPacket() {
+ setPacketBegin(false);
+ setPacketEnd(false);
+}
+
// Return the slots used by the insn.
-unsigned HexagonMCInst::getUnits(const HexagonTargetMachine* TM) const {
- const HexagonInstrInfo* QII = TM->getInstrInfo();
- const InstrItineraryData* II = TM->getInstrItineraryData();
- const InstrStage*
- IS = II->beginStage(QII->get(this->getOpcode()).getSchedClass());
+unsigned HexagonMCInst::getUnits(const HexagonTargetMachine *TM) const {
+ const HexagonInstrInfo *QII = TM->getSubtargetImpl()->getInstrInfo();
+ const InstrItineraryData *II =
+ TM->getSubtargetImpl()->getInstrItineraryData();
+ const InstrStage *IS =
+ II->beginStage(QII->get(this->getOpcode()).getSchedClass());
return (IS->getUnits());
}
+MCInstrDesc const& HexagonMCInst::getDesc() const { return (MCII->get(getOpcode())); }
+
// Return the Hexagon ISA class for the insn.
unsigned HexagonMCInst::getType() const {
- const uint64_t F = MCID->TSFlags;
+ const uint64_t F = getDesc().TSFlags;
return ((F >> HexagonII::TypePos) & HexagonII::TypeMask);
}
// Return whether the insn is an actual insn.
bool HexagonMCInst::isCanon() const {
- return (!MCID->isPseudo() &&
- !isPrefix() &&
+ return (!getDesc().isPseudo() && !isPrefix() &&
getType() != HexagonII::TypeENDLOOP);
}
@@ -49,30 +99,30 @@ bool HexagonMCInst::isPrefix() const {
// Return whether the insn is solo, i.e., cannot be in a packet.
bool HexagonMCInst::isSolo() const {
- const uint64_t F = MCID->TSFlags;
+ const uint64_t F = getDesc().TSFlags;
return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask);
}
// Return whether the insn is a new-value consumer.
bool HexagonMCInst::isNewValue() const {
- const uint64_t F = MCID->TSFlags;
+ const uint64_t F = getDesc().TSFlags;
return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask);
}
// Return whether the instruction is a legal new-value producer.
bool HexagonMCInst::hasNewValue() const {
- const uint64_t F = MCID->TSFlags;
+ const uint64_t F = getDesc().TSFlags;
return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask);
}
// Return the operand that consumes or produces a new value.
-const MCOperand& HexagonMCInst::getNewValue() const {
- const uint64_t F = MCID->TSFlags;
- const unsigned O = (F >> HexagonII::NewValueOpPos) &
- HexagonII::NewValueOpMask;
- const MCOperand& MCO = getOperand(O);
+const MCOperand &HexagonMCInst::getNewValue() const {
+ const uint64_t F = getDesc().TSFlags;
+ const unsigned O =
+ (F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask;
+ const MCOperand &MCO = getOperand(O);
- assert ((isNewValue() || hasNewValue()) && MCO.isReg());
+ assert((isNewValue() || hasNewValue()) && MCO.isReg());
return (MCO);
}
@@ -92,9 +142,9 @@ bool HexagonMCInst::isConstExtended(void) const {
return false;
short ExtOpNum = getCExtOpNum();
- int MinValue = getMinValue();
- int MaxValue = getMaxValue();
- const MCOperand& MO = getOperand(ExtOpNum);
+ int MinValue = getMinValue();
+ int MaxValue = getMaxValue();
+ const MCOperand &MO = getOperand(ExtOpNum);
// We could be using an instruction with an extendable immediate and shoehorn
// a global address into it. If it is a global address it will be constant
@@ -115,46 +165,45 @@ bool HexagonMCInst::isConstExtended(void) const {
// Return whether the instruction must be always extended.
bool HexagonMCInst::isExtended(void) const {
- const uint64_t F = MCID->TSFlags;
+ const uint64_t F = getDesc().TSFlags;
return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
}
// Return true if the instruction may be extended based on the operand value.
bool HexagonMCInst::isExtendable(void) const {
- const uint64_t F = MCID->TSFlags;
+ const uint64_t F = getDesc().TSFlags;
return (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;
}
// Return number of bits in the constant extended operand.
unsigned HexagonMCInst::getBitCount(void) const {
- const uint64_t F = MCID->TSFlags;
+ const uint64_t F = getDesc().TSFlags;
return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask);
}
// Return constant extended operand number.
unsigned short HexagonMCInst::getCExtOpNum(void) const {
- const uint64_t F = MCID->TSFlags;
+ const uint64_t F = getDesc().TSFlags;
return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask);
}
// Return whether the operand can be constant extended.
bool HexagonMCInst::isOperandExtended(const unsigned short OperandNum) const {
- const uint64_t F = MCID->TSFlags;
- return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask)
- == OperandNum;
+ const uint64_t F = getDesc().TSFlags;
+ return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask) ==
+ OperandNum;
}
// Return the min value that a constant extendable operand can have
// without being extended.
int HexagonMCInst::getMinValue(void) const {
- const uint64_t F = MCID->TSFlags;
- unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
- & HexagonII::ExtentSignedMask;
- unsigned bits = (F >> HexagonII::ExtentBitsPos)
- & HexagonII::ExtentBitsMask;
+ const uint64_t F = getDesc().TSFlags;
+ unsigned isSigned =
+ (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
+ unsigned bits = (F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
if (isSigned) // if value is signed
- return -1 << (bits - 1);
+ return -1U << (bits - 1);
else
return 0;
}
@@ -162,14 +211,13 @@ int HexagonMCInst::getMinValue(void) const {
// Return the max value that a constant extendable operand can have
// without being extended.
int HexagonMCInst::getMaxValue(void) const {
- const uint64_t F = MCID->TSFlags;
- unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
- & HexagonII::ExtentSignedMask;
- unsigned bits = (F >> HexagonII::ExtentBitsPos)
- & HexagonII::ExtentBitsMask;
+ const uint64_t F = getDesc().TSFlags;
+ unsigned isSigned =
+ (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
+ unsigned bits = (F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
if (isSigned) // if value is signed
- return ~(-1 << (bits - 1));
+ return ~(-1U << (bits - 1));
else
- return ~(-1 << bits);
+ return ~(-1U << bits);
}
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h
index 3c52d4563f8c..ce9a8db5ac44 100644
--- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInst.h
@@ -11,90 +11,98 @@
//
//===----------------------------------------------------------------------===//
-#ifndef HEXAGONMCINST_H
-#define HEXAGONMCINST_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINST_H
+#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINST_H
#include "HexagonTargetMachine.h"
#include "llvm/MC/MCInst.h"
+#include <memory>
+extern "C" void LLVMInitializeHexagonTargetMC();
namespace llvm {
- class MCOperand;
+class MCOperand;
- class HexagonMCInst: public MCInst {
- // MCID is set during instruction lowering.
- // It is needed in order to access TSFlags for
- // use in checking MC instruction properties.
- const MCInstrDesc *MCID;
+class HexagonMCInst : public MCInst {
+ friend void ::LLVMInitializeHexagonTargetMC();
+ // Used to access TSFlags
+ static std::unique_ptr <MCInstrInfo const> MCII;
- // Packet start and end markers
- unsigned packetStart: 1, packetEnd: 1;
+public:
+ explicit HexagonMCInst();
+ HexagonMCInst(const MCInstrDesc &mcid);
- public:
- explicit HexagonMCInst():
- MCInst(), MCID(nullptr), packetStart(0), packetEnd(0) {};
- HexagonMCInst(const MCInstrDesc& mcid):
- MCInst(), MCID(&mcid), packetStart(0), packetEnd(0) {};
+ static void AppendImplicitOperands(MCInst &MCI);
+ static std::bitset<16> GetImplicitBits(MCInst const &MCI);
+ static void SetImplicitBits(MCInst &MCI, std::bitset<16> Bits);
+ static void SanityCheckImplicitOperands(MCInst const &MCI) {
+ assert(MCI.getNumOperands() >= 2 && "At least the two implicit operands");
+ assert(MCI.getOperand(MCI.getNumOperands() - 1).isInst() &&
+ "Implicit bits and flags");
+ assert(MCI.getOperand(MCI.getNumOperands() - 2).isImm() &&
+ "Parent pointer");
+ }
- bool isPacketStart() const { return (packetStart); };
- bool isPacketEnd() const { return (packetEnd); };
- void setPacketStart(bool Y) { packetStart = Y; };
- void setPacketEnd(bool Y) { packetEnd = Y; };
- void resetPacket() { setPacketStart(false); setPacketEnd(false); };
+ void setPacketBegin(bool Y);
+ bool isPacketBegin() const;
+ static const size_t packetBeginIndex = 0;
+ void setPacketEnd(bool Y);
+ bool isPacketEnd() const;
+ static const size_t packetEndIndex = 1;
+ void resetPacket();
- // Return the slots used by the insn.
- unsigned getUnits(const HexagonTargetMachine* TM) const;
+ // Return the slots used by the insn.
+ unsigned getUnits(const HexagonTargetMachine *TM) const;
- // Return the Hexagon ISA class for the insn.
- unsigned getType() const;
+ // Return the Hexagon ISA class for the insn.
+ unsigned getType() const;
- void setDesc(const MCInstrDesc& mcid) { MCID = &mcid; };
- const MCInstrDesc& getDesc(void) const { return *MCID; };
+ MCInstrDesc const &getDesc() const;
- // Return whether the insn is an actual insn.
- bool isCanon() const;
+ // Return whether the insn is an actual insn.
+ bool isCanon() const;
- // Return whether the insn is a prefix.
- bool isPrefix() const;
+ // Return whether the insn is a prefix.
+ bool isPrefix() const;
- // Return whether the insn is solo, i.e., cannot be in a packet.
- bool isSolo() const;
+ // Return whether the insn is solo, i.e., cannot be in a packet.
+ bool isSolo() const;
- // Return whether the instruction needs to be constant extended.
- bool isConstExtended() const;
+ // Return whether the instruction needs to be constant extended.
+ bool isConstExtended() const;
- // Return constant extended operand number.
- unsigned short getCExtOpNum(void) const;
+ // Return constant extended operand number.
+ unsigned short getCExtOpNum(void) const;
- // Return whether the insn is a new-value consumer.
- bool isNewValue() const;
+ // Return whether the insn is a new-value consumer.
+ bool isNewValue() const;
- // Return whether the instruction is a legal new-value producer.
- bool hasNewValue() const;
+ // Return whether the instruction is a legal new-value producer.
+ bool hasNewValue() const;
- // Return the operand that consumes or produces a new value.
- const MCOperand& getNewValue() const;
+ // Return the operand that consumes or produces a new value.
+ const MCOperand &getNewValue() const;
- // Return number of bits in the constant extended operand.
- unsigned getBitCount(void) const;
+ // Return number of bits in the constant extended operand.
+ unsigned getBitCount(void) const;
- private:
- // Return whether the instruction must be always extended.
- bool isExtended() const;
+private:
+ // Return whether the instruction must be always extended.
+ bool isExtended() const;
- // Return true if the insn may be extended based on the operand value.
- bool isExtendable() const;
+ // Return true if the insn may be extended based on the operand value.
+ bool isExtendable() const;
- // Return true if the operand can be constant extended.
- bool isOperandExtended(const unsigned short OperandNum) const;
+ // Return true if the operand can be constant extended.
+ bool isOperandExtended(const unsigned short OperandNum) const;
- // Return the min value that a constant extendable operand can have
- // without being extended.
- int getMinValue() const;
+ // Return the min value that a constant extendable operand can have
+ // without being extended.
+ int getMinValue() const;
- // Return the max value that a constant extendable operand can have
- // without being extended.
- int getMaxValue() const;
- };
+ // Return the max value that a constant extendable operand can have
+ // without being extended.
+ int getMaxValue() const;
+};
}
#endif
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
index 581674dd6cb2..ae5a22bdb01b 100644
--- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
@@ -13,8 +13,10 @@
#include "HexagonMCTargetDesc.h"
#include "HexagonMCAsmInfo.h"
-#include "InstPrinter/HexagonInstPrinter.h"
+#include "MCTargetDesc/HexagonInstPrinter.h"
+#include "MCTargetDesc/HexagonMCInst.h"
#include "llvm/MC/MCCodeGenInfo.h"
+#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
@@ -46,9 +48,17 @@ static MCRegisterInfo *createHexagonMCRegisterInfo(StringRef TT) {
return X;
}
-static MCSubtargetInfo *createHexagonMCSubtargetInfo(StringRef TT,
- StringRef CPU,
- StringRef FS) {
+static MCStreamer *
+createHexagonELFStreamer(MCContext &Context, MCAsmBackend &MAB,
+ raw_ostream &OS, MCCodeEmitter *CE,
+ bool RelaxAll) {
+ MCELFStreamer *ES = new MCELFStreamer(Context, MAB, OS, CE);
+ return ES;
+}
+
+
+static MCSubtargetInfo *
+createHexagonMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS) {
MCSubtargetInfo *X = new MCSubtargetInfo();
InitHexagonMCSubtargetInfo(X, TT, CPU, FS);
return X;
@@ -59,22 +69,40 @@ static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI,
MCAsmInfo *MAI = new HexagonMCAsmInfo(TT);
// VirtualFP = (R30 + #0).
- MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(
- nullptr, Hexagon::R30, 0);
+ MCCFIInstruction Inst =
+ MCCFIInstruction::createDefCfa(nullptr, Hexagon::R30, 0);
MAI->addInitialFrameState(Inst);
return MAI;
}
+static MCStreamer *createMCStreamer(Target const &T, StringRef TT,
+ MCContext &Context, MCAsmBackend &MAB,
+ raw_ostream &OS, MCCodeEmitter *Emitter,
+ MCSubtargetInfo const &STI, bool RelaxAll) {
+ MCStreamer *ES = createHexagonELFStreamer(Context, MAB, OS, Emitter, RelaxAll);
+ new MCTargetStreamer(*ES);
+ return ES;
+}
+
+
static MCCodeGenInfo *createHexagonMCCodeGenInfo(StringRef TT, Reloc::Model RM,
- CodeModel::Model CM,
- CodeGenOpt::Level OL) {
+ CodeModel::Model CM,
+ CodeGenOpt::Level OL) {
MCCodeGenInfo *X = new MCCodeGenInfo();
// For the time being, use static relocations, since there's really no
// support for PIC yet.
X->InitMCCodeGenInfo(Reloc::Static, CM, OL);
return X;
}
+static MCInstPrinter *createHexagonMCInstPrinter(const Target &T,
+ unsigned SyntaxVariant,
+ const MCAsmInfo &MAI,
+ const MCInstrInfo &MII,
+ const MCRegisterInfo &MRI,
+ const MCSubtargetInfo &STI) {
+ return new HexagonInstPrinter(MAI, MII, MRI);
+}
// Force static initialization.
extern "C" void LLVMInitializeHexagonTargetMC() {
@@ -86,7 +114,9 @@ extern "C" void LLVMInitializeHexagonTargetMC() {
createHexagonMCCodeGenInfo);
// Register the MC instruction info.
- TargetRegistry::RegisterMCInstrInfo(TheHexagonTarget, createHexagonMCInstrInfo);
+ TargetRegistry::RegisterMCInstrInfo(TheHexagonTarget,
+ createHexagonMCInstrInfo);
+ HexagonMCInst::MCII.reset (createHexagonMCInstrInfo());
// Register the MC register info.
TargetRegistry::RegisterMCRegInfo(TheHexagonTarget,
@@ -95,4 +125,19 @@ extern "C" void LLVMInitializeHexagonTargetMC() {
// Register the MC subtarget info.
TargetRegistry::RegisterMCSubtargetInfo(TheHexagonTarget,
createHexagonMCSubtargetInfo);
+
+ // Register the MC Code Emitter
+ TargetRegistry::RegisterMCCodeEmitter(TheHexagonTarget,
+ createHexagonMCCodeEmitter);
+
+ // Register the MC Inst Printer
+ TargetRegistry::RegisterMCInstPrinter(TheHexagonTarget,
+ createHexagonMCInstPrinter);
+
+ // Register the asm backend
+ TargetRegistry::RegisterMCAsmBackend(TheHexagonTarget,
+ createHexagonAsmBackend);
+
+ // Register the obj streamer
+ TargetRegistry::RegisterMCObjectStreamer(TheHexagonTarget, createMCStreamer);
}
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h
index 2238b1ae5f35..02fd5161d24a 100644
--- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h
+++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h
@@ -11,15 +11,37 @@
//
//===----------------------------------------------------------------------===//
-#ifndef HEXAGONMCTARGETDESC_H
-#define HEXAGONMCTARGETDESC_H
+#ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCTARGETDESC_H
+#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCTARGETDESC_H
+
+#include <cstdint>
namespace llvm {
+class MCAsmBackend;
+class MCCodeEmitter;
+class MCContext;
+class MCInstrInfo;
+class MCObjectWriter;
+class MCRegisterInfo;
class MCSubtargetInfo;
class Target;
+class StringRef;
+class raw_ostream;
extern Target TheHexagonTarget;
+MCCodeEmitter *createHexagonMCCodeEmitter(MCInstrInfo const &MCII,
+ MCRegisterInfo const &MRI,
+ MCSubtargetInfo const &MST,
+ MCContext &MCT);
+
+MCAsmBackend *createHexagonAsmBackend(Target const &T,
+ MCRegisterInfo const &MRI, StringRef TT,
+ StringRef CPU);
+
+MCObjectWriter *createHexagonELFObjectWriter(raw_ostream &OS, uint8_t OSABI,
+ StringRef CPU);
+
} // End llvm namespace
// Define symbolic names for Hexagon registers. This defines a mapping from
diff --git a/lib/Target/Hexagon/MCTargetDesc/LLVMBuild.txt b/lib/Target/Hexagon/MCTargetDesc/LLVMBuild.txt
index 73c7e016f939..f559a21e3f9e 100644
--- a/lib/Target/Hexagon/MCTargetDesc/LLVMBuild.txt
+++ b/lib/Target/Hexagon/MCTargetDesc/LLVMBuild.txt
@@ -19,5 +19,5 @@
type = Library
name = HexagonDesc
parent = Hexagon
-required_libraries = HexagonInfo MC
+required_libraries = HexagonInfo MC Support
add_to_library_groups = Hexagon
diff --git a/lib/Target/Hexagon/Makefile b/lib/Target/Hexagon/Makefile
index dc387c549a1d..329c9d3018f0 100644
--- a/lib/Target/Hexagon/Makefile
+++ b/lib/Target/Hexagon/Makefile
@@ -14,10 +14,12 @@ TARGET = Hexagon
BUILT_SOURCES = HexagonGenRegisterInfo.inc \
HexagonGenInstrInfo.inc \
HexagonGenAsmWriter.inc \
- HexagonGenDAGISel.inc HexagonGenSubtargetInfo.inc \
- HexagonGenCallingConv.inc \
- HexagonGenDFAPacketizer.inc
-
-DIRS = InstPrinter TargetInfo MCTargetDesc
-
-include $(LEVEL)/Makefile.common
+ HexagonGenDAGISel.inc HexagonGenSubtargetInfo.inc \
+ HexagonGenCallingConv.inc \
+ HexagonGenDFAPacketizer.inc \
+ HexagonGenMCCodeEmitter.inc \
+ HexagonGenDisassemblerTables.inc
+
+DIRS = TargetInfo MCTargetDesc Disassembler
+
+include $(LEVEL)/Makefile.common