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

Side by Side 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: 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 unified diff | Download patch
« no previous file with comments | « src/IceAssemblerARM32.h ('k') | src/IceInstARM32.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// 1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===//
2 // 2 //
3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
4 // for details. All rights reserved. Use of this source code is governed by a 4 // for details. All rights reserved. Use of this source code is governed by a
5 // BSD-style license that can be found in the LICENSE file. 5 // BSD-style license that can be found in the LICENSE file.
6 // 6 //
7 // Modified by the Subzero authors. 7 // Modified by the Subzero authors.
8 // 8 //
9 //===----------------------------------------------------------------------===// 9 //===----------------------------------------------------------------------===//
10 // 10 //
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 } 137 }
138 138
139 RegARM32::GPRRegister decodeGPRRegister(IValueT R) { 139 RegARM32::GPRRegister decodeGPRRegister(IValueT R) {
140 return static_cast<RegARM32::GPRRegister>(R); 140 return static_cast<RegARM32::GPRRegister>(R);
141 } 141 }
142 142
143 IValueT encodeCondition(CondARM32::Cond Cond) { 143 IValueT encodeCondition(CondARM32::Cond Cond) {
144 return static_cast<IValueT>(Cond); 144 return static_cast<IValueT>(Cond);
145 } 145 }
146 146
147 // Returns the SIMD encoding of the element type for the vector.
148 IValueT encodeElmtType(Type ElmtTy) {
149 switch (ElmtTy) {
150 case IceType_i8:
151 case IceType_f32:
152 return 0;
153 case IceType_i16:
154 return 1;
155 case IceType_i32:
156 return 2;
157 case IceType_i64:
158 return 3;
159 default:
160 llvm::report_fatal_error("SIMD op: Don't understand element type " +
161 typeIceString(ElmtTy));
162 }
163 }
164
165 IValueT encodeShift(OperandARM32::ShiftKind Shift) { 147 IValueT encodeShift(OperandARM32::ShiftKind Shift) {
166 // Follows encoding in ARM section A8.4.1 "Constant shifts". 148 // Follows encoding in ARM section A8.4.1 "Constant shifts".
167 switch (Shift) { 149 switch (Shift) {
168 case OperandARM32::kNoShift: 150 case OperandARM32::kNoShift:
169 case OperandARM32::LSL: 151 case OperandARM32::LSL:
170 return 0; // 0b00 152 return 0; // 0b00
171 case OperandARM32::LSR: 153 case OperandARM32::LSR:
172 return 1; // 0b01 154 return 1; // 0b01
173 case OperandARM32::ASR: 155 case OperandARM32::ASR:
174 return 2; // 0b10 156 return 2; // 0b10
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 const bool IsMovw = kind() == llvm::ELF::R_ARM_MOVW_ABS_NC || 594 const bool IsMovw = kind() == llvm::ELF::R_ARM_MOVW_ABS_NC ||
613 kind() == llvm::ELF::R_ARM_MOVW_PREL_NC; 595 kind() == llvm::ELF::R_ARM_MOVW_PREL_NC;
614 Str << "\t" 596 Str << "\t"
615 "mov" << (IsMovw ? "w" : "t") << "\t" 597 "mov" << (IsMovw ? "w" : "t") << "\t"
616 << RegARM32::getRegName(RegNumT::fixme((Inst >> kRdShift) & 0xF)) 598 << RegARM32::getRegName(RegNumT::fixme((Inst >> kRdShift) & 0xF))
617 << ", #:" << (IsMovw ? "lower" : "upper") << "16:" << symbol(Ctx, &Asm) 599 << ", #:" << (IsMovw ? "lower" : "upper") << "16:" << symbol(Ctx, &Asm)
618 << "\t@ .word " << llvm::format_hex_no_prefix(Inst, 8) << "\n"; 600 << "\t@ .word " << llvm::format_hex_no_prefix(Inst, 8) << "\n";
619 return InstARM32::InstSize; 601 return InstARM32::InstSize;
620 } 602 }
621 603
604 IValueT AssemblerARM32::encodeElmtType(Type ElmtTy) {
605 switch (ElmtTy) {
606 case IceType_i8:
607 return 0;
608 case IceType_i16:
609 return 1;
610 case IceType_i32:
611 case IceType_f32:
612 return 2;
613 case IceType_i64:
614 return 3;
615 default:
616 llvm::report_fatal_error("SIMD op: Don't understand element type " +
617 typeIceString(ElmtTy));
618 }
619 }
620
622 // This fixup points to an ARM32 instruction with the following format: 621 // This fixup points to an ARM32 instruction with the following format:
623 void MoveRelocatableFixup::emitOffset(Assembler *Asm) const { 622 void MoveRelocatableFixup::emitOffset(Assembler *Asm) const {
624 // cccc00110T00iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, 623 // cccc00110T00iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd,
625 // iiiiiiiiiiiiiiii = Imm16, and T=1 for movt. 624 // iiiiiiiiiiiiiiii = Imm16, and T=1 for movt.
626 625
627 const IValueT Inst = Asm->load<IValueT>(position()); 626 const IValueT Inst = Asm->load<IValueT>(position());
628 constexpr IValueT Imm16Mask = 0x000F0FFF; 627 constexpr IValueT Imm16Mask = 0x000F0FFF;
629 const IValueT Imm16 = offset() & 0xffff; 628 const IValueT Imm16 = offset() & 0xffff;
630 Asm->store(position(), 629 Asm->store(position(),
631 (Inst & ~Imm16Mask) | ((Imm16 >> 12) << 16) | (Imm16 & 0xfff)); 630 (Inst & ~Imm16Mask) | ((Imm16 >> 12) << 16) | (Imm16 & 0xfff));
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 IValueT Rot = encodeRotation(Rotation); 1141 IValueT Rot = encodeRotation(Rotation);
1143 if (!Utils::IsUint(2, Rot)) 1142 if (!Utils::IsUint(2, Rot))
1144 llvm::report_fatal_error(std::string(InstName) + 1143 llvm::report_fatal_error(std::string(InstName) +
1145 ": Illegal rotation value"); 1144 ": Illegal rotation value");
1146 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | Opcode | 1145 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | Opcode |
1147 (Rn << kRnShift) | (Rd << kRdShift) | 1146 (Rn << kRnShift) | (Rd << kRdShift) |
1148 (Rot << kRotationShift) | B6 | B5 | B4 | (Rm << kRmShift); 1147 (Rot << kRotationShift) | B6 | B5 | B4 | (Rm << kRmShift);
1149 emitInst(Encoding); 1148 emitInst(Encoding);
1150 } 1149 }
1151 1150
1151 void AssemblerARM32::emitSIMDBase(IValueT Opcode, IValueT Dd, IValueT Dn,
1152 IValueT Dm, bool UseQRegs, bool IsFloatTy) {
1153 const IValueT Encoding =
1154 Opcode | B25 | (encodeCondition(CondARM32::kNone) << kConditionShift) |
1155 (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) |
1156 (getXXXXInRegYXXXX(Dd) << 12) | (IsFloatTy ? B10 : 0) |
1157 (getYInRegYXXXX(Dn) << 7) | (encodeBool(UseQRegs) << 6) |
1158 (getYInRegYXXXX(Dm) << 5) | getXXXXInRegYXXXX(Dm);
1159 emitInst(Encoding);
1160 }
1161
1152 void AssemblerARM32::emitSIMD(IValueT Opcode, Type ElmtTy, IValueT Dd, 1162 void AssemblerARM32::emitSIMD(IValueT Opcode, Type ElmtTy, IValueT Dd,
1153 IValueT Dn, IValueT Dm, bool UseQRegs) { 1163 IValueT Dn, IValueT Dm, bool UseQRegs) {
1154 IValueT Sz = encodeElmtType(ElmtTy); 1164 constexpr IValueT ElmtShift = 20;
1155 assert(Utils::IsUint(2, Sz)); 1165 const IValueT ElmtSize = encodeElmtType(ElmtTy);
1156 IValueT Encoding = 1166 assert(Utils::IsUint(2, ElmtSize));
1157 Opcode | B25 | (encodeCondition(CondARM32::kNone) << kConditionShift) | 1167 emitSIMDBase(Opcode | (ElmtSize << ElmtShift), Dd, Dn, Dm, UseQRegs,
1158 (Sz << 20) | (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) | 1168 isFloatingType(ElmtTy));
1159 (getXXXXInRegYXXXX(Dd) << 12) | (getYInRegYXXXX(Dn) << 7) | 1169 }
1160 (encodeBool(UseQRegs) << 6) | (getYInRegYXXXX(Dm) << 5) | 1170
1161 getXXXXInRegYXXXX(Dm); 1171 void AssemblerARM32::emitSIMDqqqBase(IValueT Opcode, const Operand *OpQd,
1162 emitInst(Encoding); 1172 const Operand *OpQn, const Operand *OpQm,
1173 bool IsFloatTy, const char *OpcodeName) {
1174 const IValueT Qd = encodeQRegister(OpQd, "Qd", OpcodeName);
1175 const IValueT Qn = encodeQRegister(OpQn, "Qn", OpcodeName);
1176 const IValueT Qm = encodeQRegister(OpQm, "Qm", OpcodeName);
1177 constexpr bool UseQRegs = true;
1178 emitSIMDBase(Opcode, mapQRegToDReg(Qd), mapQRegToDReg(Qn), mapQRegToDReg(Qm),
1179 UseQRegs, IsFloatTy);
1163 } 1180 }
1164 1181
1165 void AssemblerARM32::emitSIMDqqq(IValueT Opcode, Type ElmtTy, 1182 void AssemblerARM32::emitSIMDqqq(IValueT Opcode, Type ElmtTy,
1166 const Operand *OpQd, const Operand *OpQn, 1183 const Operand *OpQd, const Operand *OpQn,
1167 const Operand *OpQm, const char *OpcodeName) { 1184 const Operand *OpQm, const char *OpcodeName) {
1168 IValueT Qd = encodeQRegister(OpQd, "Qd", OpcodeName); 1185 constexpr IValueT ElmtShift = 20;
1169 IValueT Qn = encodeQRegister(OpQn, "Qn", OpcodeName); 1186 const IValueT ElmtSize = encodeElmtType(ElmtTy);
1170 IValueT Qm = encodeQRegister(OpQm, "Qm", OpcodeName); 1187 assert(Utils::IsUint(2, ElmtSize));
1171 constexpr bool UseQRegs = true; 1188 emitSIMDqqqBase(Opcode | (ElmtSize << ElmtShift), OpQd, OpQn, OpQm,
1172 emitSIMD(Opcode, ElmtTy, mapQRegToDReg(Qd), mapQRegToDReg(Qn), 1189 isFloatingType(ElmtTy), OpcodeName);
1173 mapQRegToDReg(Qm), UseQRegs);
1174 } 1190 }
1175 1191
1176 void AssemblerARM32::emitVFPddd(CondARM32::Cond Cond, IValueT Opcode, 1192 void AssemblerARM32::emitVFPddd(CondARM32::Cond Cond, IValueT Opcode,
1177 IValueT Dd, IValueT Dn, IValueT Dm) { 1193 IValueT Dd, IValueT Dn, IValueT Dm) {
1178 assert(Dd < RegARM32::getNumDRegs()); 1194 assert(Dd < RegARM32::getNumDRegs());
1179 assert(Dn < RegARM32::getNumDRegs()); 1195 assert(Dn < RegARM32::getNumDRegs());
1180 assert(Dm < RegARM32::getNumDRegs()); 1196 assert(Dm < RegARM32::getNumDRegs());
1181 assert(CondARM32::isDefined(Cond)); 1197 assert(CondARM32::isDefined(Cond));
1182 constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9 | B8; 1198 constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9 | B8;
1183 const IValueT Encoding = 1199 const IValueT Encoding =
(...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after
2242 emitVFPsss(Cond, VabssOpcode, Sd, S0, Sm); 2258 emitVFPsss(Cond, VabssOpcode, Sd, S0, Sm);
2243 } 2259 }
2244 2260
2245 void AssemblerARM32::vabsd(const Operand *OpDd, const Operand *OpDm, 2261 void AssemblerARM32::vabsd(const Operand *OpDd, const Operand *OpDm,
2246 CondARM32::Cond Cond) { 2262 CondARM32::Cond Cond) {
2247 // VABS - ARM section A8.8.280, encoding A2: 2263 // VABS - ARM section A8.8.280, encoding A2:
2248 // vabs<c>.f64 <Dd>, <Dm> 2264 // vabs<c>.f64 <Dd>, <Dm>
2249 // 2265 //
2250 // cccc11101D110000dddd101111M0mmmm where cccc=Cond, Ddddd=Dd, and Mmmmm=Dm. 2266 // cccc11101D110000dddd101111M0mmmm where cccc=Cond, Ddddd=Dd, and Mmmmm=Dm.
2251 constexpr const char *Vabsd = "vabsd"; 2267 constexpr const char *Vabsd = "vabsd";
2252 IValueT Dd = encodeDRegister(OpDd, "Dd", Vabsd); 2268 const IValueT Dd = encodeDRegister(OpDd, "Dd", Vabsd);
2253 IValueT Dm = encodeDRegister(OpDm, "Dm", Vabsd); 2269 const IValueT Dm = encodeDRegister(OpDm, "Dm", Vabsd);
2254 constexpr IValueT D0 = 0; 2270 constexpr IValueT D0 = 0;
2255 constexpr IValueT VabsdOpcode = B23 | B21 | B20 | B7 | B6; 2271 constexpr IValueT VabsdOpcode = B23 | B21 | B20 | B7 | B6;
2256 emitVFPddd(Cond, VabsdOpcode, Dd, D0, Dm); 2272 emitVFPddd(Cond, VabsdOpcode, Dd, D0, Dm);
2257 } 2273 }
2258 2274
2275 void AssemblerARM32::vabsq(const Operand *OpQd, const Operand *OpQm) {
2276 // VABS - ARM section A8.8.280, encoding A1:
2277 // vabs.<dt> <Qd>, <Qm>
2278 //
2279 // 111100111D11ss01ddd0f1101M0mmm0 where Dddd=OpQd, Mddd=OpQm, and
2280 // <dt> in {s8, s16, s32, f32} and ss is the encoding of <dt>.
2281 const Type ElmtTy = typeElementType(OpQd->getType());
2282 assert(ElmtTy != IceType_i64 && "vabsq doesn't allow i64!");
2283 constexpr const char *Vabsq = "vabsq";
2284 const IValueT Dd = mapQRegToDReg(encodeQRegister(OpQd, "Qd", Vabsq));
2285 const IValueT Dm = mapQRegToDReg(encodeQRegister(OpQm, "Qm", Vabsq));
2286 constexpr IValueT Dn = 0;
2287 const IValueT VabsqOpcode =
2288 B24 | B23 | B21 | B20 | B16 | B9 | B8 | (encodeElmtType(ElmtTy) << 18);
2289 constexpr bool UseQRegs = true;
2290 emitSIMDBase(VabsqOpcode, Dd, Dn, Dm, UseQRegs, isFloatingType(ElmtTy));
2291 }
2292
2259 void AssemblerARM32::vadds(const Operand *OpSd, const Operand *OpSn, 2293 void AssemblerARM32::vadds(const Operand *OpSd, const Operand *OpSn,
2260 const Operand *OpSm, CondARM32::Cond Cond) { 2294 const Operand *OpSm, CondARM32::Cond Cond) {
2261 // VADD (floating-point) - ARM section A8.8.283, encoding A2: 2295 // VADD (floating-point) - ARM section A8.8.283, encoding A2:
2262 // vadd<c>.f32 <Sd>, <Sn>, <Sm> 2296 // vadd<c>.f32 <Sd>, <Sn>, <Sm>
2263 // 2297 //
2264 // cccc11100D11nnnndddd101sN0M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn, 2298 // cccc11100D11nnnndddd101sN0M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn,
2265 // and mmmmM=Rm. 2299 // and mmmmM=Rm.
2266 constexpr const char *Vadds = "vadds"; 2300 constexpr const char *Vadds = "vadds";
2267 constexpr IValueT VaddsOpcode = B21 | B20; 2301 constexpr IValueT VaddsOpcode = B21 | B20;
2268 emitVFPsss(Cond, VaddsOpcode, OpSd, OpSn, OpSm, Vadds); 2302 emitVFPsss(Cond, VaddsOpcode, OpSd, OpSn, OpSm, Vadds);
2269 } 2303 }
2270 2304
2271 void AssemblerARM32::vaddqi(Type ElmtTy, const Operand *OpQd, 2305 void AssemblerARM32::vaddqi(Type ElmtTy, const Operand *OpQd,
2272 const Operand *OpQm, const Operand *OpQn) { 2306 const Operand *OpQm, const Operand *OpQn) {
2273 // VADD (integer) - ARM section A8.8.282, encoding A1: 2307 // VADD (integer) - ARM section A8.8.282, encoding A1:
2274 // vadd.<dt> <Qd>, <Qn>, <Qm> 2308 // vadd.<dt> <Qd>, <Qn>, <Qm>
2275 // 2309 //
2276 // 111100100Dssnnn0ddd01000N1M0mmm0 where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm, 2310 // 111100100Dssnnn0ddd01000N1M0mmm0 where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
2277 // and dt in [i8, i16, i32, i64] where ss is the index. 2311 // and dt in [i8, i16, i32, i64] where ss is the index.
2312 assert(isScalarIntegerType(ElmtTy) &&
2313 "vaddqi expects vector with integer element type");
2278 constexpr const char *Vaddqi = "vaddqi"; 2314 constexpr const char *Vaddqi = "vaddqi";
2279 constexpr IValueT VaddqiOpcode = B11; 2315 constexpr IValueT VaddqiOpcode = B11;
2280 emitSIMDqqq(VaddqiOpcode, ElmtTy, OpQd, OpQm, OpQn, Vaddqi); 2316 emitSIMDqqq(VaddqiOpcode, ElmtTy, OpQd, OpQm, OpQn, Vaddqi);
2281 } 2317 }
2282 2318
2283 void AssemblerARM32::vaddqf(const Operand *OpQd, const Operand *OpQn, 2319 void AssemblerARM32::vaddqf(const Operand *OpQd, const Operand *OpQn,
2284 const Operand *OpQm) { 2320 const Operand *OpQm) {
2285 // VADD (floating-point) - ARM section A8.8.283, Encoding A1: 2321 // VADD (floating-point) - ARM section A8.8.283, Encoding A1:
2286 // vadd.f32 <Qd>, <Qn>, <Qm> 2322 // vadd.f32 <Qd>, <Qn>, <Qm>
2287 // 2323 //
2288 // 111100100D00nnn0ddd01101N1M0mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm. 2324 // 111100100D00nnn0ddd01101N1M0mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
2325 assert(OpQd->getType() == IceType_v4f32 && "vaddqf expects type <4 x float>");
2289 constexpr const char *Vaddqf = "vaddqf"; 2326 constexpr const char *Vaddqf = "vaddqf";
2290 constexpr IValueT VaddqfOpcode = B11 | B10 | B8; 2327 constexpr IValueT VaddqfOpcode = B11 | B8;
2291 emitSIMDqqq(VaddqfOpcode, IceType_f32, OpQd, OpQn, OpQm, Vaddqf); 2328 constexpr bool IsFloatTy = true;
2329 emitSIMDqqqBase(VaddqfOpcode, OpQd, OpQn, OpQm, IsFloatTy, Vaddqf);
2292 } 2330 }
2293 2331
2294 void AssemblerARM32::vaddd(const Operand *OpDd, const Operand *OpDn, 2332 void AssemblerARM32::vaddd(const Operand *OpDd, const Operand *OpDn,
2295 const Operand *OpDm, CondARM32::Cond Cond) { 2333 const Operand *OpDm, CondARM32::Cond Cond) {
2296 // VADD (floating-point) - ARM section A8.8.283, encoding A2: 2334 // VADD (floating-point) - ARM section A8.8.283, encoding A2:
2297 // vadd<c>.f64 <Dd>, <Dn>, <Dm> 2335 // vadd<c>.f64 <Dd>, <Dn>, <Dm>
2298 // 2336 //
2299 // cccc11100D11nnnndddd101sN0M0mmmm where cccc=Cond, s=1, Ddddd=Rd, Nnnnn=Rn, 2337 // cccc11100D11nnnndddd101sN0M0mmmm where cccc=Cond, s=1, Ddddd=Rd, Nnnnn=Rn,
2300 // and Mmmmm=Rm. 2338 // and Mmmmm=Rm.
2301 constexpr const char *Vaddd = "vaddd"; 2339 constexpr const char *Vaddd = "vaddd";
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
2553 B25 | B24 | B8 | B4 | 2591 B25 | B24 | B8 | B4 |
2554 (encodeCondition(CondARM32::Cond::kNone) << kConditionShift) | 2592 (encodeCondition(CondARM32::Cond::kNone) << kConditionShift) |
2555 (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) | 2593 (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) |
2556 (getXXXXInRegYXXXX(Dd) << 12) | (getYInRegYXXXX(Dn) << 7) | 2594 (getXXXXInRegYXXXX(Dd) << 12) | (getYInRegYXXXX(Dn) << 7) |
2557 (getYInRegYXXXX(Dm) << 5) | getXXXXInRegYXXXX(Dm); 2595 (getYInRegYXXXX(Dm) << 5) | getXXXXInRegYXXXX(Dm);
2558 emitInst(Encoding); 2596 emitInst(Encoding);
2559 } 2597 }
2560 2598
2561 void AssemblerARM32::veorq(const Operand *OpQd, const Operand *OpQn, 2599 void AssemblerARM32::veorq(const Operand *OpQd, const Operand *OpQn,
2562 const Operand *OpQm) { 2600 const Operand *OpQm) {
2601 // VEOR - ARM section A8.8.316, encoding A1:
2602 // veor <Qd>, <Qn>, <Qm>
2603 //
2604 // 111100110D00nnn0ddd00001N1M1mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
2563 constexpr const char *Veorq = "veorq"; 2605 constexpr const char *Veorq = "veorq";
2564 constexpr IValueT VeorqOpcode = B24 | B8 | B4; 2606 constexpr IValueT VeorqOpcode = B24 | B8 | B4;
2565 emitSIMDqqq(VeorqOpcode, IceType_i8, OpQd, OpQn, OpQm, Veorq); 2607 emitSIMDqqq(VeorqOpcode, IceType_i8, OpQd, OpQn, OpQm, Veorq);
2566 } 2608 }
2567 2609
2568 void AssemblerARM32::vldrd(const Operand *OpDd, const Operand *OpAddress, 2610 void AssemblerARM32::vldrd(const Operand *OpDd, const Operand *OpAddress,
2569 CondARM32::Cond Cond, const TargetInfo &TInfo) { 2611 CondARM32::Cond Cond, const TargetInfo &TInfo) {
2570 // VLDR - ARM section A8.8.333, encoding A1. 2612 // VLDR - ARM section A8.8.333, encoding A1.
2571 // vldr<c> <Dd>, [<Rn>{, #+/-<imm>}] 2613 // vldr<c> <Dd>, [<Rn>{, #+/-<imm>}]
2572 // 2614 //
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
2930 emitVFPddd(Cond, VmuldOpcode, OpDd, OpDn, OpDm, Vmuld); 2972 emitVFPddd(Cond, VmuldOpcode, OpDd, OpDn, OpDm, Vmuld);
2931 } 2973 }
2932 2974
2933 void AssemblerARM32::vmulqi(Type ElmtTy, const Operand *OpQd, 2975 void AssemblerARM32::vmulqi(Type ElmtTy, const Operand *OpQd,
2934 const Operand *OpQn, const Operand *OpQm) { 2976 const Operand *OpQn, const Operand *OpQm) {
2935 // VMUL, VMULL (integer and polynomial) - ARM section A8.8.350, encoding A1: 2977 // VMUL, VMULL (integer and polynomial) - ARM section A8.8.350, encoding A1:
2936 // vmul<c>.<dt> <Qd>, <Qn>, <Qm> 2978 // vmul<c>.<dt> <Qd>, <Qn>, <Qm>
2937 // 2979 //
2938 // 111100100Dssnnn0ddd01001NqM1mmm0 where Dddd=Qd, Nnnn=Qn, Mmmm=Qm, and 2980 // 111100100Dssnnn0ddd01001NqM1mmm0 where Dddd=Qd, Nnnn=Qn, Mmmm=Qm, and
2939 // dt in [i8, i16, i32] where ss is the index. 2981 // dt in [i8, i16, i32] where ss is the index.
2982 assert(isScalarIntegerType(ElmtTy) &&
2983 "vmulqi expects vector with integer element type");
2940 assert(ElmtTy != IceType_i64 && "vmulqi on i64 vector not allowed"); 2984 assert(ElmtTy != IceType_i64 && "vmulqi on i64 vector not allowed");
2941 constexpr const char *Vmulqi = "vmulqi"; 2985 constexpr const char *Vmulqi = "vmulqi";
2942 constexpr IValueT VmulqiOpcode = B11 | B8 | B4; 2986 constexpr IValueT VmulqiOpcode = B11 | B8 | B4;
2943 emitSIMDqqq(VmulqiOpcode, ElmtTy, OpQd, OpQn, OpQm, Vmulqi); 2987 emitSIMDqqq(VmulqiOpcode, ElmtTy, OpQd, OpQn, OpQm, Vmulqi);
2944 } 2988 }
2945 2989
2946 void AssemblerARM32::vmulqf(const Operand *OpQd, const Operand *OpQn, 2990 void AssemblerARM32::vmulqf(const Operand *OpQd, const Operand *OpQn,
2947 const Operand *OpQm) { 2991 const Operand *OpQm) {
2948 // VMUL (floating-point) - ARM section A8.8.351, encoding A1: 2992 // VMUL (floating-point) - ARM section A8.8.351, encoding A1:
2949 // vmul.f32 <Qd>, <Qn>, <Qm> 2993 // vmul.f32 <Qd>, <Qn>, <Qm>
2950 // 2994 //
2951 // 111100110D00nnn0ddd01101MqM1mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm. 2995 // 111100110D00nnn0ddd01101MqM1mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
2996 assert(OpQd->getType() == IceType_v4f32 && "vmulqf expects type <4 x float>");
2952 constexpr const char *Vmulqf = "vmulqf"; 2997 constexpr const char *Vmulqf = "vmulqf";
2953 constexpr IValueT VmulqfOpcode = B24 | B11 | B10 | B8 | B4; 2998 constexpr IValueT VmulqfOpcode = B24 | B11 | B8 | B4;
2954 emitSIMDqqq(VmulqfOpcode, IceType_f32, OpQd, OpQn, OpQm, Vmulqf); 2999 constexpr bool IsFloatTy = true;
3000 emitSIMDqqqBase(VmulqfOpcode, OpQd, OpQn, OpQm, IsFloatTy, Vmulqf);
2955 } 3001 }
2956 3002
2957 void AssemblerARM32::vorrq(const Operand *OpQd, const Operand *OpQm, 3003 void AssemblerARM32::vorrq(const Operand *OpQd, const Operand *OpQm,
2958 const Operand *OpQn) { 3004 const Operand *OpQn) {
2959 // VORR (register) - ARM section A8.8.360, encoding A1: 3005 // VORR (register) - ARM section A8.8.360, encoding A1:
2960 // vorr <Qd>, <Qn>, <Qm> 3006 // vorr <Qd>, <Qn>, <Qm>
2961 // 3007 //
2962 // 111100100D10nnn0ddd00001N1M1mmm0 where Dddd=OpQd, Nnnn=OpQm, and Mmmm=OpQm. 3008 // 111100100D10nnn0ddd00001N1M1mmm0 where Dddd=OpQd, Nnnn=OpQm, and Mmmm=OpQm.
2963 constexpr const char *Vorrq = "vorrq"; 3009 constexpr const char *Vorrq = "vorrq";
2964 constexpr IValueT VorrqOpcode = B21 | B8 | B4; 3010 constexpr IValueT VorrqOpcode = B21 | B8 | B4;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
3055 emitVFPddd(Cond, VsubdOpcode, OpDd, OpDn, OpDm, Vsubd); 3101 emitVFPddd(Cond, VsubdOpcode, OpDd, OpDn, OpDm, Vsubd);
3056 } 3102 }
3057 3103
3058 void AssemblerARM32::vsubqi(Type ElmtTy, const Operand *OpQd, 3104 void AssemblerARM32::vsubqi(Type ElmtTy, const Operand *OpQd,
3059 const Operand *OpQm, const Operand *OpQn) { 3105 const Operand *OpQm, const Operand *OpQn) {
3060 // VSUB (integer) - ARM section A8.8.414, encoding A1: 3106 // VSUB (integer) - ARM section A8.8.414, encoding A1:
3061 // vsub.<dt> <Qd>, <Qn>, <Qm> 3107 // vsub.<dt> <Qd>, <Qn>, <Qm>
3062 // 3108 //
3063 // 111100110Dssnnn0ddd01000N1M0mmm0 where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm, 3109 // 111100110Dssnnn0ddd01000N1M0mmm0 where Dddd=OpQd, Nnnn=OpQm, Mmmm=OpQm,
3064 // and dt in [i8, i16, i32, i64] where ss is the index. 3110 // and dt in [i8, i16, i32, i64] where ss is the index.
3111 assert(isScalarIntegerType(ElmtTy) &&
3112 "vsubqi expects vector with integer element type");
3065 constexpr const char *Vsubqi = "vsubqi"; 3113 constexpr const char *Vsubqi = "vsubqi";
3066 constexpr IValueT VsubqiOpcode = B24 | B11; 3114 constexpr IValueT VsubqiOpcode = B24 | B11;
3067 emitSIMDqqq(VsubqiOpcode, ElmtTy, OpQd, OpQm, OpQn, Vsubqi); 3115 emitSIMDqqq(VsubqiOpcode, ElmtTy, OpQd, OpQm, OpQn, Vsubqi);
3068 } 3116 }
3069 3117
3070 void AssemblerARM32::vsubqf(const Operand *OpQd, const Operand *OpQn, 3118 void AssemblerARM32::vsubqf(const Operand *OpQd, const Operand *OpQn,
3071 const Operand *OpQm) { 3119 const Operand *OpQm) {
3072 // VSUB (floating-point) - ARM section A8.8.415, Encoding A1: 3120 // VSUB (floating-point) - ARM section A8.8.415, Encoding A1:
3073 // vsub.f32 <Qd>, <Qn>, <Qm> 3121 // vsub.f32 <Qd>, <Qn>, <Qm>
3074 // 3122 //
3075 // 111100100D10nnn0ddd01101N1M0mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm. 3123 // 111100100D10nnn0ddd01101N1M0mmm0 where Dddd=Qd, Nnnn=Qn, and Mmmm=Qm.
3124 assert(OpQd->getType() == IceType_v4f32 && "vsubqf expects type <4 x float>");
3076 constexpr const char *Vsubqf = "vsubqf"; 3125 constexpr const char *Vsubqf = "vsubqf";
3077 constexpr IValueT VsubqfOpcode = B21 | B11 | B10 | B8; 3126 constexpr IValueT VsubqfOpcode = B21 | B11 | B8;
3078 emitSIMDqqq(VsubqfOpcode, IceType_f32, OpQd, OpQn, OpQm, Vsubqf); 3127 emitSIMDqqq(VsubqfOpcode, IceType_f32, OpQd, OpQn, OpQm, Vsubqf);
3079 } 3128 }
3080 3129
3081 void AssemblerARM32::emitVStackOp(CondARM32::Cond Cond, IValueT Opcode, 3130 void AssemblerARM32::emitVStackOp(CondARM32::Cond Cond, IValueT Opcode,
3082 const Variable *OpBaseReg, 3131 const Variable *OpBaseReg,
3083 SizeT NumConsecRegs) { 3132 SizeT NumConsecRegs) {
3084 const IValueT BaseReg = getEncodedSRegNum(OpBaseReg); 3133 const IValueT BaseReg = getEncodedSRegNum(OpBaseReg);
3085 const IValueT DLastBit = mask(BaseReg, 0, 1); // Last bit of base register. 3134 const IValueT DLastBit = mask(BaseReg, 0, 1); // Last bit of base register.
3086 const IValueT Rd = mask(BaseReg, 1, 4); // Top 4 bits of base register. 3135 const IValueT Rd = mask(BaseReg, 1, 4); // Top 4 bits of base register.
3087 assert(0 < NumConsecRegs); 3136 assert(0 < NumConsecRegs);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3147 constexpr const char *Vsqrts = "vsqrts"; 3196 constexpr const char *Vsqrts = "vsqrts";
3148 IValueT Sd = encodeSRegister(OpSd, "Sd", Vsqrts); 3197 IValueT Sd = encodeSRegister(OpSd, "Sd", Vsqrts);
3149 IValueT Sm = encodeSRegister(OpSm, "Sm", Vsqrts); 3198 IValueT Sm = encodeSRegister(OpSm, "Sm", Vsqrts);
3150 constexpr IValueT VsqrtsOpcode = B23 | B21 | B20 | B16 | B7 | B6; 3199 constexpr IValueT VsqrtsOpcode = B23 | B21 | B20 | B16 | B7 | B6;
3151 constexpr IValueT S0 = 0; 3200 constexpr IValueT S0 = 0;
3152 emitVFPsss(Cond, VsqrtsOpcode, Sd, S0, Sm); 3201 emitVFPsss(Cond, VsqrtsOpcode, Sd, S0, Sm);
3153 } 3202 }
3154 3203
3155 } // end of namespace ARM32 3204 } // end of namespace ARM32
3156 } // end of namespace Ice 3205 } // end of namespace Ice
OLDNEW
« 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