Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(657)

Unified Diff: src/IceAssemblerARM32.cpp

Issue 1697263007: Add fabs(<4 x float>) to the integrated ARM assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Clean up CL. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceAssemblerARM32.cpp
diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp
index f4e985558ce5837f67e41fa62e36b5465b81395e..ed2622c2b03a0cd07dacd96051277054a24f7aca 100644
--- a/src/IceAssemblerARM32.cpp
+++ b/src/IceAssemblerARM32.cpp
@@ -144,24 +144,6 @@ IValueT encodeCondition(CondARM32::Cond Cond) {
return static_cast<IValueT>(Cond);
}
-// Returns the SIMD encoding of the element type for the vector.
-IValueT encodeElmtType(Type ElmtTy) {
- switch (ElmtTy) {
- case IceType_i8:
- case IceType_f32:
- return 0;
- case IceType_i16:
- return 1;
- case IceType_i32:
- return 2;
- case IceType_i64:
- return 3;
- default:
- llvm::report_fatal_error("SIMD op: Don't understand element type " +
- typeIceString(ElmtTy));
- }
-}
-
IValueT encodeShift(OperandARM32::ShiftKind Shift) {
// Follows encoding in ARM section A8.4.1 "Constant shifts".
switch (Shift) {
@@ -619,6 +601,23 @@ size_t MoveRelocatableFixup::emit(GlobalContext *Ctx,
return InstARM32::InstSize;
}
+IValueT AssemblerARM32::encodeElmtType(Type ElmtTy) {
+ switch (ElmtTy) {
+ case IceType_i8:
+ return 0;
+ case IceType_i16:
+ return 1;
+ case IceType_i32:
+ case IceType_f32:
+ return 2;
+ case IceType_i64:
+ return 3;
+ default:
+ llvm::report_fatal_error("SIMD op: Don't understand element type " +
+ typeIceString(ElmtTy));
+ }
+}
+
// This fixup points to an ARM32 instruction with the following format:
void MoveRelocatableFixup::emitOffset(Assembler *Asm) const {
// cccc00110T00iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd,
@@ -1149,28 +1148,45 @@ void AssemblerARM32::emitSignExtend(CondARM32::Cond Cond, IValueT Opcode,
emitInst(Encoding);
}
-void AssemblerARM32::emitSIMD(IValueT Opcode, Type ElmtTy, IValueT Dd,
- IValueT Dn, IValueT Dm, bool UseQRegs) {
- IValueT Sz = encodeElmtType(ElmtTy);
- assert(Utils::IsUint(2, Sz));
- IValueT Encoding =
+void AssemblerARM32::emitSIMDBase(IValueT Opcode, IValueT Dd, IValueT Dn,
+ IValueT Dm, bool UseQRegs, bool IsFloatTy) {
+ const IValueT Encoding =
Opcode | B25 | (encodeCondition(CondARM32::kNone) << kConditionShift) |
- (Sz << 20) | (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) |
- (getXXXXInRegYXXXX(Dd) << 12) | (getYInRegYXXXX(Dn) << 7) |
- (encodeBool(UseQRegs) << 6) | (getYInRegYXXXX(Dm) << 5) |
- getXXXXInRegYXXXX(Dm);
+ (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) |
Eric Holk 2016/02/16 22:31:34 Optional, but should these other shift amounts be
Karl 2016/02/17 17:51:44 DART has been somewhat inconsistent on this. I hav
+ (getXXXXInRegYXXXX(Dd) << 12) | (IsFloatTy ? B10 : 0) |
+ (getYInRegYXXXX(Dn) << 7) | (encodeBool(UseQRegs) << 6) |
+ (getYInRegYXXXX(Dm) << 5) | getXXXXInRegYXXXX(Dm);
emitInst(Encoding);
}
+void AssemblerARM32::emitSIMD(IValueT Opcode, Type ElmtTy, IValueT Dd,
+ IValueT Dn, IValueT Dm, bool UseQRegs) {
+ constexpr IValueT ElmtShift = 20;
+ const IValueT ElmtSize = encodeElmtType(ElmtTy);
+ assert(Utils::IsUint(2, ElmtSize));
+ emitSIMDBase(Opcode | (ElmtSize << ElmtShift), Dd, Dn, Dm, UseQRegs,
+ isFloatingType(ElmtTy));
+}
+
+void AssemblerARM32::emitSIMDqqqBase(IValueT Opcode, const Operand *OpQd,
+ const Operand *OpQn, const Operand *OpQm,
+ bool IsFloatTy, const char *OpcodeName) {
+ const IValueT Qd = encodeQRegister(OpQd, "Qd", OpcodeName);
+ const IValueT Qn = encodeQRegister(OpQn, "Qn", OpcodeName);
+ const IValueT Qm = encodeQRegister(OpQm, "Qm", OpcodeName);
+ constexpr bool UseQRegs = true;
+ emitSIMDBase(Opcode, mapQRegToDReg(Qd), mapQRegToDReg(Qn), mapQRegToDReg(Qm),
+ UseQRegs, IsFloatTy);
+}
+
void AssemblerARM32::emitSIMDqqq(IValueT Opcode, Type ElmtTy,
const Operand *OpQd, const Operand *OpQn,
const Operand *OpQm, const char *OpcodeName) {
- IValueT Qd = encodeQRegister(OpQd, "Qd", OpcodeName);
- IValueT Qn = encodeQRegister(OpQn, "Qn", OpcodeName);
- IValueT Qm = encodeQRegister(OpQm, "Qm", OpcodeName);
- constexpr bool UseQRegs = true;
- emitSIMD(Opcode, ElmtTy, mapQRegToDReg(Qd), mapQRegToDReg(Qn),
- mapQRegToDReg(Qm), UseQRegs);
+ constexpr IValueT ElmtShift = 20;
+ const IValueT ElmtSize = encodeElmtType(ElmtTy);
+ assert(Utils::IsUint(2, ElmtSize));
+ emitSIMDqqqBase(Opcode | (ElmtSize << ElmtShift), OpQd, OpQn, OpQm,
+ isFloatingType(ElmtTy), OpcodeName);
}
void AssemblerARM32::emitVFPddd(CondARM32::Cond Cond, IValueT Opcode,
@@ -2249,13 +2265,31 @@ void AssemblerARM32::vabsd(const Operand *OpDd, const Operand *OpDm,
//
// cccc11101D110000dddd101111M0mmmm where cccc=Cond, Ddddd=Dd, and Mmmmm=Dm.
constexpr const char *Vabsd = "vabsd";
- IValueT Dd = encodeDRegister(OpDd, "Dd", Vabsd);
- IValueT Dm = encodeDRegister(OpDm, "Dm", Vabsd);
+ const IValueT Dd = encodeDRegister(OpDd, "Dd", Vabsd);
+ const IValueT Dm = encodeDRegister(OpDm, "Dm", Vabsd);
constexpr IValueT D0 = 0;
constexpr IValueT VabsdOpcode = B23 | B21 | B20 | B7 | B6;
emitVFPddd(Cond, VabsdOpcode, Dd, D0, Dm);
}
+void AssemblerARM32::vabsq(const Operand *OpQd, const Operand *OpQm) {
+ // VABS - ARM section A8.8.280, encoding A1:
+ // vabs.<dt> <Qd>, <Qm>
+ //
+ // 111100111D11ss01ddd0f1101M0mmm0 where Dddd=OpQd, Mddd=OpQm, and
+ // <dt> in {s8, s16, s32, f32} and ss is the encoding of <dt>.
+ const Type ElmtTy = typeElementType(OpQd->getType());
+ assert(ElmtTy != IceType_i64 && "vabsq doesn't allow i64!");
+ constexpr const char *Vabsq = "vabsq";
+ const IValueT Dd = mapQRegToDReg(encodeQRegister(OpQd, "Qd", Vabsq));
+ const IValueT Dm = mapQRegToDReg(encodeQRegister(OpQm, "Qm", Vabsq));
+ constexpr IValueT Dn = 0;
+ const IValueT VabsqOpcode =
+ B24 | B23 | B21 | B20 | B16 | B9 | B8 | (encodeElmtType(ElmtTy) << 18);
+ constexpr bool UseQRegs = true;
+ emitSIMDBase(VabsqOpcode, Dd, Dn, Dm, UseQRegs, isFloatingType(ElmtTy));
+}
+
void AssemblerARM32::vadds(const Operand *OpSd, const Operand *OpSn,
const Operand *OpSm, CondARM32::Cond Cond) {
// VADD (floating-point) - ARM section A8.8.283, encoding A2:
@@ -2275,6 +2309,8 @@ void AssemblerARM32::vaddqi(Type ElmtTy, const Operand *OpQd,
//
// 111100100Dssnnn0ddd01000N1M0mmm0 where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
// and dt in [i8, i16, i32, i64] where ss is the index.
+ assert(isScalarIntegerType(ElmtTy) &&
+ "vaddqi expects vector with integer element type");
constexpr const char *Vaddqi = "vaddqi";
constexpr IValueT VaddqiOpcode = B11;
emitSIMDqqq(VaddqiOpcode, ElmtTy, OpQd, OpQm, OpQn, Vaddqi);
@@ -2286,9 +2322,11 @@ void AssemblerARM32::vaddqf(const Operand *OpQd, const Operand *OpQn,
// vadd.f32 <Qd>, <Qn>, <Qm>
//
// 111100100D00nnn0ddd01101N1M0mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
+ assert(OpQd->getType() == IceType_v4f32 && "vaddqf expects type <4 x float>");
constexpr const char *Vaddqf = "vaddqf";
- constexpr IValueT VaddqfOpcode = B11 | B10 | B8;
- emitSIMDqqq(VaddqfOpcode, IceType_f32, OpQd, OpQn, OpQm, Vaddqf);
+ constexpr IValueT VaddqfOpcode = B11 | B8;
+ constexpr bool IsFloatTy = true;
+ emitSIMDqqqBase(VaddqfOpcode, OpQd, OpQn, OpQm, IsFloatTy, Vaddqf);
}
void AssemblerARM32::vaddd(const Operand *OpDd, const Operand *OpDn,
@@ -2560,6 +2598,10 @@ void AssemblerARM32::veord(const Operand *OpDd, const Operand *OpDn,
void AssemblerARM32::veorq(const Operand *OpQd, const Operand *OpQn,
const Operand *OpQm) {
+ // VEOR - ARM section A8.8.316, encoding A1:
+ // veor <Qd>, <Qn>, <Qm>
+ //
+ // 111100110D00nnn0ddd00001N1M1mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
constexpr const char *Veorq = "veorq";
constexpr IValueT VeorqOpcode = B24 | B8 | B4;
emitSIMDqqq(VeorqOpcode, IceType_i8, OpQd, OpQn, OpQm, Veorq);
@@ -2937,6 +2979,8 @@ void AssemblerARM32::vmulqi(Type ElmtTy, const Operand *OpQd,
//
// 111100100Dssnnn0ddd01001NqM1mmm0 where Dddd=Qd, Nnnn=Qn, Mmmm=Qm, and
// dt in [i8, i16, i32] where ss is the index.
+ assert(isScalarIntegerType(ElmtTy) &&
+ "vmulqi expects vector with integer element type");
assert(ElmtTy != IceType_i64 && "vmulqi on i64 vector not allowed");
constexpr const char *Vmulqi = "vmulqi";
constexpr IValueT VmulqiOpcode = B11 | B8 | B4;
@@ -2949,9 +2993,11 @@ void AssemblerARM32::vmulqf(const Operand *OpQd, const Operand *OpQn,
// vmul.f32 <Qd>, <Qn>, <Qm>
//
// 111100110D00nnn0ddd01101MqM1mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
+ assert(OpQd->getType() == IceType_v4f32 && "vmulqf expects type <4 x float>");
constexpr const char *Vmulqf = "vmulqf";
- constexpr IValueT VmulqfOpcode = B24 | B11 | B10 | B8 | B4;
- emitSIMDqqq(VmulqfOpcode, IceType_f32, OpQd, OpQn, OpQm, Vmulqf);
+ constexpr IValueT VmulqfOpcode = B24 | B11 | B8 | B4;
+ constexpr bool IsFloatTy = true;
+ emitSIMDqqqBase(VmulqfOpcode, OpQd, OpQn, OpQm, IsFloatTy, Vmulqf);
}
void AssemblerARM32::vorrq(const Operand *OpQd, const Operand *OpQm,
@@ -3062,6 +3108,8 @@ void AssemblerARM32::vsubqi(Type ElmtTy, const Operand *OpQd,
//
// 111100110Dssnnn0ddd01000N1M0mmm0 where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
// and dt in [i8, i16, i32, i64] where ss is the index.
+ assert(isScalarIntegerType(ElmtTy) &&
+ "vsubqi expects vector with integer element type");
constexpr const char *Vsubqi = "vsubqi";
constexpr IValueT VsubqiOpcode = B24 | B11;
emitSIMDqqq(VsubqiOpcode, ElmtTy, OpQd, OpQm, OpQn, Vsubqi);
@@ -3073,8 +3121,9 @@ void AssemblerARM32::vsubqf(const Operand *OpQd, const Operand *OpQn,
// vsub.f32 <Qd>, <Qn>, <Qm>
//
// 111100100D10nnn0ddd01101N1M0mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
+ assert(OpQd->getType() == IceType_v4f32 && "vsubqf expects type <4 x float>");
constexpr const char *Vsubqf = "vsubqf";
- constexpr IValueT VsubqfOpcode = B21 | B11 | B10 | B8;
+ constexpr IValueT VsubqfOpcode = B21 | B11 | B8;
Eric Holk 2016/02/16 22:31:34 Was setting B10 before a bug?
Karl 2016/02/17 17:51:44 No. I noticed that whenever there were V-based ins
emitSIMDqqq(VsubqfOpcode, IceType_f32, OpQd, OpQn, OpQm, Vsubqf);
}

Powered by Google App Engine
This is Rietveld 408576698