aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/AArch64/InstPrinter
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2013-08-01 09:20:35 +0000
committerTim Northover <tnorthover@apple.com>2013-08-01 09:20:35 +0000
commit87773c318fcee853fb34a80a10c4347d523bdafb (patch)
tree6c8b6620d46529f553a508e9190a264534e0a0dd /lib/Target/AArch64/InstPrinter
parent691aa094dafe54151b6f70168f066bd87c161e8d (diff)
downloadexternal_llvm-87773c318fcee853fb34a80a10c4347d523bdafb.zip
external_llvm-87773c318fcee853fb34a80a10c4347d523bdafb.tar.gz
external_llvm-87773c318fcee853fb34a80a10c4347d523bdafb.tar.bz2
AArch64: add initial NEON support
Patch by Ana Pazos. - Completed implementation of instruction formats: AdvSIMD three same AdvSIMD modified immediate AdvSIMD scalar pairwise - Completed implementation of instruction classes (some of the instructions in these classes belong to yet unfinished instruction formats): Vector Arithmetic Vector Immediate Vector Pairwise Arithmetic - Initial implementation of instruction formats: AdvSIMD scalar two-reg misc AdvSIMD scalar three same - Intial implementation of instruction class: Scalar Arithmetic - Initial clang changes to support arm v8 intrinsics. Note: no clang changes for scalar intrinsics function name mangling yet. - Comprehensive test cases for added instructions To verify auto codegen, encoding, decoding, diagnosis, intrinsics. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187567 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/AArch64/InstPrinter')
-rw-r--r--lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp81
-rw-r--r--lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h9
2 files changed, 88 insertions, 2 deletions
diff --git a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
index 82ce80c..b624331 100644
--- a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
+++ b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
@@ -406,3 +406,84 @@ void AArch64InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
printAnnotation(O, Annot);
}
+
+template <A64SE::ShiftExtSpecifiers Ext, bool isHalf>
+void AArch64InstPrinter::printNeonMovImmShiftOperand(const MCInst *MI,
+ unsigned OpNum,
+ raw_ostream &O) {
+ const MCOperand &MO = MI->getOperand(OpNum);
+
+ assert(MO.isImm() &&
+ "Immediate operand required for Neon vector immediate inst.");
+
+ bool IsLSL = false;
+ if (Ext == A64SE::LSL)
+ IsLSL = true;
+ else if (Ext != A64SE::MSL)
+ llvm_unreachable("Invalid shift specifier in movi instruction");
+
+ int64_t Imm = MO.getImm();
+
+ // MSL and LSLH accepts encoded shift amount 0 or 1.
+ if ((!IsLSL || (IsLSL && isHalf)) && Imm != 0 && Imm != 1)
+ llvm_unreachable("Invalid shift amount in movi instruction");
+
+ // LSH accepts encoded shift amount 0, 1, 2 or 3.
+ if (IsLSL && (Imm < 0 || Imm > 3))
+ llvm_unreachable("Invalid shift amount in movi instruction");
+
+ // Print shift amount as multiple of 8 with MSL encoded shift amount
+ // 0 and 1 printed as 8 and 16.
+ if (!IsLSL)
+ Imm++;
+ Imm *= 8;
+
+ // LSL #0 is not printed
+ if (IsLSL) {
+ if (Imm == 0)
+ return;
+ O << ", lsl";
+ } else
+ O << ", msl";
+
+ O << " #" << Imm;
+}
+
+void AArch64InstPrinter::printNeonUImm0Operand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &o) {
+ o << "#0x0";
+}
+
+void AArch64InstPrinter::printNeonUImm8Operand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O) {
+ const MCOperand &MOUImm = MI->getOperand(OpNum);
+
+ assert(MOUImm.isImm() &&
+ "Immediate operand required for Neon vector immediate inst.");
+
+ unsigned Imm = MOUImm.getImm();
+
+ O << "#0x";
+ O.write_hex(Imm);
+}
+
+void AArch64InstPrinter::printNeonUImm64MaskOperand(const MCInst *MI,
+ unsigned OpNum,
+ raw_ostream &O) {
+ const MCOperand &MOUImm8 = MI->getOperand(OpNum);
+
+ assert(MOUImm8.isImm() &&
+ "Immediate operand required for Neon vector immediate bytemask inst.");
+
+ uint32_t UImm8 = MOUImm8.getImm();
+ uint64_t Mask = 0;
+
+ // Replicates 0x00 or 0xff byte in a 64-bit vector
+ for (unsigned ByteNum = 0; ByteNum < 8; ++ByteNum) {
+ if ((UImm8 >> ByteNum) & 1)
+ Mask |= (uint64_t)0xff << (8 * ByteNum);
+ }
+
+ O << "#0x";
+ O.write_hex(Mask);
+}
diff --git a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h
index 639fa86..f7439be 100644
--- a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h
+++ b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h
@@ -164,9 +164,14 @@ public:
return RegNo == AArch64::XSP || RegNo == AArch64::WSP;
}
-
+ template <A64SE::ShiftExtSpecifiers Ext, bool IsHalf>
+ void printNeonMovImmShiftOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
+ void printNeonUImm0Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printNeonUImm8Operand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printNeonUImm64MaskOperand(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
};
-
}
#endif