// Copyright 2017, VIXL authors // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of ARM Limited nor the names of its contributors may be // used to endorse or promote products derived from this software without // specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. extern "C" { #include } #include #include #include #include #include #include "utils-vixl.h" #include "aarch32/assembler-aarch32.h" #include "aarch32/constants-aarch32.h" #include "aarch32/instructions-aarch32.h" #include "aarch32/operands-aarch32.h" namespace vixl { namespace aarch32 { void Assembler::EmitT32_16(uint16_t instr) { VIXL_ASSERT(buffer_.Is16bitAligned()); buffer_.Emit16(instr); } void Assembler::EmitT32_32(uint32_t instr) { VIXL_ASSERT(buffer_.Is16bitAligned()); buffer_.Emit16(static_cast(instr >> 16)); buffer_.Emit16(static_cast(instr & 0xffff)); } void Assembler::EmitA32(uint32_t instr) { VIXL_ASSERT(buffer_.Is32bitAligned()); buffer_.Emit32(instr); } #ifdef VIXL_DEBUG void Assembler::PerformCheckIT(Condition condition) { if (it_mask_ == 0) { VIXL_ASSERT(IsUsingA32() || condition.Is(al)); } else { VIXL_ASSERT(condition.Is(first_condition_)); // For A32, AdavanceIT() is not called by the assembler. We must call it // in order to check that IT instructions are used consistently with // the following conditional instructions. if (IsUsingA32()) AdvanceIT(); } } #endif void Assembler::BindHelper(Label* label) { VIXL_ASSERT(!label->IsBound()); label->SetLocation(this, GetCursorOffset()); label->MarkBound(); } uint32_t Assembler::Link(uint32_t instr, Location* location, const Location::EmitOperator& op, const ReferenceInfo* info) { location->SetReferenced(); if (location->IsBound()) { return op.Encode(instr, GetCursorOffset(), location); } location->AddForwardRef(GetCursorOffset(), op, info); return instr; } // Start of generated code. class Dt_L_imm6_1 : public EncodingValue { uint32_t type_; public: explicit Dt_L_imm6_1(DataType dt); uint32_t GetTypeEncodingValue() const { return type_; } }; Dt_L_imm6_1::Dt_L_imm6_1(DataType dt) { switch (dt.GetValue()) { case S8: type_ = 0x0; SetEncodingValue(0x1); break; case U8: type_ = 0x1; SetEncodingValue(0x1); break; case S16: type_ = 0x0; SetEncodingValue(0x2); break; case U16: type_ = 0x1; SetEncodingValue(0x2); break; case S32: type_ = 0x0; SetEncodingValue(0x4); break; case U32: type_ = 0x1; SetEncodingValue(0x4); break; case S64: type_ = 0x0; SetEncodingValue(0x8); break; case U64: type_ = 0x1; SetEncodingValue(0x8); break; default: VIXL_UNREACHABLE(); type_ = 0x0; break; } } class Dt_L_imm6_2 : public EncodingValue { uint32_t type_; public: explicit Dt_L_imm6_2(DataType dt); uint32_t GetTypeEncodingValue() const { return type_; } }; Dt_L_imm6_2::Dt_L_imm6_2(DataType dt) { switch (dt.GetValue()) { case S8: type_ = 0x1; SetEncodingValue(0x1); break; case S16: type_ = 0x1; SetEncodingValue(0x2); break; case S32: type_ = 0x1; SetEncodingValue(0x4); break; case S64: type_ = 0x1; SetEncodingValue(0x8); break; default: VIXL_UNREACHABLE(); type_ = 0x0; break; } } class Dt_L_imm6_3 : public EncodingValue { public: explicit Dt_L_imm6_3(DataType dt); }; Dt_L_imm6_3::Dt_L_imm6_3(DataType dt) { switch (dt.GetValue()) { case I8: SetEncodingValue(0x1); break; case I16: SetEncodingValue(0x2); break; case I32: SetEncodingValue(0x4); break; case I64: SetEncodingValue(0x8); break; default: break; } } class Dt_L_imm6_4 : public EncodingValue { public: explicit Dt_L_imm6_4(DataType dt); }; Dt_L_imm6_4::Dt_L_imm6_4(DataType dt) { switch (dt.GetValue()) { case Untyped8: SetEncodingValue(0x1); break; case Untyped16: SetEncodingValue(0x2); break; case Untyped32: SetEncodingValue(0x4); break; case Untyped64: SetEncodingValue(0x8); break; default: break; } } class Dt_imm6_1 : public EncodingValue { uint32_t type_; public: explicit Dt_imm6_1(DataType dt); uint32_t GetTypeEncodingValue() const { return type_; } }; Dt_imm6_1::Dt_imm6_1(DataType dt) { switch (dt.GetValue()) { case S16: type_ = 0x0; SetEncodingValue(0x1); break; case U16: type_ = 0x1; SetEncodingValue(0x1); break; case S32: type_ = 0x0; SetEncodingValue(0x2); break; case U32: type_ = 0x1; SetEncodingValue(0x2); break; case S64: type_ = 0x0; SetEncodingValue(0x4); break; case U64: type_ = 0x1; SetEncodingValue(0x4); break; default: VIXL_UNREACHABLE(); type_ = 0x0; break; } } class Dt_imm6_2 : public EncodingValue { uint32_t type_; public: explicit Dt_imm6_2(DataType dt); uint32_t GetTypeEncodingValue() const { return type_; } }; Dt_imm6_2::Dt_imm6_2(DataType dt) { switch (dt.GetValue()) { case S16: type_ = 0x1; SetEncodingValue(0x1); break; case S32: type_ = 0x1; SetEncodingValue(0x2); break; case S64: type_ = 0x1; SetEncodingValue(0x4); break; default: VIXL_UNREACHABLE(); type_ = 0x0; break; } } class Dt_imm6_3 : public EncodingValue { public: explicit Dt_imm6_3(DataType dt); }; Dt_imm6_3::Dt_imm6_3(DataType dt) { switch (dt.GetValue()) { case I16: SetEncodingValue(0x1); break; case I32: SetEncodingValue(0x2); break; case I64: SetEncodingValue(0x4); break; default: break; } } class Dt_imm6_4 : public EncodingValue { uint32_t type_; public: explicit Dt_imm6_4(DataType dt); uint32_t GetTypeEncodingValue() const { return type_; } }; Dt_imm6_4::Dt_imm6_4(DataType dt) { switch (dt.GetValue()) { case S8: type_ = 0x0; SetEncodingValue(0x1); break; case U8: type_ = 0x1; SetEncodingValue(0x1); break; case S16: type_ = 0x0; SetEncodingValue(0x2); break; case U16: type_ = 0x1; SetEncodingValue(0x2); break; case S32: type_ = 0x0; SetEncodingValue(0x4); break; case U32: type_ = 0x1; SetEncodingValue(0x4); break; default: VIXL_UNREACHABLE(); type_ = 0x0; break; } } class Dt_op_U_size_1 : public EncodingValue { public: explicit Dt_op_U_size_1(DataType dt); }; Dt_op_U_size_1::Dt_op_U_size_1(DataType dt) { switch (dt.GetValue()) { case S8: SetEncodingValue(0x0); break; case S16: SetEncodingValue(0x1); break; case S32: SetEncodingValue(0x2); break; case U8: SetEncodingValue(0x4); break; case U16: SetEncodingValue(0x5); break; case U32: SetEncodingValue(0x6); break; case P8: SetEncodingValue(0x8); break; case P64: SetEncodingValue(0xa); break; default: break; } } class Dt_op_size_1 : public EncodingValue { public: explicit Dt_op_size_1(DataType dt); }; Dt_op_size_1::Dt_op_size_1(DataType dt) { switch (dt.GetValue()) { case I8: SetEncodingValue(0x0); break; case I16: SetEncodingValue(0x1); break; case I32: SetEncodingValue(0x2); break; case P8: SetEncodingValue(0x4); break; default: break; } } class Dt_op_size_2 : public EncodingValue { public: explicit Dt_op_size_2(DataType dt); }; Dt_op_size_2::Dt_op_size_2(DataType dt) { switch (dt.GetValue()) { case S8: SetEncodingValue(0x0); break; case S16: SetEncodingValue(0x1); break; case S32: SetEncodingValue(0x2); break; case U8: SetEncodingValue(0x4); break; case U16: SetEncodingValue(0x5); break; case U32: SetEncodingValue(0x6); break; default: break; } } class Dt_op_size_3 : public EncodingValue { public: explicit Dt_op_size_3(DataType dt); }; Dt_op_size_3::Dt_op_size_3(DataType dt) { switch (dt.GetValue()) { case S16: SetEncodingValue(0x0); break; case S32: SetEncodingValue(0x1); break; case S64: SetEncodingValue(0x2); break; case U16: SetEncodingValue(0x4); break; case U32: SetEncodingValue(0x5); break; case U64: SetEncodingValue(0x6); break; default: break; } } class Dt_U_imm3H_1 : public EncodingValue { public: explicit Dt_U_imm3H_1(DataType dt); }; Dt_U_imm3H_1::Dt_U_imm3H_1(DataType dt) { switch (dt.GetValue()) { case S8: SetEncodingValue(0x1); break; case S16: SetEncodingValue(0x2); break; case S32: SetEncodingValue(0x4); break; case U8: SetEncodingValue(0x9); break; case U16: SetEncodingValue(0xa); break; case U32: SetEncodingValue(0xc); break; default: break; } } class Dt_U_opc1_opc2_1 : public EncodingValue { public: explicit Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane); }; Dt_U_opc1_opc2_1::Dt_U_opc1_opc2_1(DataType dt, const DRegisterLane& lane) { switch (dt.GetValue()) { case S8: if ((lane.GetLane() & 7) != lane.GetLane()) { return; } SetEncodingValue(0x8 | lane.GetLane()); break; case S16: if ((lane.GetLane() & 3) != lane.GetLane()) { return; } SetEncodingValue(0x1 | (lane.GetLane() << 1)); break; case U8: if ((lane.GetLane() & 7) != lane.GetLane()) { return; } SetEncodingValue(0x18 | lane.GetLane()); break; case U16: if ((lane.GetLane() & 3) != lane.GetLane()) { return; } SetEncodingValue(0x11 | (lane.GetLane() << 1)); break; case Untyped32: if ((lane.GetLane() & 1) != lane.GetLane()) { return; } SetEncodingValue(0x0 | (lane.GetLane() << 2)); break; case kDataTypeValueNone: if ((lane.GetLane() & 1) != lane.GetLane()) { return; } SetEncodingValue(0x0 | (lane.GetLane() << 2)); break; default: break; } } class Dt_opc1_opc2_1 : public EncodingValue { public: explicit Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane); }; Dt_opc1_opc2_1::Dt_opc1_opc2_1(DataType dt, const DRegisterLane& lane) { switch (dt.GetValue()) { case Untyped8: if ((lane.GetLane() & 7) != lane.GetLane()) { return; } SetEncodingValue(0x8 | lane.GetLane()); break; case Untyped16: if ((lane.GetLane() & 3) != lane.GetLane()) { return; } SetEncodingValue(0x1 | (lane.GetLane() << 1)); break; case Untyped32: if ((lane.GetLane() & 1) != lane.GetLane()) { return; } SetEncodingValue(0x0 | (lane.GetLane() << 2)); break; case kDataTypeValueNone: if ((lane.GetLane() & 1) != lane.GetLane()) { return; } SetEncodingValue(0x0 | (lane.GetLane() << 2)); break; default: break; } } class Dt_imm4_1 : public EncodingValue { public: explicit Dt_imm4_1(DataType dt, const DRegisterLane& lane); }; Dt_imm4_1::Dt_imm4_1(DataType dt, const DRegisterLane& lane) { switch (dt.GetValue()) { case Untyped8: if ((lane.GetLane() & 7) != lane.GetLane()) { return; } SetEncodingValue(0x1 | (lane.GetLane() << 1)); break; case Untyped16: if ((lane.GetLane() & 3) != lane.GetLane()) { return; } SetEncodingValue(0x2 | (lane.GetLane() << 2)); break; case Untyped32: if ((lane.GetLane() & 1) != lane.GetLane()) { return; } SetEncodingValue(0x4 | (lane.GetLane() << 3)); break; default: break; } } class Dt_B_E_1 : public EncodingValue { public: explicit Dt_B_E_1(DataType dt); }; Dt_B_E_1::Dt_B_E_1(DataType dt) { switch (dt.GetValue()) { case Untyped8: SetEncodingValue(0x2); break; case Untyped16: SetEncodingValue(0x1); break; case Untyped32: SetEncodingValue(0x0); break; default: break; } } class Dt_op_1 : public EncodingValue { public: Dt_op_1(DataType dt1, DataType dt2); }; Dt_op_1::Dt_op_1(DataType dt1, DataType dt2) { if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) { SetEncodingValue(0x0); return; } if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) { SetEncodingValue(0x1); return; } if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) { SetEncodingValue(0x2); return; } if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) { SetEncodingValue(0x3); return; } } class Dt_op_2 : public EncodingValue { public: explicit Dt_op_2(DataType dt); }; Dt_op_2::Dt_op_2(DataType dt) { switch (dt.GetValue()) { case U32: SetEncodingValue(0x0); break; case S32: SetEncodingValue(0x1); break; default: break; } } class Dt_op_3 : public EncodingValue { public: explicit Dt_op_3(DataType dt); }; Dt_op_3::Dt_op_3(DataType dt) { switch (dt.GetValue()) { case S32: SetEncodingValue(0x0); break; case U32: SetEncodingValue(0x1); break; default: break; } } class Dt_U_sx_1 : public EncodingValue { public: explicit Dt_U_sx_1(DataType dt); }; Dt_U_sx_1::Dt_U_sx_1(DataType dt) { switch (dt.GetValue()) { case S16: SetEncodingValue(0x0); break; case S32: SetEncodingValue(0x1); break; case U16: SetEncodingValue(0x2); break; case U32: SetEncodingValue(0x3); break; default: break; } } class Dt_op_U_1 : public EncodingValue { public: Dt_op_U_1(DataType dt1, DataType dt2); }; Dt_op_U_1::Dt_op_U_1(DataType dt1, DataType dt2) { if ((dt1.GetValue() == F32) && (dt2.GetValue() == S32)) { SetEncodingValue(0x0); return; } if ((dt1.GetValue() == F32) && (dt2.GetValue() == U32)) { SetEncodingValue(0x1); return; } if ((dt1.GetValue() == S32) && (dt2.GetValue() == F32)) { SetEncodingValue(0x2); return; } if ((dt1.GetValue() == U32) && (dt2.GetValue() == F32)) { SetEncodingValue(0x3); return; } } class Dt_sz_1 : public EncodingValue { public: explicit Dt_sz_1(DataType dt); }; Dt_sz_1::Dt_sz_1(DataType dt) { switch (dt.GetValue()) { case F32: SetEncodingValue(0x0); break; default: break; } } class Dt_F_size_1 : public EncodingValue { public: explicit Dt_F_size_1(DataType dt); }; Dt_F_size_1::Dt_F_size_1(DataType dt) { switch (dt.GetValue()) { case S8: SetEncodingValue(0x0); break; case S16: SetEncodingValue(0x1); break; case S32: SetEncodingValue(0x2); break; case F32: SetEncodingValue(0x6); break; default: break; } } class Dt_F_size_2 : public EncodingValue { public: explicit Dt_F_size_2(DataType dt); }; Dt_F_size_2::Dt_F_size_2(DataType dt) { switch (dt.GetValue()) { case I8: SetEncodingValue(0x0); break; case I16: SetEncodingValue(0x1); break; case I32: SetEncodingValue(0x2); break; case F32: SetEncodingValue(0x6); break; default: break; } } class Dt_F_size_3 : public EncodingValue { public: explicit Dt_F_size_3(DataType dt); }; Dt_F_size_3::Dt_F_size_3(DataType dt) { switch (dt.GetValue()) { case I16: SetEncodingValue(0x1); break; case I32: SetEncodingValue(0x2); break; case F32: SetEncodingValue(0x6); break; default: break; } } class Dt_F_size_4 : public EncodingValue { public: explicit Dt_F_size_4(DataType dt); }; Dt_F_size_4::Dt_F_size_4(DataType dt) { switch (dt.GetValue()) { case U32: SetEncodingValue(0x2); break; case F32: SetEncodingValue(0x6); break; default: break; } } class Dt_U_size_1 : public EncodingValue { public: explicit Dt_U_size_1(DataType dt); }; Dt_U_size_1::Dt_U_size_1(DataType dt) { switch (dt.GetValue()) { case S8: SetEncodingValue(0x0); break; case S16: SetEncodingValue(0x1); break; case S32: SetEncodingValue(0x2); break; case U8: SetEncodingValue(0x4); break; case U16: SetEncodingValue(0x5); break; case U32: SetEncodingValue(0x6); break; default: break; } } class Dt_U_size_2 : public EncodingValue { public: explicit Dt_U_size_2(DataType dt); }; Dt_U_size_2::Dt_U_size_2(DataType dt) { switch (dt.GetValue()) { case S16: SetEncodingValue(0x1); break; case S32: SetEncodingValue(0x2); break; case U16: SetEncodingValue(0x5); break; case U32: SetEncodingValue(0x6); break; default: break; } } class Dt_U_size_3 : public EncodingValue { public: explicit Dt_U_size_3(DataType dt); }; Dt_U_size_3::Dt_U_size_3(DataType dt) { switch (dt.GetValue()) { case S8: SetEncodingValue(0x0); break; case S16: SetEncodingValue(0x1); break; case S32: SetEncodingValue(0x2); break; case S64: SetEncodingValue(0x3); break; case U8: SetEncodingValue(0x4); break; case U16: SetEncodingValue(0x5); break; case U32: SetEncodingValue(0x6); break; case U64: SetEncodingValue(0x7); break; default: break; } } class Dt_size_1 : public EncodingValue { public: explicit Dt_size_1(DataType dt); }; Dt_size_1::Dt_size_1(DataType dt) { switch (dt.GetValue()) { case Untyped8: SetEncodingValue(0x0); break; default: break; } } class Dt_size_2 : public EncodingValue { public: explicit Dt_size_2(DataType dt); }; Dt_size_2::Dt_size_2(DataType dt) { switch (dt.GetValue()) { case I8: SetEncodingValue(0x0); break; case I16: SetEncodingValue(0x1); break; case I32: SetEncodingValue(0x2); break; case I64: SetEncodingValue(0x3); break; default: break; } } class Dt_size_3 : public EncodingValue { public: explicit Dt_size_3(DataType dt); }; Dt_size_3::Dt_size_3(DataType dt) { switch (dt.GetValue()) { case I16: SetEncodingValue(0x0); break; case I32: SetEncodingValue(0x1); break; case I64: SetEncodingValue(0x2); break; default: break; } } class Dt_size_4 : public EncodingValue { public: explicit Dt_size_4(DataType dt); }; Dt_size_4::Dt_size_4(DataType dt) { switch (dt.GetValue()) { case I8: SetEncodingValue(0x0); break; case I16: SetEncodingValue(0x1); break; case I32: SetEncodingValue(0x2); break; default: break; } } class Dt_size_5 : public EncodingValue { public: explicit Dt_size_5(DataType dt); }; Dt_size_5::Dt_size_5(DataType dt) { switch (dt.GetValue()) { case S8: SetEncodingValue(0x0); break; case S16: SetEncodingValue(0x1); break; case S32: SetEncodingValue(0x2); break; default: break; } } class Dt_size_6 : public EncodingValue { public: explicit Dt_size_6(DataType dt); }; Dt_size_6::Dt_size_6(DataType dt) { switch (dt.GetValue()) { case Untyped8: SetEncodingValue(0x0); break; case Untyped16: SetEncodingValue(0x1); break; case Untyped32: SetEncodingValue(0x2); break; case Untyped64: SetEncodingValue(0x3); break; default: break; } } class Dt_size_7 : public EncodingValue { public: explicit Dt_size_7(DataType dt); }; Dt_size_7::Dt_size_7(DataType dt) { switch (dt.GetValue()) { case Untyped8: SetEncodingValue(0x0); break; case Untyped16: SetEncodingValue(0x1); break; case Untyped32: SetEncodingValue(0x2); break; default: break; } } class Dt_size_8 : public EncodingValue { public: Dt_size_8(DataType dt, Alignment align); }; Dt_size_8::Dt_size_8(DataType dt, Alignment align) { switch (dt.GetValue()) { case Untyped8: SetEncodingValue(0x0); break; case Untyped16: SetEncodingValue(0x1); break; case Untyped32: if (align.Is(k64BitAlign) || align.Is(kNoAlignment)) { SetEncodingValue(0x2); } else if (align.Is(k128BitAlign)) { SetEncodingValue(0x3); } break; default: break; } } class Dt_size_9 : public EncodingValue { uint32_t type_; public: explicit Dt_size_9(DataType dt); uint32_t GetTypeEncodingValue() const { return type_; } }; Dt_size_9::Dt_size_9(DataType dt) { switch (dt.GetValue()) { case I16: type_ = 0x0; SetEncodingValue(0x1); break; case I32: type_ = 0x0; SetEncodingValue(0x2); break; case F32: type_ = 0x1; SetEncodingValue(0x2); break; default: VIXL_UNREACHABLE(); type_ = 0x0; break; } } class Dt_size_10 : public EncodingValue { public: explicit Dt_size_10(DataType dt); }; Dt_size_10::Dt_size_10(DataType dt) { switch (dt.GetValue()) { case S8: case U8: case I8: SetEncodingValue(0x0); break; case S16: case U16: case I16: SetEncodingValue(0x1); break; case S32: case U32: case I32: SetEncodingValue(0x2); break; default: break; } } class Dt_size_11 : public EncodingValue { uint32_t type_; public: explicit Dt_size_11(DataType dt); uint32_t GetTypeEncodingValue() const { return type_; } }; Dt_size_11::Dt_size_11(DataType dt) { switch (dt.GetValue()) { case S16: type_ = 0x0; SetEncodingValue(0x1); break; case U16: type_ = 0x1; SetEncodingValue(0x1); break; case S32: type_ = 0x0; SetEncodingValue(0x2); break; case U32: type_ = 0x1; SetEncodingValue(0x2); break; default: VIXL_UNREACHABLE(); type_ = 0x0; break; } } class Dt_size_12 : public EncodingValue { uint32_t type_; public: explicit Dt_size_12(DataType dt); uint32_t GetTypeEncodingValue() const { return type_; } }; Dt_size_12::Dt_size_12(DataType dt) { switch (dt.GetValue()) { case S8: type_ = 0x0; SetEncodingValue(0x0); break; case U8: type_ = 0x1; SetEncodingValue(0x0); break; case S16: type_ = 0x0; SetEncodingValue(0x1); break; case U16: type_ = 0x1; SetEncodingValue(0x1); break; case S32: type_ = 0x0; SetEncodingValue(0x2); break; case U32: type_ = 0x1; SetEncodingValue(0x2); break; default: VIXL_UNREACHABLE(); type_ = 0x0; break; } } class Dt_size_13 : public EncodingValue { public: explicit Dt_size_13(DataType dt); }; Dt_size_13::Dt_size_13(DataType dt) { switch (dt.GetValue()) { case S16: SetEncodingValue(0x1); break; case S32: SetEncodingValue(0x2); break; default: break; } } class Dt_size_14 : public EncodingValue { public: explicit Dt_size_14(DataType dt); }; Dt_size_14::Dt_size_14(DataType dt) { switch (dt.GetValue()) { case S16: SetEncodingValue(0x0); break; case S32: SetEncodingValue(0x1); break; case S64: SetEncodingValue(0x2); break; default: break; } } class Dt_size_15 : public EncodingValue { public: explicit Dt_size_15(DataType dt); }; Dt_size_15::Dt_size_15(DataType dt) { switch (dt.GetValue()) { case Untyped8: SetEncodingValue(0x0); break; case Untyped16: SetEncodingValue(0x1); break; default: break; } } class Dt_size_16 : public EncodingValue { public: explicit Dt_size_16(DataType dt); }; Dt_size_16::Dt_size_16(DataType dt) { switch (dt.GetValue()) { case F32: SetEncodingValue(0x2); break; default: break; } } class Dt_size_17 : public EncodingValue { public: explicit Dt_size_17(DataType dt); }; Dt_size_17::Dt_size_17(DataType dt) { switch (dt.GetValue()) { case I8: SetEncodingValue(0x0); break; case I16: SetEncodingValue(0x1); break; case I32: SetEncodingValue(0x2); break; default: break; } } class Index_1 : public EncodingValue { public: Index_1(const NeonRegisterList& nreglist, DataType dt); }; Index_1::Index_1(const NeonRegisterList& nreglist, DataType dt) { switch (dt.GetValue()) { case Untyped8: { if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { return; } uint32_t value = nreglist.GetTransferLane() << 1; if (!nreglist.IsSingleSpaced()) return; SetEncodingValue(value); break; } case Untyped16: { if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { return; } uint32_t value = nreglist.GetTransferLane() << 2; if (nreglist.IsDoubleSpaced()) value |= 2; SetEncodingValue(value); break; } case Untyped32: { if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { return; } uint32_t value = nreglist.GetTransferLane() << 3; if (nreglist.IsDoubleSpaced()) value |= 4; SetEncodingValue(value); break; } default: break; } } class Align_index_align_1 : public EncodingValue { public: Align_index_align_1(Alignment align, const NeonRegisterList& nreglist, DataType dt); }; Align_index_align_1::Align_index_align_1(Alignment align, const NeonRegisterList& nreglist, DataType dt) { switch (dt.GetValue()) { case Untyped8: { uint32_t value; if (align.GetType() == kNoAlignment) { value = 0; } else { return; } if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { return; } value |= nreglist.GetTransferLane() << 1; SetEncodingValue(value); break; } case Untyped16: { uint32_t value; if (align.GetType() == k16BitAlign) { value = 1; } else if (align.GetType() == kNoAlignment) { value = 0; } else { return; } if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { return; } value |= nreglist.GetTransferLane() << 2; SetEncodingValue(value); break; } case Untyped32: { uint32_t value; if (align.GetType() == k32BitAlign) { value = 3; } else if (align.GetType() == kNoAlignment) { value = 0; } else { return; } if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { return; } value |= nreglist.GetTransferLane() << 3; SetEncodingValue(value); break; } default: break; } } class Align_index_align_2 : public EncodingValue { public: Align_index_align_2(Alignment align, const NeonRegisterList& nreglist, DataType dt); }; Align_index_align_2::Align_index_align_2(Alignment align, const NeonRegisterList& nreglist, DataType dt) { switch (dt.GetValue()) { case Untyped8: { uint32_t value; if (align.GetType() == k16BitAlign) { value = 1; } else if (align.GetType() == kNoAlignment) { value = 0; } else { return; } if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { return; } value |= nreglist.GetTransferLane() << 1; if (!nreglist.IsSingleSpaced()) return; SetEncodingValue(value); break; } case Untyped16: { uint32_t value; if (align.GetType() == k32BitAlign) { value = 1; } else if (align.GetType() == kNoAlignment) { value = 0; } else { return; } if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { return; } value |= nreglist.GetTransferLane() << 2; if (nreglist.IsDoubleSpaced()) value |= 2; SetEncodingValue(value); break; } case Untyped32: { uint32_t value; if (align.GetType() == k64BitAlign) { value = 1; } else if (align.GetType() == kNoAlignment) { value = 0; } else { return; } if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { return; } value |= nreglist.GetTransferLane() << 3; if (nreglist.IsDoubleSpaced()) value |= 4; SetEncodingValue(value); break; } default: break; } } class Align_index_align_3 : public EncodingValue { public: Align_index_align_3(Alignment align, const NeonRegisterList& nreglist, DataType dt); }; Align_index_align_3::Align_index_align_3(Alignment align, const NeonRegisterList& nreglist, DataType dt) { switch (dt.GetValue()) { case Untyped8: { uint32_t value; if (align.GetType() == k32BitAlign) { value = 1; } else if (align.GetType() == kNoAlignment) { value = 0; } else { return; } if ((nreglist.GetTransferLane() & 7) != nreglist.GetTransferLane()) { return; } value |= nreglist.GetTransferLane() << 1; if (!nreglist.IsSingleSpaced()) return; SetEncodingValue(value); break; } case Untyped16: { uint32_t value; if (align.GetType() == k64BitAlign) { value = 1; } else if (align.GetType() == kNoAlignment) { value = 0; } else { return; } if ((nreglist.GetTransferLane() & 3) != nreglist.GetTransferLane()) { return; } value |= nreglist.GetTransferLane() << 2; if (nreglist.IsDoubleSpaced()) value |= 2; SetEncodingValue(value); break; } case Untyped32: { uint32_t value; if (align.GetType() == k64BitAlign) { value = 1; } else if (align.GetType() == k128BitAlign) { value = 2; } else if (align.GetType() == kNoAlignment) { value = 0; } else { return; } if ((nreglist.GetTransferLane() & 1) != nreglist.GetTransferLane()) { return; } value |= nreglist.GetTransferLane() << 3; if (nreglist.IsDoubleSpaced()) value |= 4; SetEncodingValue(value); break; } default: break; } } class Align_a_1 : public EncodingValue { public: Align_a_1(Alignment align, DataType dt); }; Align_a_1::Align_a_1(Alignment align, DataType dt) { switch (align.GetType()) { case k16BitAlign: if (dt.Is(Untyped16)) SetEncodingValue(0x1); break; case k32BitAlign: if (dt.Is(Untyped32)) SetEncodingValue(0x1); break; case kNoAlignment: SetEncodingValue(0x0); break; default: break; } } class Align_a_2 : public EncodingValue { public: Align_a_2(Alignment align, DataType dt); }; Align_a_2::Align_a_2(Alignment align, DataType dt) { switch (align.GetType()) { case k16BitAlign: if (dt.Is(Untyped8)) SetEncodingValue(0x1); break; case k32BitAlign: if (dt.Is(Untyped16)) SetEncodingValue(0x1); break; case k64BitAlign: if (dt.Is(Untyped32)) SetEncodingValue(0x1); break; case kNoAlignment: SetEncodingValue(0x0); break; default: break; } } class Align_a_3 : public EncodingValue { public: Align_a_3(Alignment align, DataType dt); }; Align_a_3::Align_a_3(Alignment align, DataType dt) { switch (align.GetType()) { case k32BitAlign: if (dt.Is(Untyped8)) SetEncodingValue(0x1); break; case k64BitAlign: if (dt.Is(Untyped16)) SetEncodingValue(0x1); else if (dt.Is(Untyped32)) SetEncodingValue(0x1); break; case k128BitAlign: if (dt.Is(Untyped32)) SetEncodingValue(0x1); break; case kNoAlignment: SetEncodingValue(0x0); break; default: break; } } class Align_align_1 : public EncodingValue { public: Align_align_1(Alignment align, const NeonRegisterList& nreglist); }; Align_align_1::Align_align_1(Alignment align, const NeonRegisterList& nreglist) { switch (align.GetType()) { case k64BitAlign: SetEncodingValue(0x1); break; case k128BitAlign: if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4)) SetEncodingValue(0x2); break; case k256BitAlign: if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4)) SetEncodingValue(0x3); break; case kNoAlignment: SetEncodingValue(0x0); break; default: break; } } class Align_align_2 : public EncodingValue { public: Align_align_2(Alignment align, const NeonRegisterList& nreglist); }; Align_align_2::Align_align_2(Alignment align, const NeonRegisterList& nreglist) { switch (align.GetType()) { case k64BitAlign: SetEncodingValue(0x1); break; case k128BitAlign: SetEncodingValue(0x2); break; case k256BitAlign: if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3); break; case kNoAlignment: SetEncodingValue(0x0); break; default: break; } } class Align_align_3 : public EncodingValue { public: explicit Align_align_3(Alignment align); }; Align_align_3::Align_align_3(Alignment align) { switch (align.GetType()) { case k64BitAlign: SetEncodingValue(0x1); break; case kNoAlignment: SetEncodingValue(0x0); break; default: break; } } class Align_align_4 : public EncodingValue { public: explicit Align_align_4(Alignment align); }; Align_align_4::Align_align_4(Alignment align) { switch (align.GetType()) { case k64BitAlign: SetEncodingValue(0x1); break; case k128BitAlign: SetEncodingValue(0x2); break; case k256BitAlign: SetEncodingValue(0x3); break; case kNoAlignment: SetEncodingValue(0x0); break; default: break; } } class Align_align_5 : public EncodingValue { public: Align_align_5(Alignment align, const NeonRegisterList& nreglist); }; Align_align_5::Align_align_5(Alignment align, const NeonRegisterList& nreglist) { switch (align.GetType()) { case k64BitAlign: SetEncodingValue(0x1); break; case k128BitAlign: if ((nreglist.GetLength() == 2) || (nreglist.GetLength() == 4)) SetEncodingValue(0x2); break; case k256BitAlign: if ((nreglist.GetLength() == 4)) SetEncodingValue(0x3); break; case kNoAlignment: SetEncodingValue(0x0); break; default: break; } } // CBNZ{} ,