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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1878943009: Subzero. ARM32. Vector casts. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Adds vcvt assembler lit tests. Created 4 years, 8 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
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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 217
218 // Figures out Op/Cmode values for given Value. Returns true if able to encode. 218 // Figures out Op/Cmode values for given Value. Returns true if able to encode.
219 bool encodeAdvSIMDExpandImm(IValueT Value, Type ElmtTy, IValueT &Op, 219 bool encodeAdvSIMDExpandImm(IValueT Value, Type ElmtTy, IValueT &Op,
220 IValueT &Cmode, IValueT &Imm8) { 220 IValueT &Cmode, IValueT &Imm8) {
221 // TODO(kschimpf): Handle other shifted 8-bit values. 221 // TODO(kschimpf): Handle other shifted 8-bit values.
222 constexpr IValueT Imm8Mask = 0xFF; 222 constexpr IValueT Imm8Mask = 0xFF;
223 if ((Value & IValueT(~Imm8Mask)) != 0) 223 if ((Value & IValueT(~Imm8Mask)) != 0)
224 return false; 224 return false;
225 Imm8 = Value; 225 Imm8 = Value;
226 switch (ElmtTy) { 226 switch (ElmtTy) {
227 case IceType_i8:
228 Op = 0;
229 Cmode = 14; // 0b1110
230 return true;
227 case IceType_i16: 231 case IceType_i16:
228 Op = 0; 232 Op = 0;
229 Cmode = 8; // 100:0 233 Cmode = 8; // 0b1000
230 return true; 234 return true;
231 case IceType_i32: 235 case IceType_i32:
232 Op = 0; 236 Op = 0;
233 Cmode = 0; // 000:0 237 Cmode = 0; // 0b0000
234 return true; 238 return true;
235 default: 239 default:
236 return false; 240 return false;
237 } 241 }
238 } 242 }
239 243
240 // Defines layouts of an operand representing a (register) memory address, 244 // Defines layouts of an operand representing a (register) memory address,
241 // possibly modified by an immediate value. 245 // possibly modified by an immediate value.
242 enum EncodedImmAddress { 246 enum EncodedImmAddress {
243 // Address modified by a rotated immediate 8-bit value. 247 // Address modified by a rotated immediate 8-bit value.
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after
1208 void AssemblerARM32::emitSIMDqqq(IValueT Opcode, Type ElmtTy, 1212 void AssemblerARM32::emitSIMDqqq(IValueT Opcode, Type ElmtTy,
1209 const Operand *OpQd, const Operand *OpQn, 1213 const Operand *OpQd, const Operand *OpQn,
1210 const Operand *OpQm, const char *OpcodeName) { 1214 const Operand *OpQm, const char *OpcodeName) {
1211 constexpr IValueT ElmtShift = 20; 1215 constexpr IValueT ElmtShift = 20;
1212 const IValueT ElmtSize = encodeElmtType(ElmtTy); 1216 const IValueT ElmtSize = encodeElmtType(ElmtTy);
1213 assert(Utils::IsUint(2, ElmtSize)); 1217 assert(Utils::IsUint(2, ElmtSize));
1214 emitSIMDqqqBase(Opcode | (ElmtSize << ElmtShift), OpQd, OpQn, OpQm, 1218 emitSIMDqqqBase(Opcode | (ElmtSize << ElmtShift), OpQd, OpQn, OpQm,
1215 isFloatingType(ElmtTy), OpcodeName); 1219 isFloatingType(ElmtTy), OpcodeName);
1216 } 1220 }
1217 1221
1222 void AssemblerARM32::emitSIMDShiftqqc(IValueT Opcode, const Operand *OpQd,
1223 const Operand *OpQm, const IValueT Imm6,
1224 const char *OpcodeName) {
1225 const IValueT Qd = encodeQRegister(OpQd, "Qd", OpcodeName);
1226 const IValueT Qn = 0;
1227 const IValueT Qm = encodeQRegister(OpQm, "Qm", OpcodeName);
1228 constexpr bool UseQRegs = true;
1229 constexpr bool IsFloatTy = false;
1230 constexpr IValueT ElmtShift = 16;
1231 emitSIMDBase(Opcode | (Imm6 << ElmtShift), mapQRegToDReg(Qd),
1232 mapQRegToDReg(Qn), mapQRegToDReg(Qm), UseQRegs, IsFloatTy);
1233 }
1234
1235 void AssemblerARM32::emitSIMDCvtqq(IValueT Opcode, const Operand *OpQd,
1236 const Operand *OpQm,
1237 const char *OpcodeName) {
1238 const IValueT SIMDOpcode =
1239 B24 | B23 | B21 | B20 | B19 | B17 | B16 | B10 | B9 | Opcode;
1240 constexpr bool UseQRegs = true;
1241 constexpr bool IsFloatTy = false;
1242 const IValueT Qd = encodeQRegister(OpQd, "Qd", OpcodeName);
1243 constexpr IValueT Qn = 0;
1244 const IValueT Qm = encodeQRegister(OpQm, "Qm", OpcodeName);
1245 emitSIMDBase(SIMDOpcode, mapQRegToDReg(Qd), mapQRegToDReg(Qn),
1246 mapQRegToDReg(Qm), UseQRegs, IsFloatTy);
1247 }
1248
1218 void AssemblerARM32::emitVFPddd(CondARM32::Cond Cond, IValueT Opcode, 1249 void AssemblerARM32::emitVFPddd(CondARM32::Cond Cond, IValueT Opcode,
1219 IValueT Dd, IValueT Dn, IValueT Dm) { 1250 IValueT Dd, IValueT Dn, IValueT Dm) {
1220 assert(Dd < RegARM32::getNumDRegs()); 1251 assert(Dd < RegARM32::getNumDRegs());
1221 assert(Dn < RegARM32::getNumDRegs()); 1252 assert(Dn < RegARM32::getNumDRegs());
1222 assert(Dm < RegARM32::getNumDRegs()); 1253 assert(Dm < RegARM32::getNumDRegs());
1223 assert(CondARM32::isDefined(Cond)); 1254 assert(CondARM32::isDefined(Cond));
1224 constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9 | B8; 1255 constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9 | B8;
1225 const IValueT Encoding = 1256 const IValueT Encoding =
1226 Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) | 1257 Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) |
1227 (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) | 1258 (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dn) << 16) |
(...skipping 1322 matching lines...) Expand 10 before | Expand all | Expand 10 after
2550 // 2581 //
2551 // cccc11101D111100dddd10011M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm. 2582 // cccc11101D111100dddd10011M0mmmm where cccc=Cond, ddddD=Sd, and mmmmM=Sm.
2552 constexpr const char *Vcvtus = "vcvtus"; 2583 constexpr const char *Vcvtus = "vcvtus";
2553 IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtus); 2584 IValueT Sd = encodeSRegister(OpSd, "Sd", Vcvtus);
2554 IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtus); 2585 IValueT Sm = encodeSRegister(OpSm, "Sm", Vcvtus);
2555 constexpr IValueT VcvtsiOpcode = B23 | B21 | B20 | B19 | B18 | B7 | B6; 2586 constexpr IValueT VcvtsiOpcode = B23 | B21 | B20 | B19 | B18 | B7 | B6;
2556 constexpr IValueT S0 = 0; 2587 constexpr IValueT S0 = 0;
2557 emitVFPsss(Cond, VcvtsiOpcode, Sd, S0, Sm); 2588 emitVFPsss(Cond, VcvtsiOpcode, Sd, S0, Sm);
2558 } 2589 }
2559 2590
2591 void AssemblerARM32::vcvtqsi(const Operand *OpQd, const Operand *OpQm) {
2592 // VCVT (between floating-point and integer, Advanced SIMD)
2593 // - ARM Section A8.8.305, encoding A1:
2594 // vcvt<c>.f32.s32 <Qd>, <Qm>
2595 //
2596 // 111100111D11ss11dddd011ooQM0mmmm where Ddddd=Qd, Mmmmm=Qm, and 10=op.
2597 constexpr const char *Vcvtqsi = "vcvt.s32.f32";
2598 constexpr IValueT VcvtqsiOpcode = B8;
2599 emitSIMDCvtqq(VcvtqsiOpcode, OpQd, OpQm, Vcvtqsi);
2600 }
2601
2602 void AssemblerARM32::vcvtqsu(const Operand *OpQd, const Operand *OpQm) {
2603 // VCVT (between floating-point and integer, Advanced SIMD)
2604 // - ARM Section A8.8.305, encoding A1:
2605 // vcvt<c>.f32.u32 <Qd>, <Qm>
2606 //
2607 // 111100111D11ss11dddd011ooQM0mmmm where Ddddd=Qd, Mmmmm=Qm, and 11=op.
2608 constexpr const char *Vcvtqsu = "vcvt.u32.f32";
2609 constexpr IValueT VcvtqsuOpcode = B8 | B7;
2610 emitSIMDCvtqq(VcvtqsuOpcode, OpQd, OpQm, Vcvtqsu);
2611 }
2612
2613 void AssemblerARM32::vcvtqis(const Operand *OpQd, const Operand *OpQm) {
2614 // VCVT (between floating-point and integer, Advanced SIMD)
2615 // - ARM Section A8.8.305, encoding A1:
2616 // vcvt<c>.f32.s32 <Qd>, <Qm>
2617 //
2618 // 111100111D11ss11dddd011ooQM0mmmm where Ddddd=Qd, Mmmmm=Qm, and 01=op.
2619 constexpr const char *Vcvtqis = "vcvt.f32.s32";
2620 constexpr IValueT VcvtqisOpcode = 0;
2621 emitSIMDCvtqq(VcvtqisOpcode, OpQd, OpQm, Vcvtqis);
2622 }
2623
2624 void AssemblerARM32::vcvtqus(const Operand *OpQd, const Operand *OpQm) {
2625 // VCVT (between floating-point and integer, Advanced SIMD)
2626 // - ARM Section A8.8.305, encoding A1:
2627 // vcvt<c>.f32.u32 <Qd>, <Qm>
2628 //
2629 // 111100111D11ss11dddd011ooQM0mmmm where Ddddd=Qd, Mmmmm=Qm, and 01=op.
2630 constexpr const char *Vcvtqus = "vcvt.f32.u32";
2631 constexpr IValueT VcvtqusOpcode = B7;
2632 emitSIMDCvtqq(VcvtqusOpcode, OpQd, OpQm, Vcvtqus);
2633 }
2634
2560 void AssemblerARM32::emitVFPds(CondARM32::Cond Cond, IValueT Opcode, IValueT Dd, 2635 void AssemblerARM32::emitVFPds(CondARM32::Cond Cond, IValueT Opcode, IValueT Dd,
2561 IValueT Sm) { 2636 IValueT Sm) {
2562 assert(Dd < RegARM32::getNumDRegs()); 2637 assert(Dd < RegARM32::getNumDRegs());
2563 assert(Sm < RegARM32::getNumSRegs()); 2638 assert(Sm < RegARM32::getNumSRegs());
2564 assert(CondARM32::isDefined(Cond)); 2639 assert(CondARM32::isDefined(Cond));
2565 constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9; 2640 constexpr IValueT VFPOpcode = B27 | B26 | B25 | B11 | B9;
2566 const IValueT Encoding = 2641 const IValueT Encoding =
2567 Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) | 2642 Opcode | VFPOpcode | (encodeCondition(Cond) << kConditionShift) |
2568 (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dd) << 12) | 2643 (getYInRegYXXXX(Dd) << 22) | (getXXXXInRegYXXXX(Dd) << 12) |
2569 (getYInRegXXXXY(Sm) << 5) | getXXXXInRegXXXXY(Sm); 2644 (getYInRegXXXXY(Sm) << 5) | getXXXXInRegXXXXY(Sm);
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
3260 // 3335 //
3261 // 1111001U0Dssnnnndddd0100NQM0mmmm where Ddddd=Qd, Mmmmm=Qm, Nnnnn=Qn, 0=U, 3336 // 1111001U0Dssnnnndddd0100NQM0mmmm where Ddddd=Qd, Mmmmm=Qm, Nnnnn=Qn, 0=U,
3262 // 1=Q 3337 // 1=Q
3263 assert(isScalarIntegerType(ElmtTy) && 3338 assert(isScalarIntegerType(ElmtTy) &&
3264 "vshl expects vector with integer element type"); 3339 "vshl expects vector with integer element type");
3265 constexpr const char *Vshl = "vshl"; 3340 constexpr const char *Vshl = "vshl";
3266 constexpr IValueT VshlOpcode = B10 | B6; 3341 constexpr IValueT VshlOpcode = B10 | B6;
3267 emitSIMDqqq(VshlOpcode, ElmtTy, OpQd, OpQn, OpQm, Vshl); 3342 emitSIMDqqq(VshlOpcode, ElmtTy, OpQd, OpQn, OpQm, Vshl);
3268 } 3343 }
3269 3344
3345 namespace {
3346 enum SIMDShiftType { ST_Vshl, ST_Vshr };
3347 IValueT encodeSIMDShiftImm6(SIMDShiftType Shift, Type ElmtTy,
3348 const ConstantInteger32 *Imm6) {
3349 const IValueT Imm = Imm6->getValue();
3350 assert(Imm > 0);
3351 const SizeT MaxShift = getScalarIntBitWidth(ElmtTy);
3352 assert(Imm < MaxShift);
3353 assert(ElmtTy == IceType_i8 || ElmtTy == IceType_i16 ||
3354 ElmtTy == IceType_i32);
3355 const IValueT VshlImm = Imm - MaxShift;
3356 const IValueT VshrImm = 2 * MaxShift - Imm;
3357 return ((Shift == ST_Vshl) ? VshlImm : VshrImm) & (2 * MaxShift - 1);
3358 }
3359 } // end of anonymous namespace
3360
3361 void AssemblerARM32::vshlqc(Type ElmtTy, const Operand *OpQd,
3362 const Operand *OpQm,
3363 const ConstantInteger32 *Imm6) {
3364 // VSHL - ARM section A8.8.395, encoding A1:
3365 // vshl Qd, Qm, #Imm
3366 //
3367 // 1111001U1Diiiiiidddd0101LQM1mmmm where Ddddd=Qd, Mmmmm=Qm, iiiiii=Imm6,
3368 // 0=U, 1=Q, 0=L.
3369 assert(isScalarIntegerType(ElmtTy) &&
3370 "vshl expects vector with integer element type");
3371 constexpr const char *Vshl = "vshl";
3372 constexpr IValueT VshlOpcode = B23 | B10 | B8 | B4;
3373 emitSIMDShiftqqc(VshlOpcode, OpQd, OpQm,
3374 encodeSIMDShiftImm6(ST_Vshl, ElmtTy, Imm6), Vshl);
3375 }
3376
3377 void AssemblerARM32::vshrqic(Type ElmtTy, const Operand *OpQd,
3378 const Operand *OpQm,
3379 const ConstantInteger32 *Imm6) {
3380 // VSHR - ARM section A8.8.398, encoding A1:
3381 // vshr Qd, Qm, #Imm
3382 //
3383 // 1111001U1Diiiiiidddd0101LQM1mmmm where Ddddd=Qd, Mmmmm=Qm, iiiiii=Imm6,
3384 // 0=U, 1=Q, 0=L.
3385 assert(isScalarIntegerType(ElmtTy) &&
3386 "vshr expects vector with integer element type");
3387 constexpr const char *Vshr = "vshr";
3388 constexpr IValueT VshrOpcode = B23 | B4;
3389 emitSIMDShiftqqc(VshrOpcode, OpQd, OpQm,
3390 encodeSIMDShiftImm6(ST_Vshr, ElmtTy, Imm6), Vshr);
3391 }
3392
3393 void AssemblerARM32::vshrquc(Type ElmtTy, const Operand *OpQd,
3394 const Operand *OpQm,
3395 const ConstantInteger32 *Imm6) {
3396 // VSHR - ARM section A8.8.398, encoding A1:
3397 // vshr Qd, Qm, #Imm
3398 //
3399 // 1111001U1Diiiiiidddd0101LQM1mmmm where Ddddd=Qd, Mmmmm=Qm, iiiiii=Imm6,
3400 // 0=U, 1=Q, 0=L.
3401 assert(isScalarIntegerType(ElmtTy) &&
3402 "vshr expects vector with integer element type");
3403 constexpr const char *Vshr = "vshr";
3404 constexpr IValueT VshrOpcode = B23 | B4;
3405 emitSIMDShiftqqc(VshrOpcode, OpQd, OpQm,
3406 encodeSIMDShiftImm6(ST_Vshr, ElmtTy, Imm6), Vshr);
3407 }
3408
3270 void AssemblerARM32::vshlqu(Type ElmtTy, const Operand *OpQd, 3409 void AssemblerARM32::vshlqu(Type ElmtTy, const Operand *OpQd,
3271 const Operand *OpQm, const Operand *OpQn) { 3410 const Operand *OpQm, const Operand *OpQn) {
3272 // VSHL - ARM section A8.8.396, encoding A1: 3411 // VSHL - ARM section A8.8.396, encoding A1:
3273 // vshl Qd, Qm, Qn 3412 // vshl Qd, Qm, Qn
3274 // 3413 //
3275 // 1111001U0Dssnnnndddd0100NQM0mmmm where Ddddd=Qd, Mmmmm=Qm, Nnnnn=Qn, 1=U, 3414 // 1111001U0Dssnnnndddd0100NQM0mmmm where Ddddd=Qd, Mmmmm=Qm, Nnnnn=Qn, 1=U,
3276 // 1=Q 3415 // 1=Q
3277 assert(isScalarIntegerType(ElmtTy) && 3416 assert(isScalarIntegerType(ElmtTy) &&
3278 "vshl expects vector with integer element type"); 3417 "vshl expects vector with integer element type");
3279 constexpr const char *Vshl = "vshl"; 3418 constexpr const char *Vshl = "vshl";
(...skipping 24 matching lines...) Expand all
3304 constexpr const char *Vsqrts = "vsqrts"; 3443 constexpr const char *Vsqrts = "vsqrts";
3305 IValueT Sd = encodeSRegister(OpSd, "Sd", Vsqrts); 3444 IValueT Sd = encodeSRegister(OpSd, "Sd", Vsqrts);
3306 IValueT Sm = encodeSRegister(OpSm, "Sm", Vsqrts); 3445 IValueT Sm = encodeSRegister(OpSm, "Sm", Vsqrts);
3307 constexpr IValueT VsqrtsOpcode = B23 | B21 | B20 | B16 | B7 | B6; 3446 constexpr IValueT VsqrtsOpcode = B23 | B21 | B20 | B16 | B7 | B6;
3308 constexpr IValueT S0 = 0; 3447 constexpr IValueT S0 = 0;
3309 emitVFPsss(Cond, VsqrtsOpcode, Sd, S0, Sm); 3448 emitVFPsss(Cond, VsqrtsOpcode, Sd, S0, Sm);
3310 } 3449 }
3311 3450
3312 } // end of namespace ARM32 3451 } // end of namespace ARM32
3313 } // end of namespace Ice 3452 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698