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

Unified Diff: src/IceAssemblerARM32.cpp

Issue 1679023008: Add insert/extract element to the integrated ARM assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. 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
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.h » ('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 ba328c807b494716de33ac15eaecea328dd01f34..a9ef88e7f0115bc2e054f1e6f5c9cb703c732bec 100644
--- a/src/IceAssemblerARM32.cpp
+++ b/src/IceAssemblerARM32.cpp
@@ -158,7 +158,7 @@ IValueT encodeElmtType(Type ElmtTy) {
return 3;
default:
llvm::report_fatal_error("SIMD op: Don't understand element type " +
- std::string(typeString(ElmtTy)));
+ typeIceString(ElmtTy));
}
}
@@ -213,7 +213,17 @@ IValueT getEncodedQRegNum(const Variable *Var) {
return RegARM32::getEncodedQReg(Var->getRegNum());
}
-IValueT mapQRegToDReg(IValueT EncodedQReg) { return EncodedQReg << 1; }
+IValueT mapQRegToDReg(IValueT EncodedQReg) {
+ IValueT DReg = EncodedQReg << 1;
+ assert(DReg < RegARM32::getNumDRegs());
+ return DReg;
+}
+
+IValueT mapQRegToSReg(IValueT EncodedQReg) {
+ IValueT SReg = EncodedQReg << 2;
+ assert(SReg < RegARM32::getNumSRegs());
+ return SReg;
+}
IValueT getYInRegXXXXY(IValueT RegXXXXY) { return RegXXXXY & 0x1; }
@@ -1010,6 +1020,60 @@ void AssemblerARM32::emitDivOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
emitInst(Encoding);
}
+void AssemblerARM32::emitInsertExtractInt(CondARM32::Cond Cond,
+ const Operand *OpQn, uint32_t Index,
+ const Operand *OpRt, bool IsExtract,
+ const char *InstName) {
+ const IValueT Rt = encodeGPRegister(OpRt, "Rt", InstName);
+ IValueT Dn = mapQRegToDReg(encodeQRegister(OpQn, "Qn", InstName));
+ assert(Rt != RegARM32::Encoded_Reg_pc);
+ assert(Rt != RegARM32::Encoded_Reg_sp);
+ assert(CondARM32::isDefined(Cond));
+ const uint32_t BitSize = typeWidthInBytes(OpRt->getType()) * CHAR_BIT;
+ IValueT Opcode1 = 0;
+ IValueT Opcode2 = 0;
+ switch (BitSize) {
+ default:
+ llvm::report_fatal_error(std::string(InstName) +
+ ": Unable to process type " +
+ typeIceString(OpRt->getType()));
+ case 8:
+ assert(Index < 16);
+ Dn = Dn | mask(Index, 3, 1);
+ Opcode1 = B1 | mask(Index, 2, 1);
+ Opcode2 = mask(Index, 0, 2);
+ break;
+ case 16:
+ assert(Index < 8);
+ Dn = Dn | mask(Index, 2, 1);
+ Opcode1 = mask(Index, 1, 1);
+ Opcode2 = (mask(Index, 0, 1) << 1) | B0;
+ break;
+ case 32:
+ assert(Index < 4);
+ Dn = Dn | mask(Index, 1, 1);
+ Opcode1 = mask(Index, 0, 1);
+ break;
+ }
+ const IValueT Encoding = B27 | B26 | B25 | B11 | B9 | B8 | B4 |
+ (encodeCondition(Cond) << kConditionShift) |
+ (Opcode1 << 21) |
+ (getXXXXInRegYXXXX(Dn) << kRnShift) | (Rt << 12) |
+ (encodeBool(IsExtract) << 20) |
+ (getYInRegYXXXX(Dn) << 7) | (Opcode2 << 5);
+ emitInst(Encoding);
+}
+
+void AssemblerARM32::emitMoveSS(CondARM32::Cond Cond, IValueT Sd, IValueT Sm) {
+ // VMOV (register) - ARM section A8.8.340, encoding A2:
+ // vmov<c>.f32 <Sd>, <Sm>
+ //
+ // cccc11101D110000dddd101001M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
+ constexpr IValueT VmovssOpcode = B23 | B21 | B20 | B6;
+ constexpr IValueT S0 = 0;
+ emitVFPsss(Cond, VmovssOpcode, Sd, S0, Sm);
+}
+
void AssemblerARM32::emitMulOp(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd,
IValueT Rn, IValueT Rm, IValueT Rs,
bool SetFlags) {
@@ -2654,6 +2718,33 @@ void AssemblerARM32::vmovdrr(const Operand *OpDm, const Operand *OpRt,
emitInst(Encoding);
}
+void AssemblerARM32::vmovqir(const Operand *OpQn, uint32_t Index,
+ const Operand *OpRt, CondARM32::Cond Cond) {
+ // VMOV (ARM core register to scalar) - ARM section A8.8.341, encoding A1:
+ // vmov<c>.<size> <Dn[x]>, <Rt>
+ constexpr const char *Vmovdr = "vmovdr";
+ constexpr bool IsExtract = true;
+ emitInsertExtractInt(Cond, OpQn, Index, OpRt, !IsExtract, Vmovdr);
+}
+
+void AssemblerARM32::vmovqis(const Operand *OpQd, uint32_t Index,
+ const Operand *OpSm, CondARM32::Cond Cond) {
+ constexpr const char *Vmovqis = "vmovqis";
+ assert(Index < 4);
+ IValueT Sd = mapQRegToSReg(encodeQRegister(OpQd, "Qd", Vmovqis)) + Index;
+ IValueT Sm = encodeSRegister(OpSm, "Sm", Vmovqis);
+ emitMoveSS(Cond, Sd, Sm);
+}
+
+void AssemblerARM32::vmovrqi(const Operand *OpRt, const Operand *OpQn,
+ uint32_t Index, CondARM32::Cond Cond) {
+ // VMOV (scalar to ARM core register) - ARM section A8.8.342, encoding A1:
+ // vmov<c>.<dt> <Rt>, <Dn[x]>
+ constexpr const char *Vmovrd = "vmovrd";
+ constexpr bool IsExtract = true;
+ emitInsertExtractInt(Cond, OpQn, Index, OpRt, IsExtract, Vmovrd);
+}
+
void AssemblerARM32::vmovrrd(const Operand *OpRt, const Operand *OpRt2,
const Operand *OpDm, CondARM32::Cond Cond) {
// VMOV (between two ARM core registers and a doubleword extension register).
@@ -2716,16 +2807,20 @@ void AssemblerARM32::vmovs(const Operand *OpSd,
void AssemblerARM32::vmovss(const Operand *OpSd, const Variable *OpSm,
CondARM32::Cond Cond) {
- // VMOV (register) - ARM section A8.8.340, encoding A2:
- // vmov<c>.f32 <Sd>, <Sm>
- //
- // cccc11101D110000dddd101001M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
constexpr const char *Vmovss = "Vmovss";
IValueT Sd = encodeSRegister(OpSd, "Sd", Vmovss);
IValueT Sm = encodeSRegister(OpSm, "Sm", Vmovss);
- constexpr IValueT VmovssOpcode = B23 | B21 | B20 | B6;
- constexpr IValueT S0 = 0;
- emitVFPsss(Cond, VmovssOpcode, Sd, S0, Sm);
+ emitMoveSS(Cond, Sd, Sm);
+}
+
+void AssemblerARM32::vmovsqi(const Operand *OpSd, const Operand *OpQm,
+ uint32_t Index, CondARM32::Cond Cond) {
+ constexpr const char *Vmovsqi = "vmovsqi";
+ const IValueT Sd = encodeSRegister(OpSd, "Sd", Vmovsqi);
+ assert(Index < 4);
+ const IValueT Sm =
+ mapQRegToSReg(encodeQRegister(OpQm, "Qm", Vmovsqi)) + Index;
+ emitMoveSS(Cond, Sd, Sm);
}
void AssemblerARM32::vmovsr(const Operand *OpSn, const Operand *OpRt,
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698