summaryrefslogtreecommitdiff
path: root/lib/Target
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2009-07-01 23:16:05 +0000
committerBob Wilson <bob.wilson@apple.com>2009-07-01 23:16:05 +0000
commit8b024a5eb5b64b482f7d92aad7a3f0e6cac93f12 (patch)
treeb0374c162191192f0ebc78caf49e53e79c064fad /lib/Target
parent4434ed44c45c87a72b7a0bf2f91211f895022b91 (diff)
downloadllvm-8b024a5eb5b64b482f7d92aad7a3f0e6cac93f12.tar.gz
llvm-8b024a5eb5b64b482f7d92aad7a3f0e6cac93f12.tar.bz2
llvm-8b024a5eb5b64b482f7d92aad7a3f0e6cac93f12.tar.xz
Add a new addressing mode for NEON load/store instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74658 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/ARM/ARMAddressingModes.h24
-rw-r--r--lib/Target/ARM/ARMConstantIslandPass.cpp1
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp15
-rw-r--r--lib/Target/ARM/ARMInstrFormats.td19
-rw-r--r--lib/Target/ARM/ARMInstrInfo.h19
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td8
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp17
7 files changed, 82 insertions, 21 deletions
diff --git a/lib/Target/ARM/ARMAddressingModes.h b/lib/Target/ARM/ARMAddressingModes.h
index 7dc2dca58c..15c9ec1fc2 100644
--- a/lib/Target/ARM/ARMAddressingModes.h
+++ b/lib/Target/ARM/ARMAddressingModes.h
@@ -496,7 +496,29 @@ namespace ARM_AM {
static inline bool getAM5WBFlag(unsigned AM5Opc) {
return ((AM5Opc >> 8) & 1);
}
-
+
+ //===--------------------------------------------------------------------===//
+ // Addressing Mode #6
+ //===--------------------------------------------------------------------===//
+ //
+ // This is used for NEON load / store instructions.
+ //
+ // addrmode6 := reg with optional writeback
+ //
+ // This is stored in three operands [regaddr, regupdate, opc]. The first is
+ // the address register. The second register holds the value of a post-access
+ // increment for writeback or reg0 if no writeback or if the writeback
+ // increment is the size of the memory access. The third operand encodes
+ // whether there is writeback to the address register.
+
+ static inline unsigned getAM6Opc(bool WB = false) {
+ return (int)WB;
+ }
+
+ static inline bool getAM6WBFlag(unsigned Mode) {
+ return Mode & 1;
+ }
+
} // end namespace ARM_AM
} // end namespace llvm
diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp
index 19c311c4f2..9fedaa4654 100644
--- a/lib/Target/ARM/ARMConstantIslandPass.cpp
+++ b/lib/Target/ARM/ARMConstantIslandPass.cpp
@@ -462,6 +462,7 @@ void ARMConstantIslands::InitialFunctionScan(MachineFunction &Fn,
Bits = 8;
Scale = 4; // +-(offset_8*4)
break;
+ // addrmode6 has no immediate offset.
case ARMII::AddrModeT1_1:
Bits = 5; // +offset_5
break;
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 258adb583a..15136909bf 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -76,9 +76,11 @@ public:
SDValue &Offset, SDValue &Opc);
bool SelectAddrMode5(SDValue Op, SDValue N, SDValue &Base,
SDValue &Offset);
+ bool SelectAddrMode6(SDValue Op, SDValue N, SDValue &Addr, SDValue &Update,
+ SDValue &Opc);
bool SelectAddrModePC(SDValue Op, SDValue N, SDValue &Offset,
- SDValue &Label);
+ SDValue &Label);
bool SelectThumbAddrModeRR(SDValue Op, SDValue N, SDValue &Base,
SDValue &Offset);
@@ -105,7 +107,6 @@ public:
bool SelectT2AddrModeSoReg(SDValue Op, SDValue N, SDValue &Base,
SDValue &OffReg, SDValue &ShImm);
-
// Include the pieces autogenerated from the target description.
#include "ARMGenDAGISel.inc"
@@ -415,6 +416,16 @@ bool ARMDAGToDAGISel::SelectAddrMode5(SDValue Op, SDValue N,
return true;
}
+bool ARMDAGToDAGISel::SelectAddrMode6(SDValue Op, SDValue N,
+ SDValue &Addr, SDValue &Update,
+ SDValue &Opc) {
+ Addr = N;
+ // The optional writeback is handled in ARMLoadStoreOpt.
+ Update = CurDAG->getRegister(0, MVT::i32);
+ Opc = CurDAG->getTargetConstant(ARM_AM::getAM6Opc(false), MVT::i32);
+ return true;
+}
+
bool ARMDAGToDAGISel::SelectAddrModePC(SDValue Op, SDValue N,
SDValue &Offset, SDValue &Label) {
if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) {
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td
index a9c66a5506..072e9a260e 100644
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -72,15 +72,16 @@ def AddrMode2 : AddrMode<2>;
def AddrMode3 : AddrMode<3>;
def AddrMode4 : AddrMode<4>;
def AddrMode5 : AddrMode<5>;
-def AddrModeT1_1 : AddrMode<6>;
-def AddrModeT1_2 : AddrMode<7>;
-def AddrModeT1_4 : AddrMode<8>;
-def AddrModeT1_s : AddrMode<9>;
-def AddrModeT2_i12: AddrMode<10>;
-def AddrModeT2_i8 : AddrMode<11>;
-def AddrModeT2_so : AddrMode<12>;
-def AddrModeT2_pc : AddrMode<13>;
-def AddrModeT2_i8s4 : AddrMode<14>;
+def AddrMode6 : AddrMode<6>;
+def AddrModeT1_1 : AddrMode<7>;
+def AddrModeT1_2 : AddrMode<8>;
+def AddrModeT1_4 : AddrMode<9>;
+def AddrModeT1_s : AddrMode<10>;
+def AddrModeT2_i12: AddrMode<12>;
+def AddrModeT2_i8 : AddrMode<12>;
+def AddrModeT2_so : AddrMode<13>;
+def AddrModeT2_pc : AddrMode<14>;
+def AddrModeT2_i8s4 : AddrMode<15>;
// Instruction size.
class SizeFlagVal<bits<3> val> {
diff --git a/lib/Target/ARM/ARMInstrInfo.h b/lib/Target/ARM/ARMInstrInfo.h
index cdc420820d..f30104f27c 100644
--- a/lib/Target/ARM/ARMInstrInfo.h
+++ b/lib/Target/ARM/ARMInstrInfo.h
@@ -39,15 +39,16 @@ namespace ARMII {
AddrMode3 = 3,
AddrMode4 = 4,
AddrMode5 = 5,
- AddrModeT1_1 = 6,
- AddrModeT1_2 = 7,
- AddrModeT1_4 = 8,
- AddrModeT1_s = 9, // i8 * 4 for pc and sp relative data
- AddrModeT2_i12 = 10,
- AddrModeT2_i8 = 11,
- AddrModeT2_so = 12,
- AddrModeT2_pc = 13, // +/- i12 for pc relative data
- AddrModeT2_i8s4 = 14, // i8 * 4
+ AddrMode6 = 6,
+ AddrModeT1_1 = 7,
+ AddrModeT1_2 = 8,
+ AddrModeT1_4 = 9,
+ AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data
+ AddrModeT2_i12 = 11,
+ AddrModeT2_i8 = 12,
+ AddrModeT2_so = 13,
+ AddrModeT2_pc = 14, // +/- i12 for pc relative data
+ AddrModeT2_i8s4 = 15, // i8 * 4
// Size* - Flags to keep track of the size of an instruction.
SizeShift = 4,
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index b3f7a7d0e2..380012108e 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -287,6 +287,14 @@ def addrmode5 : Operand<i32>,
let MIOperandInfo = (ops GPR, i32imm);
}
+// addrmode6 := reg with optional writeback
+//
+def addrmode6 : Operand<i32>,
+ ComplexPattern<i32, 3, "SelectAddrMode6", []> {
+ let PrintMethod = "printAddrMode6Operand";
+ let MIOperandInfo = (ops GPR:$addr, GPR:$upd, i32imm);
+}
+
// addrmodepc := pc + reg
//
def addrmodepc : Operand<i32>,
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index 773f279d86..20a1a93c05 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -105,6 +105,7 @@ namespace {
const char *Modifier = 0);
void printAddrMode5Operand(const MachineInstr *MI, int OpNum,
const char *Modifier = 0);
+ void printAddrMode6Operand(const MachineInstr *MI, int OpNum);
void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
const char *Modifier = 0);
void printBitfieldInvMaskImmOperand (const MachineInstr *MI, int OpNum);
@@ -587,6 +588,22 @@ void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
O << "]";
}
+void ARMAsmPrinter::printAddrMode6Operand(const MachineInstr *MI, int Op) {
+ const MachineOperand &MO1 = MI->getOperand(Op);
+ const MachineOperand &MO2 = MI->getOperand(Op+1);
+ const MachineOperand &MO3 = MI->getOperand(Op+2);
+
+ // FIXME: No support yet for specifying alignment.
+ O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName << "]";
+
+ if (ARM_AM::getAM6WBFlag(MO3.getImm())) {
+ if (MO2.getReg() == 0)
+ O << "!";
+ else
+ O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
+ }
+}
+
void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
const char *Modifier) {
if (Modifier && strcmp(Modifier, "label") == 0) {