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

Unified Diff: src/IceAssemblerARM32.cpp

Issue 1652173002: Implements the vector add instructions in the integrated ARM assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. Created 4 years, 11 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
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceAssemblerARM32.cpp
diff --git a/src/IceAssemblerARM32.cpp b/src/IceAssemblerARM32.cpp
index dd1e2644ec199290021b42d43c5b50d1a5a76687..13e2b1a4d09f2bdba2229ae5b89c8ff1ecd6ecb1 100644
--- a/src/IceAssemblerARM32.cpp
+++ b/src/IceAssemblerARM32.cpp
@@ -144,6 +144,25 @@ 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(
+ std::string("SIMD op: Don't understand element type ") +
+ typeString(ElmtTy));
+ }
+}
+
IValueT encodeShift(OperandARM32::ShiftKind Shift) {
// Follows encoding in ARM section A8.4.1 "Constant shifts".
switch (Shift) {
@@ -191,6 +210,12 @@ IValueT getEncodedDRegNum(const Variable *Var) {
return RegARM32::getEncodedDReg(Var->getRegNum());
}
+IValueT getEncodedQRegNum(const Variable *Var) {
+ return RegARM32::getEncodedQReg(Var->getRegNum());
+}
+
+IValueT mapQRegToDReg(IValueT EncodedQReg) { return EncodedQReg << 1; }
+
IValueT getYInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY & 0x1; }
IValueT getXXXXInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY >> 1; }
@@ -305,7 +330,7 @@ IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift,
}
// Defines the set of registers expected in an operand.
-enum RegSetWanted { WantGPRegs, WantSRegs, WantDRegs };
+enum RegSetWanted { WantGPRegs, WantSRegs, WantDRegs, WantQRegs };
EncodedOperand encodeOperand(const Operand *Opnd, IValueT &Value,
RegSetWanted WantedRegSet) {
@@ -322,6 +347,9 @@ EncodedOperand encodeOperand(const Operand *Opnd, IValueT &Value,
case WantDRegs:
Value = getEncodedDRegNum(Var);
break;
+ case WantQRegs:
+ Value = getEncodedQRegNum(Var);
+ break;
}
return EncodedAsRegister;
}
@@ -503,6 +531,11 @@ IValueT encodeDRegister(const Operand *OpReg, const char *RegName,
return encodeRegister(OpReg, WantDRegs, RegName, InstName);
}
+IValueT encodeQRegister(const Operand *OpReg, const char *RegName,
+ const char *InstName) {
+ return encodeRegister(OpReg, WantQRegs, RegName, InstName);
+}
+
void verifyPOrNotW(IValueT Address, const char *InstName) {
if (BuildDefs::minimal())
return;
@@ -1030,6 +1063,30 @@ 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 =
+ 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);
+ emitInst(Encoding);
+}
+
+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);
+}
+
void AssemblerARM32::emitVFPddd(CondARM32::Cond Cond, IValueT Opcode,
IValueT Dd, IValueT Dn, IValueT Dm) {
assert(Dd < RegARM32::getNumDRegs());
@@ -2097,6 +2154,29 @@ void AssemblerARM32::vadds(const Operand *OpSd, const Operand *OpSn,
emitVFPsss(Cond, VaddsOpcode, OpSd, OpSn, OpSm, Vadds);
}
+void AssemblerARM32::vaddqi(Type ElmtTy, const Operand *OpQd,
+ const Operand *OpQm, const Operand *OpQn) {
+ // VADD (integer) - ARM section A8.8.282, encoding A1:
+ // vadd.<dt> <Qd>, <Qn>, <Qm>
+ //
+ // 111100100Dssnnn0ddd01000NqM0mmm0 where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
+ // and dt in [i8, i16, i32, i64] where ss is the index.
+ constexpr const char *Vaddqi = "vaddqi";
+ constexpr IValueT VaddqiOpcode = B11;
+ emitSIMDqqq(VaddqiOpcode, ElmtTy, OpQd, OpQm, OpQn, Vaddqi);
+}
+
+void AssemblerARM32::vaddqf(const Operand *OpQd, const Operand *OpQn,
+ const Operand *OpQm) {
+ // VADD (floating-point) - ARM section A8.8.283, Encoding A1:
+ // vadd.f32 <Qd>, <Qn>, <Qm>
+ //
+ // 111100100D00nnn0ddd01101N1M0mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
+ constexpr const char *Vaddqf = "vaddqf";
+ constexpr IValueT VaddqfOpcode = B11 | B10 | B8;
+ emitSIMDqqq(VaddqfOpcode, IceType_f32, OpQd, OpQn, OpQm, Vaddqf);
+}
+
void AssemblerARM32::vaddd(const Operand *OpDd, const Operand *OpDn,
const Operand *OpDm, CondARM32::Cond Cond) {
// VADD (floating-point) - ARM section A8.8.283, encoding A2:
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698