| 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 2526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2537 encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address); | 2537 encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address); |
| 2538 (void)AddressEncoding; | 2538 (void)AddressEncoding; |
| 2539 assert(AddressEncoding == EncodedAsImmRegOffset); | 2539 assert(AddressEncoding == EncodedAsImmRegOffset); |
| 2540 IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | | 2540 IValueT Encoding = B27 | B26 | B24 | B20 | B11 | B9 | |
| 2541 (encodeCondition(Cond) << kConditionShift) | | 2541 (encodeCondition(Cond) << kConditionShift) | |
| 2542 (getYInRegXXXXY(Sd) << 22) | | 2542 (getYInRegXXXXY(Sd) << 22) | |
| 2543 (getXXXXInRegXXXXY(Sd) << 12) | Address; | 2543 (getXXXXInRegXXXXY(Sd) << 12) | Address; |
| 2544 emitInst(Encoding); | 2544 emitInst(Encoding); |
| 2545 } | 2545 } |
| 2546 | 2546 |
| 2547 void AssemblerARM32::emitVMem1Op(IValueT Opcode, IValueT Dd, IValueT Rn, |
| 2548 IValueT Rm, DRegListSize NumDRegs, |
| 2549 size_t ElmtSize, IValueT Align, |
| 2550 const char *InstName) { |
| 2551 assert(Utils::IsAbsoluteUint(2, Align)); |
| 2552 IValueT EncodedElmtSize; |
| 2553 switch (ElmtSize) { |
| 2554 default: { |
| 2555 std::string Buffer; |
| 2556 llvm::raw_string_ostream StrBuf(Buffer); |
| 2557 StrBuf << InstName << ": found invalid vector element size " << ElmtSize; |
| 2558 llvm::report_fatal_error(StrBuf.str()); |
| 2559 } |
| 2560 case 8: |
| 2561 EncodedElmtSize = 0; |
| 2562 break; |
| 2563 case 16: |
| 2564 EncodedElmtSize = 1; |
| 2565 break; |
| 2566 case 32: |
| 2567 EncodedElmtSize = 2; |
| 2568 break; |
| 2569 case 64: |
| 2570 EncodedElmtSize = 3; |
| 2571 } |
| 2572 const IValueT Encoding = |
| 2573 Opcode | (encodeCondition(CondARM32::kNone) << kConditionShift) | |
| 2574 (getYInRegYXXXX(Dd) << 22) | (Rn << kRnShift) | |
| 2575 (getXXXXInRegYXXXX(Dd) << kRdShift) | (NumDRegs << 8) | |
| 2576 (EncodedElmtSize << 6) | (Align << 4) | Rm; |
| 2577 emitInst(Encoding); |
| 2578 } |
| 2579 |
| 2580 void AssemblerARM32::vld1qr(size_t ElmtSize, const Operand *OpQd, |
| 2581 const Operand *OpAddress, const TargetInfo &TInfo) { |
| 2582 // VLD1 (multiple single elements) - ARM section A8.8.320, encoding A1: |
| 2583 // vld1.<size> <Qd>, [<Rn>] |
| 2584 // |
| 2585 // 111101000D10nnnnddd0ttttssaammmm where tttt=DRegListSize2, Dddd=Qd, |
| 2586 // nnnn=Rn, aa=0 (use default alignment), size=ElmtSize, and ss is the |
| 2587 // encoding of ElmtSize. |
| 2588 constexpr const char *Vld1qr = "vld1qr"; |
| 2589 const IValueT Qd = encodeQRegister(OpQd, "Qd", Vld1qr); |
| 2590 const IValueT Dd = mapQRegToDReg(Qd); |
| 2591 IValueT Address; |
| 2592 if (encodeAddress(OpAddress, Address, TInfo, NoImmOffsetAddress) != |
| 2593 EncodedAsImmRegOffset) |
| 2594 llvm::report_fatal_error(std::string(Vld1qr) + ": malform memory address"); |
| 2595 const IValueT Rn = mask(Address, kRnShift, 4); |
| 2596 constexpr IValueT Rm = RegARM32::Reg_pc; |
| 2597 constexpr IValueT Opcode = B26 | B21; |
| 2598 constexpr IValueT Align = 0; // use default alignment. |
| 2599 emitVMem1Op(Opcode, Dd, Rn, Rm, DRegListSize2, ElmtSize, Align, Vld1qr); |
| 2600 } |
| 2601 |
| 2547 void AssemblerARM32::vmovd(const Operand *OpDd, | 2602 void AssemblerARM32::vmovd(const Operand *OpDd, |
| 2548 const OperandARM32FlexFpImm *OpFpImm, | 2603 const OperandARM32FlexFpImm *OpFpImm, |
| 2549 CondARM32::Cond Cond) { | 2604 CondARM32::Cond Cond) { |
| 2550 // VMOV (immediate) - ARM section A8.8.339, encoding A2: | 2605 // VMOV (immediate) - ARM section A8.8.339, encoding A2: |
| 2551 // vmov<c>.f64 <Dd>, #<imm> | 2606 // vmov<c>.f64 <Dd>, #<imm> |
| 2552 // | 2607 // |
| 2553 // cccc11101D11xxxxdddd10110000yyyy where cccc=Cond, ddddD=Sn, xxxxyyyy=imm. | 2608 // cccc11101D11xxxxdddd10110000yyyy where cccc=Cond, ddddD=Sn, xxxxyyyy=imm. |
| 2554 constexpr const char *Vmovd = "vmovd"; | 2609 constexpr const char *Vmovd = "vmovd"; |
| 2555 IValueT Dd = encodeSRegister(OpDd, "Dd", Vmovd); | 2610 IValueT Dd = encodeSRegister(OpDd, "Dd", Vmovd); |
| 2556 IValueT Imm8 = OpFpImm->getModifiedImm(); | 2611 IValueT Imm8 = OpFpImm->getModifiedImm(); |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2851 IValueT AddressEncoding = | 2906 IValueT AddressEncoding = |
| 2852 encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address); | 2907 encodeAddress(OpAddress, Address, TInfo, RotatedImm8Div4Address); |
| 2853 (void)AddressEncoding; | 2908 (void)AddressEncoding; |
| 2854 assert(AddressEncoding == EncodedAsImmRegOffset); | 2909 assert(AddressEncoding == EncodedAsImmRegOffset); |
| 2855 IValueT Encoding = | 2910 IValueT Encoding = |
| 2856 B27 | B26 | B24 | B11 | B9 | (encodeCondition(Cond) << kConditionShift) | | 2911 B27 | B26 | B24 | B11 | B9 | (encodeCondition(Cond) << kConditionShift) | |
| 2857 (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sd) << 12) | Address; | 2912 (getYInRegXXXXY(Sd) << 22) | (getXXXXInRegXXXXY(Sd) << 12) | Address; |
| 2858 emitInst(Encoding); | 2913 emitInst(Encoding); |
| 2859 } | 2914 } |
| 2860 | 2915 |
| 2916 void AssemblerARM32::vst1qr(size_t ElmtSize, const Operand *OpQd, |
| 2917 const Operand *OpAddress, const TargetInfo &TInfo) { |
| 2918 // VST1 (multiple single elements) - ARM section A8.8.404, encoding A1: |
| 2919 // vst1.<size> <Qd>, [<Rn>] |
| 2920 // |
| 2921 // 111101000D00nnnnddd0ttttssaammmm where tttt=DRegListSize2, Dddd=Qd, |
| 2922 // nnnn=Rn, aa=0 (use default alignment), size=ElmtSize, and ss is the |
| 2923 // encoding of ElmtSize. |
| 2924 constexpr const char *Vst1qr = "vst1qr"; |
| 2925 const IValueT Qd = encodeQRegister(OpQd, "Qd", Vst1qr); |
| 2926 const IValueT Dd = mapQRegToDReg(Qd); |
| 2927 IValueT Address; |
| 2928 if (encodeAddress(OpAddress, Address, TInfo, NoImmOffsetAddress) != |
| 2929 EncodedAsImmRegOffset) |
| 2930 llvm::report_fatal_error(std::string(Vst1qr) + ": malform memory address"); |
| 2931 const IValueT Rn = mask(Address, kRnShift, 4); |
| 2932 constexpr IValueT Rm = RegARM32::Reg_pc; |
| 2933 constexpr IValueT Opcode = B26; |
| 2934 constexpr IValueT Align = 0; // use default alignment. |
| 2935 emitVMem1Op(Opcode, Dd, Rn, Rm, DRegListSize2, ElmtSize, Align, Vst1qr); |
| 2936 } |
| 2937 |
| 2861 void AssemblerARM32::vsubs(const Operand *OpSd, const Operand *OpSn, | 2938 void AssemblerARM32::vsubs(const Operand *OpSd, const Operand *OpSn, |
| 2862 const Operand *OpSm, CondARM32::Cond Cond) { | 2939 const Operand *OpSm, CondARM32::Cond Cond) { |
| 2863 // VSUB (floating-point) - ARM section A8.8.415, encoding A2: | 2940 // VSUB (floating-point) - ARM section A8.8.415, encoding A2: |
| 2864 // vsub<c>.f32 <Sd>, <Sn>, <Sm> | 2941 // vsub<c>.f32 <Sd>, <Sn>, <Sm> |
| 2865 // | 2942 // |
| 2866 // cccc11100D11nnnndddd101sN1M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn, | 2943 // cccc11100D11nnnndddd101sN1M0mmmm where cccc=Cond, s=0, ddddD=Rd, nnnnN=Rn, |
| 2867 // and mmmmM=Rm. | 2944 // and mmmmM=Rm. |
| 2868 constexpr const char *Vsubs = "vsubs"; | 2945 constexpr const char *Vsubs = "vsubs"; |
| 2869 constexpr IValueT VsubsOpcode = B21 | B20 | B6; | 2946 constexpr IValueT VsubsOpcode = B21 | B20 | B6; |
| 2870 emitVFPsss(Cond, VsubsOpcode, OpSd, OpSn, OpSm, Vsubs); | 2947 emitVFPsss(Cond, VsubsOpcode, OpSd, OpSn, OpSm, Vsubs); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2974 constexpr const char *Vsqrts = "vsqrts"; | 3051 constexpr const char *Vsqrts = "vsqrts"; |
| 2975 IValueT Sd = encodeSRegister(OpSd, "Sd", Vsqrts); | 3052 IValueT Sd = encodeSRegister(OpSd, "Sd", Vsqrts); |
| 2976 IValueT Sm = encodeSRegister(OpSm, "Sm", Vsqrts); | 3053 IValueT Sm = encodeSRegister(OpSm, "Sm", Vsqrts); |
| 2977 constexpr IValueT VsqrtsOpcode = B23 | B21 | B20 | B16 | B7 | B6; | 3054 constexpr IValueT VsqrtsOpcode = B23 | B21 | B20 | B16 | B7 | B6; |
| 2978 constexpr IValueT S0 = 0; | 3055 constexpr IValueT S0 = 0; |
| 2979 emitVFPsss(Cond, VsqrtsOpcode, Sd, S0, Sm); | 3056 emitVFPsss(Cond, VsqrtsOpcode, Sd, S0, Sm); |
| 2980 } | 3057 } |
| 2981 | 3058 |
| 2982 } // end of namespace ARM32 | 3059 } // end of namespace ARM32 |
| 2983 } // end of namespace Ice | 3060 } // end of namespace Ice |
| OLD | NEW |