| OLD | NEW |
| 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 2504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2515 encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address); | 2515 encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address); |
| 2516 (void)AddressEncoding; | 2516 (void)AddressEncoding; |
| 2517 assert(AddressEncoding == EncodedAsImmRegOffset); | 2517 assert(AddressEncoding == EncodedAsImmRegOffset); |
| 2518 IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | | 2518 IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | |
| 2519 (encodeCondition(Cond) << kConditionShift) | | 2519 (encodeCondition(Cond) << kConditionShift) | |
| 2520 (getYInRegXXXXY(Sd) << 22) | | 2520 (getYInRegXXXXY(Sd) << 22) | |
| 2521 (getXXXXInRegXXXXY(Sd) << 12) | Address; | 2521 (getXXXXInRegXXXXY(Sd) << 12) | Address; |
| 2522 emitInst(Encoding); | 2522 emitInst(Encoding); |
| 2523 } | 2523 } |
| 2524 | 2524 |
| 2525 void AssemblerARM32::emitVMem1Op(IValueT Opcode, IValueT Dd, IValueT Rn, |
| 2526 IValueT Rm, DRegListSize NumDRegs, |
| 2527 size_t ElmtSize, IValueT Align, |
| 2528 const char *InstName) { |
| 2529 assert(Utils::IsAbsoluteUint(2, Align)); |
| 2530 IValueT EncodedElmtSize; |
| 2531 switch (ElmtSize) { |
| 2532 default: { |
| 2533 std::string Buffer; |
| 2534 llvm::raw_string_ostream StrBuf(Buffer); |
| 2535 StrBuf << InstName << ": found invalid vector element size " << ElmtSize; |
| 2536 llvm::report_fatal_error(StrBuf.str()); |
| 2537 } |
| 2538 case 8: |
| 2539 EncodedElmtSize = 0; |
| 2540 break; |
| 2541 case 16: |
| 2542 EncodedElmtSize = 1; |
| 2543 break; |
| 2544 case 32: |
| 2545 EncodedElmtSize = 2; |
| 2546 break; |
| 2547 case 64: |
| 2548 EncodedElmtSize = 3; |
| 2549 } |
| 2550 const IValueT Encoding = |
| 2551 Opcode | (encodeCondition(CondARM32::kNone) << kConditionShift) | |
| 2552 (getYInRegYXXXX(Dd) << 22) | (Rn << kRnShift) | |
| 2553 (getXXXXInRegYXXXX(Dd) << kRdShift) | (NumDRegs << 8) | |
| 2554 (EncodedElmtSize << 6) | (Align << 4) | Rm; |
| 2555 emitInst(Encoding); |
| 2556 } |
| 2557 |
| 2558 void AssemblerARM32::vld1qr(size_t ElmtSize, const Operand *OpQd, |
| 2559 const Operand *OpAddress, const TargetInfo &TInfo) { |
| 2560 // VLD1 (multiple single elements) - ARM section A8.8.320, encoding A1: |
| 2561 // vld1.<size> <Qd>, [<Rn>] |
| 2562 // |
| 2563 // 111101000D10nnnnddd0ttttssaammmm where tttt=DRegListSize2, Dddd=Qd, |
| 2564 // nnnn=Rn, aa=0 (use default alignment), size=ElmtSize, and ss is the |
| 2565 // encoding of ElmtSize. |
| 2566 constexpr const char *Vld1qr = "vld1qr"; |
| 2567 const IValueT Qd = encodeQRegister(OpQd, "Qd", Vld1qr); |
| 2568 const IValueT Dd = mapQRegToDReg(Qd); |
| 2569 IValueT Address; |
| 2570 if (encodeAddress(OpAddress, Address, TInfo, NoImmOffsetAddress) != |
| 2571 EncodedAsImmRegOffset) |
| 2572 llvm::report_fatal_error(std::string(Vld1qr) + ": malform memory address"); |
| 2573 const IValueT Rn = mask(Address, kRnShift, 4); |
| 2574 constexpr IValueT Rm = RegARM32::Reg_pc; |
| 2575 constexpr IValueT Opcode = B26 | B21; |
| 2576 constexpr IValueT Align = 0; // use default alignment. |
| 2577 emitVMem1Op(Opcode, Dd, Rn, Rm, DRegListSize2, ElmtSize, Align, Vld1qr); |
| 2578 } |
| 2579 |
| 2525 void AssemblerARM32::vmovd(const Operand *OpDd, | 2580 void AssemblerARM32::vmovd(const Operand *OpDd, |
| 2526 const OperandARM32FlexFpImm *OpFpImm, | 2581 const OperandARM32FlexFpImm *OpFpImm, |
| 2527 CondARM32::Cond Cond) { | 2582 CondARM32::Cond Cond) { |
| 2528 // VMOV (immediate) - ARM section A8.8.339, encoding A2: | 2583 // VMOV (immediate) - ARM section A8.8.339, encoding A2: |
| 2529 // vmov<c>.f64 <Dd>, #<imm> | 2584 // vmov<c>.f64 <Dd>, #<imm> |
| 2530 // | 2585 // |
| 2531 // cccc11101D11xxxxdddd10110000yyyy where cccc=Cond, ddddD=Sn, xxxxyyyy=imm. | 2586 // cccc11101D11xxxxdddd10110000yyyy where cccc=Cond, ddddD=Sn, xxxxyyyy=imm. |
| 2532 constexpr const char *Vmovd = "vmovd"; | 2587 constexpr const char *Vmovd = "vmovd"; |
| 2533 IValueT Dd = encodeSRegister(OpDd, "Dd", Vmovd); | 2588 IValueT Dd = encodeSRegister(OpDd, "Dd", Vmovd); |
| 2534 IValueT Imm8 = OpFpImm->getModifiedImm(); | 2589 IValueT Imm8 = OpFpImm->getModifiedImm(); |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2829 IValueT AddressEncoding = | 2884 IValueT AddressEncoding = |
| 2830 encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address); | 2885 encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address); |
| 2831 (void)AddressEncoding; | 2886 (void)AddressEncoding; |
| 2832 assert(AddressEncoding == EncodedAsImmRegOffset); | 2887 assert(AddressEncoding == EncodedAsImmRegOffset); |
| 2833 IValueT Encoding = | 2888 IValueT Encoding = |
| 2834 B27 | B26 | B24 | B11 | B9 | (encodeCondition(Cond) << kConditionShift) | | 2889 B27 | B26 | B24 | B11 | B9 | (encodeCondition(Cond) << kConditionShift) | |
| 2835 (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sd) << 12) | Address; | 2890 (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sd) << 12) | Address; |
| 2836 emitInst(Encoding); | 2891 emitInst(Encoding); |
| 2837 } | 2892 } |
| 2838 | 2893 |
| 2894 void AssemblerARM32::vst1qr(size_t ElmtSize, const Operand *OpQd, |
| 2895 const Operand *OpAddress, const TargetInfo &TInfo) { |
| 2896 // VST1 (multiple single elements) - ARM section A8.8.404, encoding A1: |
| 2897 // vst1.<size> <Qd>, [<Rn>] |
| 2898 // |
| 2899 // 111101000D00nnnnddd0ttttssaammmm where tttt=DRegListSize2, Dddd=Qd, |
| 2900 // nnnn=Rn, aa=0 (use default alignment), size=ElmtSize, and ss is the |
| 2901 // encoding of ElmtSize. |
| 2902 constexpr const char *Vst1qr = "vst1qr"; |
| 2903 const IValueT Qd = encodeQRegister(OpQd, "Qd", Vst1qr); |
| 2904 const IValueT Dd = mapQRegToDReg(Qd); |
| 2905 IValueT Address; |
| 2906 if (encodeAddress(OpAddress, Address, TInfo, NoImmOffsetAddress) != |
| 2907 EncodedAsImmRegOffset) |
| 2908 llvm::report_fatal_error(std::string(Vst1qr) + ": malform memory address"); |
| 2909 const IValueT Rn = mask(Address, kRnShift, 4); |
| 2910 constexpr IValueT Rm = RegARM32::Reg_pc; |
| 2911 constexpr IValueT Opcode = B26; |
| 2912 constexpr IValueT Align = 0; // use default alignment. |
| 2913 emitVMem1Op(Opcode, Dd, Rn, Rm, DRegListSize2, ElmtSize, Align, Vst1qr); |
| 2914 } |
| 2915 |
| 2839 void AssemblerARM32::vsubs(const Operand *OpSd, const Operand *OpSn, | 2916 void AssemblerARM32::vsubs(const Operand *OpSd, const Operand *OpSn, |
| 2840 const Operand *OpSm, CondARM32::Cond Cond) { | 2917 const Operand *OpSm, CondARM32::Cond Cond) { |
| 2841 // VSUB (floating-point) - ARM section A8.8.415, encoding A2: | 2918 // VSUB (floating-point) - ARM section A8.8.415, encoding A2: |
| 2842 // vsub<c>.f32 <Sd>, <Sn>, <Sm> | 2919 // vsub<c>.f32 <Sd>, <Sn>, <Sm> |
| 2843 // | 2920 // |
| 2844 // cccc11100D11nnnndddd101sN1M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn, | 2921 // cccc11100D11nnnndddd101sN1M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn, |
| 2845 // and mmmmM=Rm. | 2922 // and mmmmM=Rm. |
| 2846 constexpr const char *Vsubs = "vsubs"; | 2923 constexpr const char *Vsubs = "vsubs"; |
| 2847 constexpr IValueT VsubsOpcode = B21 | B20 | B6; | 2924 constexpr IValueT VsubsOpcode = B21 | B20 | B6; |
| 2848 emitVFPsss(Cond, VsubsOpcode, OpSd, OpSn, OpSm, Vsubs); | 2925 emitVFPsss(Cond, VsubsOpcode, OpSd, OpSn, OpSm, Vsubs); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2952 constexpr const char *Vsqrts = "vsqrts"; | 3029 constexpr const char *Vsqrts = "vsqrts"; |
| 2953 IValueT Sd = encodeSRegister(OpSd, "Sd", Vsqrts); | 3030 IValueT Sd = encodeSRegister(OpSd, "Sd", Vsqrts); |
| 2954 IValueT Sm = encodeSRegister(OpSm, "Sm", Vsqrts); | 3031 IValueT Sm = encodeSRegister(OpSm, "Sm", Vsqrts); |
| 2955 constexpr IValueT VsqrtsOpcode = B23 | B21 | B20 | B16 | B7 | B6; | 3032 constexpr IValueT VsqrtsOpcode = B23 | B21 | B20 | B16 | B7 | B6; |
| 2956 constexpr IValueT S0 = 0; | 3033 constexpr IValueT S0 = 0; |
| 2957 emitVFPsss(Cond, VsqrtsOpcode, Sd, S0, Sm); | 3034 emitVFPsss(Cond, VsqrtsOpcode, Sd, S0, Sm); |
| 2958 } | 3035 } |
| 2959 | 3036 |
| 2960 } // end of namespace ARM32 | 3037 } // end of namespace ARM32 |
| 2961 } // end of namespace Ice | 3038 } // end of namespace Ice |
| OLD | NEW |