67277 lines
3.2 MiB
67277 lines
3.2 MiB
// Copyright 2015, 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 <stdint.h>
|
|
}
|
|
|
|
#include <cassert>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <iomanip>
|
|
#include <iostream>
|
|
|
|
#include "utils-vixl.h"
|
|
#include "aarch32/constants-aarch32.h"
|
|
#include "aarch32/disasm-aarch32.h"
|
|
#include "aarch32/instructions-aarch32.h"
|
|
#include "aarch32/operands-aarch32.h"
|
|
|
|
namespace vixl {
|
|
namespace aarch32 {
|
|
|
|
using internal::Int64;
|
|
using internal::Uint32;
|
|
|
|
class T32CodeAddressIncrementer {
|
|
uint32_t* code_address_;
|
|
uint32_t increment_;
|
|
|
|
public:
|
|
T32CodeAddressIncrementer(uint32_t instr, uint32_t* code_address)
|
|
: code_address_(code_address),
|
|
increment_(Disassembler::Is16BitEncoding(instr) ? 2 : 4) {}
|
|
~T32CodeAddressIncrementer() { *code_address_ += increment_; }
|
|
};
|
|
|
|
class A32CodeAddressIncrementer {
|
|
uint32_t* code_address_;
|
|
|
|
public:
|
|
explicit A32CodeAddressIncrementer(uint32_t* code_address)
|
|
: code_address_(code_address) {}
|
|
~A32CodeAddressIncrementer() { *code_address_ += 4; }
|
|
};
|
|
|
|
class DecodeNeon {
|
|
int lane_;
|
|
SpacingType spacing_;
|
|
bool valid_;
|
|
|
|
public:
|
|
DecodeNeon(int lane, SpacingType spacing)
|
|
: lane_(lane), spacing_(spacing), valid_(true) {}
|
|
DecodeNeon() : lane_(0), spacing_(kSingle), valid_(false) {}
|
|
int GetLane() const { return lane_; }
|
|
SpacingType GetSpacing() const { return spacing_; }
|
|
bool IsValid() const { return valid_; }
|
|
};
|
|
|
|
class DecodeNeonAndAlign : public DecodeNeon {
|
|
public:
|
|
Alignment align_;
|
|
DecodeNeonAndAlign(int lanes, SpacingType spacing, Alignment align)
|
|
: DecodeNeon(lanes, spacing), align_(align) {}
|
|
DecodeNeonAndAlign() : align_(kBadAlignment) {}
|
|
Alignment GetAlign() const { return align_; }
|
|
};
|
|
|
|
// Start of generated code.
|
|
DataTypeValue Dt_L_imm6_1_Decode(uint32_t value, uint32_t type_value) {
|
|
if ((value & 0xf) == 0x1) {
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return S8;
|
|
case 0x1:
|
|
return U8;
|
|
}
|
|
} else if ((value & 0xe) == 0x2) {
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return S16;
|
|
case 0x1:
|
|
return U16;
|
|
}
|
|
} else if ((value & 0xc) == 0x4) {
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return S32;
|
|
case 0x1:
|
|
return U32;
|
|
}
|
|
} else if ((value & 0x8) == 0x8) {
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return S64;
|
|
case 0x1:
|
|
return U64;
|
|
}
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_L_imm6_2_Decode(uint32_t value, uint32_t type_value) {
|
|
if ((value & 0xf) == 0x1) {
|
|
if (type_value == 0x1) return S8;
|
|
} else if ((value & 0xe) == 0x2) {
|
|
if (type_value == 0x1) return S16;
|
|
} else if ((value & 0xc) == 0x4) {
|
|
if (type_value == 0x1) return S32;
|
|
} else if ((value & 0x8) == 0x8) {
|
|
if (type_value == 0x1) return S64;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_L_imm6_3_Decode(uint32_t value) {
|
|
if ((value & 0xf) == 0x1) {
|
|
return I8;
|
|
} else if ((value & 0xe) == 0x2) {
|
|
return I16;
|
|
} else if ((value & 0xc) == 0x4) {
|
|
return I32;
|
|
} else if ((value & 0x8) == 0x8) {
|
|
return I64;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_L_imm6_4_Decode(uint32_t value) {
|
|
if ((value & 0xf) == 0x1) {
|
|
return Untyped8;
|
|
} else if ((value & 0xe) == 0x2) {
|
|
return Untyped16;
|
|
} else if ((value & 0xc) == 0x4) {
|
|
return Untyped32;
|
|
} else if ((value & 0x8) == 0x8) {
|
|
return Untyped64;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_imm6_1_Decode(uint32_t value, uint32_t type_value) {
|
|
if ((value & 0x7) == 0x1) {
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return S16;
|
|
case 0x1:
|
|
return U16;
|
|
}
|
|
} else if ((value & 0x6) == 0x2) {
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return S32;
|
|
case 0x1:
|
|
return U32;
|
|
}
|
|
} else if ((value & 0x4) == 0x4) {
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return S64;
|
|
case 0x1:
|
|
return U64;
|
|
}
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_imm6_2_Decode(uint32_t value, uint32_t type_value) {
|
|
if ((value & 0x7) == 0x1) {
|
|
if (type_value == 0x1) return S16;
|
|
} else if ((value & 0x6) == 0x2) {
|
|
if (type_value == 0x1) return S32;
|
|
} else if ((value & 0x4) == 0x4) {
|
|
if (type_value == 0x1) return S64;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_imm6_3_Decode(uint32_t value) {
|
|
if ((value & 0x7) == 0x1) {
|
|
return I16;
|
|
} else if ((value & 0x6) == 0x2) {
|
|
return I32;
|
|
} else if ((value & 0x4) == 0x4) {
|
|
return I64;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_imm6_4_Decode(uint32_t value, uint32_t type_value) {
|
|
if ((value & 0x7) == 0x1) {
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return S8;
|
|
case 0x1:
|
|
return U8;
|
|
}
|
|
} else if ((value & 0x6) == 0x2) {
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return S16;
|
|
case 0x1:
|
|
return U16;
|
|
}
|
|
} else if ((value & 0x4) == 0x4) {
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return S32;
|
|
case 0x1:
|
|
return U32;
|
|
}
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_op_U_size_1_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return S8;
|
|
case 0x1:
|
|
return S16;
|
|
case 0x2:
|
|
return S32;
|
|
case 0x4:
|
|
return U8;
|
|
case 0x5:
|
|
return U16;
|
|
case 0x6:
|
|
return U32;
|
|
case 0x8:
|
|
return P8;
|
|
case 0xa:
|
|
return P64;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_op_size_1_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return I8;
|
|
case 0x1:
|
|
return I16;
|
|
case 0x2:
|
|
return I32;
|
|
case 0x4:
|
|
return P8;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_op_size_2_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return S8;
|
|
case 0x1:
|
|
return S16;
|
|
case 0x2:
|
|
return S32;
|
|
case 0x4:
|
|
return U8;
|
|
case 0x5:
|
|
return U16;
|
|
case 0x6:
|
|
return U32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_op_size_3_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return S16;
|
|
case 0x1:
|
|
return S32;
|
|
case 0x2:
|
|
return S64;
|
|
case 0x4:
|
|
return U16;
|
|
case 0x5:
|
|
return U32;
|
|
case 0x6:
|
|
return U64;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_U_imm3H_1_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x1:
|
|
return S8;
|
|
case 0x2:
|
|
return S16;
|
|
case 0x4:
|
|
return S32;
|
|
case 0x9:
|
|
return U8;
|
|
case 0xa:
|
|
return U16;
|
|
case 0xc:
|
|
return U32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_U_opc1_opc2_1_Decode(uint32_t value, unsigned* lane) {
|
|
if ((value & 0x18) == 0x8) {
|
|
*lane = value & 7;
|
|
return S8;
|
|
}
|
|
if ((value & 0x19) == 0x1) {
|
|
*lane = (value >> 1) & 3;
|
|
return S16;
|
|
}
|
|
if ((value & 0x18) == 0x18) {
|
|
*lane = value & 7;
|
|
return U8;
|
|
}
|
|
if ((value & 0x19) == 0x11) {
|
|
*lane = (value >> 1) & 3;
|
|
return U16;
|
|
}
|
|
if ((value & 0x1b) == 0x0) {
|
|
*lane = (value >> 2) & 1;
|
|
return Untyped32;
|
|
}
|
|
*lane = -1;
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_opc1_opc2_1_Decode(uint32_t value, unsigned* lane) {
|
|
if ((value & 0x8) == 0x8) {
|
|
*lane = value & 7;
|
|
return Untyped8;
|
|
}
|
|
if ((value & 0x9) == 0x1) {
|
|
*lane = (value >> 1) & 3;
|
|
return Untyped16;
|
|
}
|
|
if ((value & 0xb) == 0x0) {
|
|
*lane = (value >> 2) & 1;
|
|
return Untyped32;
|
|
}
|
|
*lane = -1;
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_imm4_1_Decode(uint32_t value, unsigned* lane) {
|
|
if ((value & 0x1) == 0x1) {
|
|
*lane = (value >> 1) & 7;
|
|
return Untyped8;
|
|
}
|
|
if ((value & 0x3) == 0x2) {
|
|
*lane = (value >> 2) & 3;
|
|
return Untyped16;
|
|
}
|
|
if ((value & 0x7) == 0x4) {
|
|
*lane = (value >> 3) & 1;
|
|
return Untyped32;
|
|
}
|
|
*lane = -1;
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_B_E_1_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x2:
|
|
return Untyped8;
|
|
case 0x1:
|
|
return Untyped16;
|
|
case 0x0:
|
|
return Untyped32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_op_1_Decode1(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return F32;
|
|
case 0x1:
|
|
return F32;
|
|
case 0x2:
|
|
return S32;
|
|
case 0x3:
|
|
return U32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_op_1_Decode2(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return S32;
|
|
case 0x1:
|
|
return U32;
|
|
case 0x2:
|
|
return F32;
|
|
case 0x3:
|
|
return F32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_op_2_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return U32;
|
|
case 0x1:
|
|
return S32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_op_3_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return S32;
|
|
case 0x1:
|
|
return U32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_U_sx_1_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return S16;
|
|
case 0x1:
|
|
return S32;
|
|
case 0x2:
|
|
return U16;
|
|
case 0x3:
|
|
return U32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_op_U_1_Decode1(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return F32;
|
|
case 0x1:
|
|
return F32;
|
|
case 0x2:
|
|
return S32;
|
|
case 0x3:
|
|
return U32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_op_U_1_Decode2(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return S32;
|
|
case 0x1:
|
|
return U32;
|
|
case 0x2:
|
|
return F32;
|
|
case 0x3:
|
|
return F32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_sz_1_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return F32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_F_size_1_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return S8;
|
|
case 0x1:
|
|
return S16;
|
|
case 0x2:
|
|
return S32;
|
|
case 0x6:
|
|
return F32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_F_size_2_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return I8;
|
|
case 0x1:
|
|
return I16;
|
|
case 0x2:
|
|
return I32;
|
|
case 0x6:
|
|
return F32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_F_size_3_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x1:
|
|
return I16;
|
|
case 0x2:
|
|
return I32;
|
|
case 0x6:
|
|
return F32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_F_size_4_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x2:
|
|
return U32;
|
|
case 0x6:
|
|
return F32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_U_size_1_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return S8;
|
|
case 0x1:
|
|
return S16;
|
|
case 0x2:
|
|
return S32;
|
|
case 0x4:
|
|
return U8;
|
|
case 0x5:
|
|
return U16;
|
|
case 0x6:
|
|
return U32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_U_size_2_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x1:
|
|
return S16;
|
|
case 0x2:
|
|
return S32;
|
|
case 0x5:
|
|
return U16;
|
|
case 0x6:
|
|
return U32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_U_size_3_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return S8;
|
|
case 0x1:
|
|
return S16;
|
|
case 0x2:
|
|
return S32;
|
|
case 0x3:
|
|
return S64;
|
|
case 0x4:
|
|
return U8;
|
|
case 0x5:
|
|
return U16;
|
|
case 0x6:
|
|
return U32;
|
|
case 0x7:
|
|
return U64;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_1_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return Untyped8;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_2_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return I8;
|
|
case 0x1:
|
|
return I16;
|
|
case 0x2:
|
|
return I32;
|
|
case 0x3:
|
|
return I64;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_3_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return I16;
|
|
case 0x1:
|
|
return I32;
|
|
case 0x2:
|
|
return I64;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_4_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return I8;
|
|
case 0x1:
|
|
return I16;
|
|
case 0x2:
|
|
return I32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_5_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return S8;
|
|
case 0x1:
|
|
return S16;
|
|
case 0x2:
|
|
return S32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_6_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return Untyped8;
|
|
case 0x1:
|
|
return Untyped16;
|
|
case 0x2:
|
|
return Untyped32;
|
|
case 0x3:
|
|
return Untyped64;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_7_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return Untyped8;
|
|
case 0x1:
|
|
return Untyped16;
|
|
case 0x2:
|
|
return Untyped32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_8_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return Untyped8;
|
|
case 0x1:
|
|
return Untyped16;
|
|
case 0x2:
|
|
return Untyped32;
|
|
case 0x3:
|
|
return Untyped32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_9_Decode(uint32_t value, uint32_t type_value) {
|
|
switch (value) {
|
|
case 0x1:
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return I16;
|
|
}
|
|
break;
|
|
case 0x2:
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return I32;
|
|
case 0x1:
|
|
return F32;
|
|
}
|
|
break;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_10_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return I8;
|
|
case 0x1:
|
|
return I16;
|
|
case 0x2:
|
|
return I32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_11_Decode(uint32_t value, uint32_t type_value) {
|
|
switch (value) {
|
|
case 0x1:
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return S16;
|
|
case 0x1:
|
|
return U16;
|
|
}
|
|
break;
|
|
case 0x2:
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return S32;
|
|
case 0x1:
|
|
return U32;
|
|
}
|
|
break;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_12_Decode(uint32_t value, uint32_t type_value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return S8;
|
|
case 0x1:
|
|
return U8;
|
|
}
|
|
break;
|
|
case 0x1:
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return S16;
|
|
case 0x1:
|
|
return U16;
|
|
}
|
|
break;
|
|
case 0x2:
|
|
switch (type_value) {
|
|
case 0x0:
|
|
return S32;
|
|
case 0x1:
|
|
return U32;
|
|
}
|
|
break;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_13_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x1:
|
|
return S16;
|
|
case 0x2:
|
|
return S32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_14_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return S16;
|
|
case 0x1:
|
|
return S32;
|
|
case 0x2:
|
|
return S64;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_15_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return Untyped8;
|
|
case 0x1:
|
|
return Untyped16;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_16_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x2:
|
|
return F32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DataTypeValue Dt_size_17_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0x0:
|
|
return I8;
|
|
case 0x1:
|
|
return I16;
|
|
case 0x2:
|
|
return I32;
|
|
}
|
|
return kDataTypeValueInvalid;
|
|
}
|
|
|
|
DecodeNeon Index_1_Decode(uint32_t value, DataType dt) {
|
|
switch (dt.GetValue()) {
|
|
case Untyped8: {
|
|
int lane = (value >> 1) & 0x7;
|
|
if ((value & 1) != 0) break;
|
|
SpacingType spacing = kSingle;
|
|
return DecodeNeon(lane, spacing);
|
|
}
|
|
case Untyped16: {
|
|
int lane = (value >> 2) & 0x3;
|
|
if ((value & 1) != 0) break;
|
|
SpacingType spacing = ((value & 3) == 2) ? kDouble : kSingle;
|
|
return DecodeNeon(lane, spacing);
|
|
}
|
|
case Untyped32: {
|
|
int lane = (value >> 3) & 0x1;
|
|
if ((value & 3) != 0) break;
|
|
SpacingType spacing = ((value & 7) == 4) ? kDouble : kSingle;
|
|
return DecodeNeon(lane, spacing);
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return DecodeNeon();
|
|
}
|
|
|
|
DecodeNeonAndAlign Align_index_align_1_Decode(uint32_t value, DataType dt) {
|
|
switch (dt.GetValue()) {
|
|
case Untyped8: {
|
|
AlignmentType align;
|
|
if ((value & 1) == 0) {
|
|
align = kNoAlignment;
|
|
} else {
|
|
break;
|
|
}
|
|
int lane = (value >> 1) & 0x7;
|
|
SpacingType spacing = kSingle;
|
|
return DecodeNeonAndAlign(lane, spacing, align);
|
|
}
|
|
case Untyped16: {
|
|
AlignmentType align;
|
|
if ((value & 3) == 1) {
|
|
align = k16BitAlign;
|
|
} else if ((value & 3) == 0) {
|
|
align = kNoAlignment;
|
|
} else {
|
|
break;
|
|
}
|
|
int lane = (value >> 2) & 0x3;
|
|
SpacingType spacing = kSingle;
|
|
return DecodeNeonAndAlign(lane, spacing, align);
|
|
}
|
|
case Untyped32: {
|
|
AlignmentType align;
|
|
if ((value & 7) == 3) {
|
|
align = k32BitAlign;
|
|
} else if ((value & 7) == 0) {
|
|
align = kNoAlignment;
|
|
} else {
|
|
break;
|
|
}
|
|
int lane = (value >> 3) & 0x1;
|
|
SpacingType spacing = kSingle;
|
|
return DecodeNeonAndAlign(lane, spacing, align);
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return DecodeNeonAndAlign();
|
|
}
|
|
|
|
DecodeNeonAndAlign Align_index_align_2_Decode(uint32_t value, DataType dt) {
|
|
switch (dt.GetValue()) {
|
|
case Untyped8: {
|
|
AlignmentType align;
|
|
if ((value & 1) == 1) {
|
|
align = k16BitAlign;
|
|
} else if ((value & 1) == 0) {
|
|
align = kNoAlignment;
|
|
} else {
|
|
break;
|
|
}
|
|
int lane = (value >> 1) & 0x7;
|
|
SpacingType spacing = kSingle;
|
|
return DecodeNeonAndAlign(lane, spacing, align);
|
|
}
|
|
case Untyped16: {
|
|
AlignmentType align;
|
|
if ((value & 1) == 1) {
|
|
align = k32BitAlign;
|
|
} else if ((value & 1) == 0) {
|
|
align = kNoAlignment;
|
|
} else {
|
|
break;
|
|
}
|
|
int lane = (value >> 2) & 0x3;
|
|
SpacingType spacing = ((value & 2) == 2) ? kDouble : kSingle;
|
|
return DecodeNeonAndAlign(lane, spacing, align);
|
|
}
|
|
case Untyped32: {
|
|
AlignmentType align;
|
|
if ((value & 3) == 1) {
|
|
align = k64BitAlign;
|
|
} else if ((value & 3) == 0) {
|
|
align = kNoAlignment;
|
|
} else {
|
|
break;
|
|
}
|
|
int lane = (value >> 3) & 0x1;
|
|
SpacingType spacing = ((value & 4) == 4) ? kDouble : kSingle;
|
|
return DecodeNeonAndAlign(lane, spacing, align);
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return DecodeNeonAndAlign();
|
|
}
|
|
|
|
DecodeNeonAndAlign Align_index_align_3_Decode(uint32_t value, DataType dt) {
|
|
switch (dt.GetValue()) {
|
|
case Untyped8: {
|
|
AlignmentType align;
|
|
if ((value & 1) == 1) {
|
|
align = k32BitAlign;
|
|
} else if ((value & 1) == 0) {
|
|
align = kNoAlignment;
|
|
} else {
|
|
break;
|
|
}
|
|
int lane = (value >> 1) & 0x7;
|
|
SpacingType spacing = kSingle;
|
|
return DecodeNeonAndAlign(lane, spacing, align);
|
|
}
|
|
case Untyped16: {
|
|
AlignmentType align;
|
|
if ((value & 1) == 1) {
|
|
align = k64BitAlign;
|
|
} else if ((value & 1) == 0) {
|
|
align = kNoAlignment;
|
|
} else {
|
|
break;
|
|
}
|
|
int lane = (value >> 2) & 0x3;
|
|
SpacingType spacing = ((value & 2) == 2) ? kDouble : kSingle;
|
|
return DecodeNeonAndAlign(lane, spacing, align);
|
|
}
|
|
case Untyped32: {
|
|
AlignmentType align;
|
|
if ((value & 3) == 1) {
|
|
align = k64BitAlign;
|
|
} else if ((value & 3) == 2) {
|
|
align = k128BitAlign;
|
|
} else if ((value & 3) == 0) {
|
|
align = kNoAlignment;
|
|
} else {
|
|
break;
|
|
}
|
|
int lane = (value >> 3) & 0x1;
|
|
SpacingType spacing = ((value & 4) == 4) ? kDouble : kSingle;
|
|
return DecodeNeonAndAlign(lane, spacing, align);
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return DecodeNeonAndAlign();
|
|
}
|
|
|
|
Alignment Align_a_1_Decode(uint32_t value, DataType dt) {
|
|
switch (value) {
|
|
case 0:
|
|
return kNoAlignment;
|
|
case 1:
|
|
if (dt.Is(Untyped16)) return k16BitAlign;
|
|
if (dt.Is(Untyped32)) return k32BitAlign;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return kBadAlignment;
|
|
}
|
|
|
|
Alignment Align_a_2_Decode(uint32_t value, DataType dt) {
|
|
switch (value) {
|
|
case 0:
|
|
return kNoAlignment;
|
|
case 1:
|
|
if (dt.Is(Untyped8)) return k16BitAlign;
|
|
if (dt.Is(Untyped16)) return k32BitAlign;
|
|
if (dt.Is(Untyped32)) return k64BitAlign;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return kBadAlignment;
|
|
}
|
|
|
|
Alignment Align_a_3_Decode(uint32_t value, DataType dt, uint32_t size) {
|
|
switch (value) {
|
|
case 0:
|
|
if (size != 3) return kNoAlignment;
|
|
break;
|
|
case 1:
|
|
if (dt.Is(Untyped8)) return k32BitAlign;
|
|
if (dt.Is(Untyped16)) return k64BitAlign;
|
|
if (size == 2) return k64BitAlign;
|
|
if (size == 3) return k128BitAlign;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return kBadAlignment;
|
|
}
|
|
|
|
Alignment Align_align_1_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0:
|
|
return kNoAlignment;
|
|
case 1:
|
|
return k64BitAlign;
|
|
case 2:
|
|
return k128BitAlign;
|
|
case 3:
|
|
return k256BitAlign;
|
|
default:
|
|
break;
|
|
}
|
|
return kBadAlignment;
|
|
}
|
|
|
|
Alignment Align_align_2_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0:
|
|
return kNoAlignment;
|
|
case 1:
|
|
return k64BitAlign;
|
|
case 2:
|
|
return k128BitAlign;
|
|
case 3:
|
|
return k256BitAlign;
|
|
default:
|
|
break;
|
|
}
|
|
return kBadAlignment;
|
|
}
|
|
|
|
Alignment Align_align_3_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0:
|
|
return kNoAlignment;
|
|
case 1:
|
|
return k64BitAlign;
|
|
default:
|
|
break;
|
|
}
|
|
return kBadAlignment;
|
|
}
|
|
|
|
Alignment Align_align_4_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0:
|
|
return kNoAlignment;
|
|
case 1:
|
|
return k64BitAlign;
|
|
case 2:
|
|
return k128BitAlign;
|
|
case 3:
|
|
return k256BitAlign;
|
|
default:
|
|
break;
|
|
}
|
|
return kBadAlignment;
|
|
}
|
|
|
|
Alignment Align_align_5_Decode(uint32_t value) {
|
|
switch (value) {
|
|
case 0:
|
|
return kNoAlignment;
|
|
case 1:
|
|
return k64BitAlign;
|
|
case 2:
|
|
return k128BitAlign;
|
|
case 3:
|
|
return k256BitAlign;
|
|
default:
|
|
break;
|
|
}
|
|
return kBadAlignment;
|
|
}
|
|
|
|
|
|
void Disassembler::adc(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kAdc, kArithmetic);
|
|
os() << ToCString(kAdc) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::adcs(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kAdcs, kArithmetic);
|
|
os() << ToCString(kAdcs) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::add(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kAdd, kArithmetic);
|
|
os() << ToCString(kAdd) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::add(Condition cond, Register rd, const Operand& operand) {
|
|
os().SetCurrentInstruction(kAdd, kArithmetic);
|
|
os() << ToCString(kAdd) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << operand;
|
|
}
|
|
|
|
void Disassembler::adds(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kAdds, kArithmetic);
|
|
os() << ToCString(kAdds) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::adds(Register rd, const Operand& operand) {
|
|
os().SetCurrentInstruction(kAdds, kArithmetic);
|
|
os() << ToCString(kAdds) << " " << rd << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::addw(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kAddw, kArithmetic);
|
|
os() << ToCString(kAddw) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::adr(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Location* location) {
|
|
os().SetCurrentInstruction(kAdr, kAddress);
|
|
os() << ToCString(kAdr) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rd << ", "
|
|
<< PrintLabel(kAnyLocation, location, GetCodeAddress() & ~3);
|
|
}
|
|
|
|
void Disassembler::and_(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kAnd, kBitwise);
|
|
os() << ToCString(kAnd) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::ands(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kAnds, kBitwise);
|
|
os() << ToCString(kAnds) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::asr(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rm,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kAsr, kShift);
|
|
os() << ToCString(kAsr) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::asrs(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rm,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kAsrs, kShift);
|
|
os() << ToCString(kAsrs) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::b(Condition cond, EncodingSize size, Location* location) {
|
|
os().SetCurrentInstruction(kB, kAddress | kBranch);
|
|
os() << ToCString(kB) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< PrintLabel(kCodeLocation, location, GetCodeAddress());
|
|
}
|
|
|
|
void Disassembler::bfc(Condition cond,
|
|
Register rd,
|
|
uint32_t lsb,
|
|
uint32_t width) {
|
|
os().SetCurrentInstruction(kBfc, kShift);
|
|
os() << ToCString(kBfc) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << ImmediatePrinter(lsb) << ", " << ImmediatePrinter(width);
|
|
}
|
|
|
|
void Disassembler::bfi(
|
|
Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) {
|
|
os().SetCurrentInstruction(kBfi, kShift);
|
|
os() << ToCString(kBfi) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << ImmediatePrinter(lsb) << ", "
|
|
<< ImmediatePrinter(width);
|
|
}
|
|
|
|
void Disassembler::bic(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kBic, kBitwise);
|
|
os() << ToCString(kBic) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::bics(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kBics, kBitwise);
|
|
os() << ToCString(kBics) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::bkpt(Condition cond, uint32_t imm) {
|
|
os().SetCurrentInstruction(kBkpt, kSystem);
|
|
os() << ToCString(kBkpt) << ConditionPrinter(it_block_, cond) << " "
|
|
<< RawImmediatePrinter(imm);
|
|
}
|
|
|
|
void Disassembler::bl(Condition cond, Location* location) {
|
|
os().SetCurrentInstruction(kBl, kAddress | kBranch);
|
|
os() << ToCString(kBl) << ConditionPrinter(it_block_, cond) << " "
|
|
<< PrintLabel(kCodeLocation, location, GetCodeAddress());
|
|
}
|
|
|
|
void Disassembler::blx(Condition cond, Location* location) {
|
|
os().SetCurrentInstruction(kBlx, kAddress | kBranch);
|
|
os() << ToCString(kBlx) << ConditionPrinter(it_block_, cond) << " "
|
|
<< PrintLabel(kCodeLocation, location, GetCodeAddress() & ~3);
|
|
}
|
|
|
|
void Disassembler::blx(Condition cond, Register rm) {
|
|
os().SetCurrentInstruction(kBlx, kAddress | kBranch);
|
|
os() << ToCString(kBlx) << ConditionPrinter(it_block_, cond) << " " << rm;
|
|
}
|
|
|
|
void Disassembler::bx(Condition cond, Register rm) {
|
|
os().SetCurrentInstruction(kBx, kAddress | kBranch);
|
|
os() << ToCString(kBx) << ConditionPrinter(it_block_, cond) << " " << rm;
|
|
}
|
|
|
|
void Disassembler::bxj(Condition cond, Register rm) {
|
|
os().SetCurrentInstruction(kBxj, kAddress | kBranch);
|
|
os() << ToCString(kBxj) << ConditionPrinter(it_block_, cond) << " " << rm;
|
|
}
|
|
|
|
void Disassembler::cbnz(Register rn, Location* location) {
|
|
os().SetCurrentInstruction(kCbnz, kAddress | kBranch);
|
|
os() << ToCString(kCbnz) << " " << rn << ", "
|
|
<< PrintLabel(kCodeLocation, location, GetCodeAddress());
|
|
}
|
|
|
|
void Disassembler::cbz(Register rn, Location* location) {
|
|
os().SetCurrentInstruction(kCbz, kAddress | kBranch);
|
|
os() << ToCString(kCbz) << " " << rn << ", "
|
|
<< PrintLabel(kCodeLocation, location, GetCodeAddress());
|
|
}
|
|
|
|
void Disassembler::clrex(Condition cond) {
|
|
os().SetCurrentInstruction(kClrex, kNoAttribute);
|
|
os() << ToCString(kClrex) << ConditionPrinter(it_block_, cond);
|
|
}
|
|
|
|
void Disassembler::clz(Condition cond, Register rd, Register rm) {
|
|
os().SetCurrentInstruction(kClz, kNoAttribute);
|
|
os() << ToCString(kClz) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rm;
|
|
}
|
|
|
|
void Disassembler::cmn(Condition cond,
|
|
EncodingSize size,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kCmn, kArithmetic);
|
|
os() << ToCString(kCmn) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::cmp(Condition cond,
|
|
EncodingSize size,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kCmp, kArithmetic);
|
|
os() << ToCString(kCmp) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::crc32b(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kCrc32b, kNoAttribute);
|
|
os() << ToCString(kCrc32b) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::crc32cb(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kCrc32cb, kNoAttribute);
|
|
os() << ToCString(kCrc32cb) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::crc32ch(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kCrc32ch, kNoAttribute);
|
|
os() << ToCString(kCrc32ch) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::crc32cw(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kCrc32cw, kNoAttribute);
|
|
os() << ToCString(kCrc32cw) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::crc32h(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kCrc32h, kNoAttribute);
|
|
os() << ToCString(kCrc32h) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::crc32w(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kCrc32w, kNoAttribute);
|
|
os() << ToCString(kCrc32w) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::dmb(Condition cond, MemoryBarrier option) {
|
|
os().SetCurrentInstruction(kDmb, kNoAttribute);
|
|
os() << ToCString(kDmb) << ConditionPrinter(it_block_, cond) << " " << option;
|
|
}
|
|
|
|
void Disassembler::dsb(Condition cond, MemoryBarrier option) {
|
|
os().SetCurrentInstruction(kDsb, kNoAttribute);
|
|
os() << ToCString(kDsb) << ConditionPrinter(it_block_, cond) << " " << option;
|
|
}
|
|
|
|
void Disassembler::eor(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kEor, kBitwise);
|
|
os() << ToCString(kEor) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::eors(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kEors, kBitwise);
|
|
os() << ToCString(kEors) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::fldmdbx(Condition cond,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
DRegisterList dreglist) {
|
|
os().SetCurrentInstruction(kFldmdbx,
|
|
kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kFldmdbx) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< write_back << ", " << dreglist;
|
|
}
|
|
|
|
void Disassembler::fldmiax(Condition cond,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
DRegisterList dreglist) {
|
|
os().SetCurrentInstruction(kFldmiax,
|
|
kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kFldmiax) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< write_back << ", " << dreglist;
|
|
}
|
|
|
|
void Disassembler::fstmdbx(Condition cond,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
DRegisterList dreglist) {
|
|
os().SetCurrentInstruction(kFstmdbx,
|
|
kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kFstmdbx) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< write_back << ", " << dreglist;
|
|
}
|
|
|
|
void Disassembler::fstmiax(Condition cond,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
DRegisterList dreglist) {
|
|
os().SetCurrentInstruction(kFstmiax,
|
|
kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kFstmiax) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< write_back << ", " << dreglist;
|
|
}
|
|
|
|
void Disassembler::hlt(Condition cond, uint32_t imm) {
|
|
os().SetCurrentInstruction(kHlt, kSystem);
|
|
os() << ToCString(kHlt) << ConditionPrinter(it_block_, cond) << " "
|
|
<< RawImmediatePrinter(imm);
|
|
}
|
|
|
|
void Disassembler::hvc(Condition cond, uint32_t imm) {
|
|
os().SetCurrentInstruction(kHvc, kSystem);
|
|
os() << ToCString(kHvc) << ConditionPrinter(it_block_, cond) << " "
|
|
<< RawImmediatePrinter(imm);
|
|
}
|
|
|
|
void Disassembler::isb(Condition cond, MemoryBarrier option) {
|
|
os().SetCurrentInstruction(kIsb, kNoAttribute);
|
|
os() << ToCString(kIsb) << ConditionPrinter(it_block_, cond) << " " << option;
|
|
}
|
|
|
|
void Disassembler::it(Condition cond, uint16_t mask) {
|
|
os().SetCurrentInstruction(kIt, kNoAttribute);
|
|
os() << ToCString(kIt);
|
|
int count;
|
|
if ((mask & 0x1) != 0) {
|
|
count = 3;
|
|
} else if ((mask & 0x2) != 0) {
|
|
count = 2;
|
|
} else if ((mask & 0x4) != 0) {
|
|
count = 1;
|
|
} else {
|
|
count = 0;
|
|
}
|
|
uint16_t tmp = 0x8;
|
|
uint16_t ref = (cond.GetCondition() & 0x1) << 3;
|
|
while (count-- > 0) {
|
|
os() << (((mask & tmp) == ref) ? "t" : "e");
|
|
tmp >>= 1;
|
|
ref >>= 1;
|
|
}
|
|
if (cond.Is(al)) {
|
|
os() << " al";
|
|
} else {
|
|
os() << " " << cond;
|
|
}
|
|
}
|
|
|
|
void Disassembler::lda(Condition cond, Register rt, const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLda, kAddress | kLoadStore);
|
|
os() << ToCString(kLda) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << PrintMemOperand(kLoadWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldab(Condition cond,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdab, kAddress | kLoadStore);
|
|
os() << ToCString(kLdab) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << PrintMemOperand(kLoadByteLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldaex(Condition cond,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdaex, kAddress | kLoadStore);
|
|
os() << ToCString(kLdaex) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << PrintMemOperand(kLoadWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldaexb(Condition cond,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdaexb, kAddress | kLoadStore);
|
|
os() << ToCString(kLdaexb) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << PrintMemOperand(kLoadByteLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldaexd(Condition cond,
|
|
Register rt,
|
|
Register rt2,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdaexd, kAddress | kLoadStore);
|
|
os() << ToCString(kLdaexd) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << rt2 << ", "
|
|
<< PrintMemOperand(kLoadDoubleWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldaexh(Condition cond,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdaexh, kAddress | kLoadStore);
|
|
os() << ToCString(kLdaexh) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << PrintMemOperand(kLoadHalfWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldah(Condition cond,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdah, kAddress | kLoadStore);
|
|
os() << ToCString(kLdah) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << PrintMemOperand(kLoadHalfWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldm(Condition cond,
|
|
EncodingSize size,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kLdm, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kLdm) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rn << write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::ldmda(Condition cond,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kLdmda, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kLdmda) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::ldmdb(Condition cond,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kLdmdb, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kLdmdb) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::ldmea(Condition cond,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kLdmea, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kLdmea) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::ldmed(Condition cond,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kLdmed, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kLdmed) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::ldmfa(Condition cond,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kLdmfa, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kLdmfa) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::ldmfd(Condition cond,
|
|
EncodingSize size,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kLdmfd, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kLdmfd) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rn << write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::ldmib(Condition cond,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kLdmib, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kLdmib) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::ldr(Condition cond,
|
|
EncodingSize size,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdr, kAddress | kLoadStore);
|
|
os() << ToCString(kLdr) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rt << ", " << PrintMemOperand(kLoadWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldr(Condition cond,
|
|
EncodingSize size,
|
|
Register rt,
|
|
Location* location) {
|
|
os().SetCurrentInstruction(kLdr, kAddress | kLoadStore);
|
|
os() << ToCString(kLdr) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rt << ", "
|
|
<< PrintLabel(kLoadWordLocation, location, GetCodeAddress() & ~3);
|
|
}
|
|
|
|
void Disassembler::ldrb(Condition cond,
|
|
EncodingSize size,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdrb, kAddress | kLoadStore);
|
|
os() << ToCString(kLdrb) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rt << ", " << PrintMemOperand(kLoadByteLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldrb(Condition cond, Register rt, Location* location) {
|
|
os().SetCurrentInstruction(kLdrb, kAddress | kLoadStore);
|
|
os() << ToCString(kLdrb) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", "
|
|
<< PrintLabel(kLoadByteLocation, location, GetCodeAddress() & ~3);
|
|
}
|
|
|
|
void Disassembler::ldrd(Condition cond,
|
|
Register rt,
|
|
Register rt2,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdrd, kAddress | kLoadStore);
|
|
os() << ToCString(kLdrd) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << rt2 << ", "
|
|
<< PrintMemOperand(kLoadDoubleWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldrd(Condition cond,
|
|
Register rt,
|
|
Register rt2,
|
|
Location* location) {
|
|
os().SetCurrentInstruction(kLdrd, kAddress | kLoadStore);
|
|
os() << ToCString(kLdrd) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << rt2 << ", "
|
|
<< PrintLabel(kLoadDoubleWordLocation, location, GetCodeAddress() & ~3);
|
|
}
|
|
|
|
void Disassembler::ldrex(Condition cond,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdrex, kAddress | kLoadStore);
|
|
os() << ToCString(kLdrex) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << PrintMemOperand(kLoadWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldrexb(Condition cond,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdrexb, kAddress | kLoadStore);
|
|
os() << ToCString(kLdrexb) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << PrintMemOperand(kLoadByteLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldrexd(Condition cond,
|
|
Register rt,
|
|
Register rt2,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdrexd, kAddress | kLoadStore);
|
|
os() << ToCString(kLdrexd) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << rt2 << ", "
|
|
<< PrintMemOperand(kLoadDoubleWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldrexh(Condition cond,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdrexh, kAddress | kLoadStore);
|
|
os() << ToCString(kLdrexh) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << PrintMemOperand(kLoadHalfWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldrh(Condition cond,
|
|
EncodingSize size,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdrh, kAddress | kLoadStore);
|
|
os() << ToCString(kLdrh) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rt << ", " << PrintMemOperand(kLoadHalfWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldrh(Condition cond, Register rt, Location* location) {
|
|
os().SetCurrentInstruction(kLdrh, kAddress | kLoadStore);
|
|
os() << ToCString(kLdrh) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", "
|
|
<< PrintLabel(kLoadHalfWordLocation, location, GetCodeAddress() & ~3);
|
|
}
|
|
|
|
void Disassembler::ldrsb(Condition cond,
|
|
EncodingSize size,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdrsb, kAddress | kLoadStore);
|
|
os() << ToCString(kLdrsb) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rt << ", " << PrintMemOperand(kLoadSignedByteLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldrsb(Condition cond, Register rt, Location* location) {
|
|
os().SetCurrentInstruction(kLdrsb, kAddress | kLoadStore);
|
|
os() << ToCString(kLdrsb) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", "
|
|
<< PrintLabel(kLoadSignedByteLocation, location, GetCodeAddress() & ~3);
|
|
}
|
|
|
|
void Disassembler::ldrsh(Condition cond,
|
|
EncodingSize size,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kLdrsh, kAddress | kLoadStore);
|
|
os() << ToCString(kLdrsh) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rt << ", " << PrintMemOperand(kLoadSignedHalfWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::ldrsh(Condition cond, Register rt, Location* location) {
|
|
os().SetCurrentInstruction(kLdrsh, kAddress | kLoadStore);
|
|
os() << ToCString(kLdrsh) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << PrintLabel(kLoadSignedHalfWordLocation,
|
|
location,
|
|
GetCodeAddress() & ~3);
|
|
}
|
|
|
|
void Disassembler::lsl(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rm,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kLsl, kShift);
|
|
os() << ToCString(kLsl) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::lsls(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rm,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kLsls, kShift);
|
|
os() << ToCString(kLsls) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::lsr(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rm,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kLsr, kShift);
|
|
os() << ToCString(kLsr) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::lsrs(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rm,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kLsrs, kShift);
|
|
os() << ToCString(kLsrs) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::mla(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kMla, kArithmetic);
|
|
os() << ToCString(kMla) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::mlas(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kMlas, kArithmetic);
|
|
os() << ToCString(kMlas) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::mls(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kMls, kArithmetic);
|
|
os() << ToCString(kMls) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::mov(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kMov, kNoAttribute);
|
|
os() << ToCString(kMov) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rd << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::movs(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kMovs, kNoAttribute);
|
|
os() << ToCString(kMovs) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rd << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::movt(Condition cond, Register rd, const Operand& operand) {
|
|
os().SetCurrentInstruction(kMovt, kNoAttribute);
|
|
os() << ToCString(kMovt) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << operand;
|
|
}
|
|
|
|
void Disassembler::movw(Condition cond, Register rd, const Operand& operand) {
|
|
os().SetCurrentInstruction(kMovw, kNoAttribute);
|
|
os() << ToCString(kMovw) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << operand;
|
|
}
|
|
|
|
void Disassembler::mrs(Condition cond, Register rd, SpecialRegister spec_reg) {
|
|
os().SetCurrentInstruction(kMrs, kNoAttribute);
|
|
os() << ToCString(kMrs) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << spec_reg;
|
|
}
|
|
|
|
void Disassembler::msr(Condition cond,
|
|
MaskedSpecialRegister spec_reg,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kMsr, kNoAttribute);
|
|
os() << ToCString(kMsr) << ConditionPrinter(it_block_, cond) << " "
|
|
<< spec_reg << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::mul(
|
|
Condition cond, EncodingSize size, Register rd, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kMul, kArithmetic);
|
|
os() << ToCString(kMul) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::muls(Condition cond, Register rd, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kMuls, kArithmetic);
|
|
os() << ToCString(kMuls) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::mvn(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kMvn, kNoAttribute);
|
|
os() << ToCString(kMvn) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rd << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::mvns(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kMvns, kNoAttribute);
|
|
os() << ToCString(kMvns) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rd << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::nop(Condition cond, EncodingSize size) {
|
|
os().SetCurrentInstruction(kNop, kNoAttribute);
|
|
os() << ToCString(kNop) << ConditionPrinter(it_block_, cond) << size;
|
|
}
|
|
|
|
void Disassembler::orn(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kOrn, kBitwise);
|
|
os() << ToCString(kOrn) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::orns(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kOrns, kBitwise);
|
|
os() << ToCString(kOrns) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::orr(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kOrr, kBitwise);
|
|
os() << ToCString(kOrr) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::orrs(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kOrrs, kBitwise);
|
|
os() << ToCString(kOrrs) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::pkhbt(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kPkhbt, kNoAttribute);
|
|
os() << ToCString(kPkhbt) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::pkhtb(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kPkhtb, kNoAttribute);
|
|
os() << ToCString(kPkhtb) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::pld(Condition cond, Location* location) {
|
|
os().SetCurrentInstruction(kPld, kAddress);
|
|
os() << ToCString(kPld) << ConditionPrinter(it_block_, cond) << " "
|
|
<< PrintLabel(kDataLocation, location, GetCodeAddress() & ~3);
|
|
}
|
|
|
|
void Disassembler::pld(Condition cond, const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kPld, kAddress);
|
|
os() << ToCString(kPld) << ConditionPrinter(it_block_, cond) << " "
|
|
<< PrintMemOperand(kDataLocation, operand);
|
|
}
|
|
|
|
void Disassembler::pldw(Condition cond, const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kPldw, kAddress);
|
|
os() << ToCString(kPldw) << ConditionPrinter(it_block_, cond) << " "
|
|
<< PrintMemOperand(kDataLocation, operand);
|
|
}
|
|
|
|
void Disassembler::pli(Condition cond, const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kPli, kAddress);
|
|
os() << ToCString(kPli) << ConditionPrinter(it_block_, cond) << " "
|
|
<< PrintMemOperand(kCodeLocation, operand);
|
|
}
|
|
|
|
void Disassembler::pli(Condition cond, Location* location) {
|
|
os().SetCurrentInstruction(kPli, kAddress);
|
|
os() << ToCString(kPli) << ConditionPrinter(it_block_, cond) << " "
|
|
<< PrintLabel(kCodeLocation, location, GetCodeAddress() & ~3);
|
|
}
|
|
|
|
void Disassembler::pop(Condition cond,
|
|
EncodingSize size,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kPop, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kPop) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< registers;
|
|
}
|
|
|
|
void Disassembler::pop(Condition cond, EncodingSize size, Register rt) {
|
|
os().SetCurrentInstruction(kPop, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kPop) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< "{" << rt << "}";
|
|
}
|
|
|
|
void Disassembler::push(Condition cond,
|
|
EncodingSize size,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kPush, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kPush) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< registers;
|
|
}
|
|
|
|
void Disassembler::push(Condition cond, EncodingSize size, Register rt) {
|
|
os().SetCurrentInstruction(kPush, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kPush) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< "{" << rt << "}";
|
|
}
|
|
|
|
void Disassembler::qadd(Condition cond, Register rd, Register rm, Register rn) {
|
|
os().SetCurrentInstruction(kQadd, kArithmetic);
|
|
os() << ToCString(kQadd) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << rn;
|
|
}
|
|
|
|
void Disassembler::qadd16(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kQadd16, kArithmetic);
|
|
os() << ToCString(kQadd16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::qadd8(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kQadd8, kArithmetic);
|
|
os() << ToCString(kQadd8) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::qasx(Condition cond, Register rd, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kQasx, kArithmetic);
|
|
os() << ToCString(kQasx) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::qdadd(Condition cond,
|
|
Register rd,
|
|
Register rm,
|
|
Register rn) {
|
|
os().SetCurrentInstruction(kQdadd, kArithmetic);
|
|
os() << ToCString(kQdadd) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << rn;
|
|
}
|
|
|
|
void Disassembler::qdsub(Condition cond,
|
|
Register rd,
|
|
Register rm,
|
|
Register rn) {
|
|
os().SetCurrentInstruction(kQdsub, kArithmetic);
|
|
os() << ToCString(kQdsub) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << rn;
|
|
}
|
|
|
|
void Disassembler::qsax(Condition cond, Register rd, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kQsax, kArithmetic);
|
|
os() << ToCString(kQsax) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::qsub(Condition cond, Register rd, Register rm, Register rn) {
|
|
os().SetCurrentInstruction(kQsub, kArithmetic);
|
|
os() << ToCString(kQsub) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << rn;
|
|
}
|
|
|
|
void Disassembler::qsub16(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kQsub16, kArithmetic);
|
|
os() << ToCString(kQsub16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::qsub8(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kQsub8, kArithmetic);
|
|
os() << ToCString(kQsub8) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::rbit(Condition cond, Register rd, Register rm) {
|
|
os().SetCurrentInstruction(kRbit, kNoAttribute);
|
|
os() << ToCString(kRbit) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rm;
|
|
}
|
|
|
|
void Disassembler::rev(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kRev, kNoAttribute);
|
|
os() << ToCString(kRev) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::rev16(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kRev16, kNoAttribute);
|
|
os() << ToCString(kRev16) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::revsh(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kRevsh, kNoAttribute);
|
|
os() << ToCString(kRevsh) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::ror(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rm,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kRor, kShift);
|
|
os() << ToCString(kRor) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::rors(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rm,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kRors, kShift);
|
|
os() << ToCString(kRors) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::rrx(Condition cond, Register rd, Register rm) {
|
|
os().SetCurrentInstruction(kRrx, kShift);
|
|
os() << ToCString(kRrx) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm;
|
|
}
|
|
|
|
void Disassembler::rrxs(Condition cond, Register rd, Register rm) {
|
|
os().SetCurrentInstruction(kRrxs, kShift);
|
|
os() << ToCString(kRrxs) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm;
|
|
}
|
|
|
|
void Disassembler::rsb(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kRsb, kArithmetic);
|
|
os() << ToCString(kRsb) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::rsbs(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kRsbs, kArithmetic);
|
|
os() << ToCString(kRsbs) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::rsc(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kRsc, kArithmetic);
|
|
os() << ToCString(kRsc) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::rscs(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kRscs, kArithmetic);
|
|
os() << ToCString(kRscs) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::sadd16(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSadd16, kArithmetic);
|
|
os() << ToCString(kSadd16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::sadd8(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSadd8, kArithmetic);
|
|
os() << ToCString(kSadd8) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::sasx(Condition cond, Register rd, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSasx, kArithmetic);
|
|
os() << ToCString(kSasx) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::sbc(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kSbc, kArithmetic);
|
|
os() << ToCString(kSbc) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::sbcs(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kSbcs, kArithmetic);
|
|
os() << ToCString(kSbcs) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::sbfx(
|
|
Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) {
|
|
os().SetCurrentInstruction(kSbfx, kShift);
|
|
os() << ToCString(kSbfx) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << ImmediatePrinter(lsb) << ", "
|
|
<< ImmediatePrinter(width);
|
|
}
|
|
|
|
void Disassembler::sdiv(Condition cond, Register rd, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSdiv, kArithmetic);
|
|
os() << ToCString(kSdiv) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::sel(Condition cond, Register rd, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSel, kNoAttribute);
|
|
os() << ToCString(kSel) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::shadd16(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kShadd16, kArithmetic);
|
|
os() << ToCString(kShadd16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::shadd8(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kShadd8, kArithmetic);
|
|
os() << ToCString(kShadd8) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::shasx(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kShasx, kArithmetic);
|
|
os() << ToCString(kShasx) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::shsax(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kShsax, kArithmetic);
|
|
os() << ToCString(kShsax) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::shsub16(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kShsub16, kArithmetic);
|
|
os() << ToCString(kShsub16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::shsub8(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kShsub8, kArithmetic);
|
|
os() << ToCString(kShsub8) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smlabb(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kSmlabb, kArithmetic);
|
|
os() << ToCString(kSmlabb) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::smlabt(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kSmlabt, kArithmetic);
|
|
os() << ToCString(kSmlabt) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::smlad(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kSmlad, kArithmetic);
|
|
os() << ToCString(kSmlad) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::smladx(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kSmladx, kArithmetic);
|
|
os() << ToCString(kSmladx) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::smlal(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSmlal, kArithmetic);
|
|
os() << ToCString(kSmlal) << ConditionPrinter(it_block_, cond) << " " << rdlo
|
|
<< ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smlalbb(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSmlalbb, kArithmetic);
|
|
os() << ToCString(kSmlalbb) << ConditionPrinter(it_block_, cond) << " "
|
|
<< rdlo << ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smlalbt(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSmlalbt, kArithmetic);
|
|
os() << ToCString(kSmlalbt) << ConditionPrinter(it_block_, cond) << " "
|
|
<< rdlo << ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smlald(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSmlald, kArithmetic);
|
|
os() << ToCString(kSmlald) << ConditionPrinter(it_block_, cond) << " " << rdlo
|
|
<< ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smlaldx(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSmlaldx, kArithmetic);
|
|
os() << ToCString(kSmlaldx) << ConditionPrinter(it_block_, cond) << " "
|
|
<< rdlo << ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smlals(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSmlals, kArithmetic);
|
|
os() << ToCString(kSmlals) << ConditionPrinter(it_block_, cond) << " " << rdlo
|
|
<< ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smlaltb(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSmlaltb, kArithmetic);
|
|
os() << ToCString(kSmlaltb) << ConditionPrinter(it_block_, cond) << " "
|
|
<< rdlo << ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smlaltt(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSmlaltt, kArithmetic);
|
|
os() << ToCString(kSmlaltt) << ConditionPrinter(it_block_, cond) << " "
|
|
<< rdlo << ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smlatb(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kSmlatb, kArithmetic);
|
|
os() << ToCString(kSmlatb) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::smlatt(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kSmlatt, kArithmetic);
|
|
os() << ToCString(kSmlatt) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::smlawb(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kSmlawb, kArithmetic);
|
|
os() << ToCString(kSmlawb) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::smlawt(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kSmlawt, kArithmetic);
|
|
os() << ToCString(kSmlawt) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::smlsd(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kSmlsd, kArithmetic);
|
|
os() << ToCString(kSmlsd) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::smlsdx(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kSmlsdx, kArithmetic);
|
|
os() << ToCString(kSmlsdx) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::smlsld(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSmlsld, kArithmetic);
|
|
os() << ToCString(kSmlsld) << ConditionPrinter(it_block_, cond) << " " << rdlo
|
|
<< ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smlsldx(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSmlsldx, kArithmetic);
|
|
os() << ToCString(kSmlsldx) << ConditionPrinter(it_block_, cond) << " "
|
|
<< rdlo << ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smmla(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kSmmla, kArithmetic);
|
|
os() << ToCString(kSmmla) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::smmlar(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kSmmlar, kArithmetic);
|
|
os() << ToCString(kSmmlar) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::smmls(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kSmmls, kArithmetic);
|
|
os() << ToCString(kSmmls) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::smmlsr(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kSmmlsr, kArithmetic);
|
|
os() << ToCString(kSmmlsr) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::smmul(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSmmul, kArithmetic);
|
|
os() << ToCString(kSmmul) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smmulr(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSmmulr, kArithmetic);
|
|
os() << ToCString(kSmmulr) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smuad(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSmuad, kArithmetic);
|
|
os() << ToCString(kSmuad) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smuadx(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSmuadx, kArithmetic);
|
|
os() << ToCString(kSmuadx) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smulbb(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSmulbb, kArithmetic);
|
|
os() << ToCString(kSmulbb) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smulbt(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSmulbt, kArithmetic);
|
|
os() << ToCString(kSmulbt) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smull(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSmull, kArithmetic);
|
|
os() << ToCString(kSmull) << ConditionPrinter(it_block_, cond) << " " << rdlo
|
|
<< ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smulls(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSmulls, kArithmetic);
|
|
os() << ToCString(kSmulls) << ConditionPrinter(it_block_, cond) << " " << rdlo
|
|
<< ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smultb(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSmultb, kArithmetic);
|
|
os() << ToCString(kSmultb) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smultt(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSmultt, kArithmetic);
|
|
os() << ToCString(kSmultt) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smulwb(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSmulwb, kArithmetic);
|
|
os() << ToCString(kSmulwb) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smulwt(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSmulwt, kArithmetic);
|
|
os() << ToCString(kSmulwt) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smusd(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSmusd, kArithmetic);
|
|
os() << ToCString(kSmusd) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::smusdx(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSmusdx, kArithmetic);
|
|
os() << ToCString(kSmusdx) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::ssat(Condition cond,
|
|
Register rd,
|
|
uint32_t imm,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kSsat, kArithmetic);
|
|
os() << ToCString(kSsat) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << ImmediatePrinter(imm) << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::ssat16(Condition cond,
|
|
Register rd,
|
|
uint32_t imm,
|
|
Register rn) {
|
|
os().SetCurrentInstruction(kSsat16, kArithmetic);
|
|
os() << ToCString(kSsat16) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << ImmediatePrinter(imm) << ", " << rn;
|
|
}
|
|
|
|
void Disassembler::ssax(Condition cond, Register rd, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kSsax, kArithmetic);
|
|
os() << ToCString(kSsax) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::ssub16(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSsub16, kArithmetic);
|
|
os() << ToCString(kSsub16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::ssub8(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kSsub8, kArithmetic);
|
|
os() << ToCString(kSsub8) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::stl(Condition cond, Register rt, const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kStl, kAddress | kLoadStore);
|
|
os() << ToCString(kStl) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << PrintMemOperand(kStoreWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::stlb(Condition cond,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kStlb, kAddress | kLoadStore);
|
|
os() << ToCString(kStlb) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << PrintMemOperand(kStoreByteLocation, operand);
|
|
}
|
|
|
|
void Disassembler::stlex(Condition cond,
|
|
Register rd,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kStlex, kAddress | kLoadStore);
|
|
os() << ToCString(kStlex) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rt << ", " << PrintMemOperand(kStoreWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::stlexb(Condition cond,
|
|
Register rd,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kStlexb, kAddress | kLoadStore);
|
|
os() << ToCString(kStlexb) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rt << ", " << PrintMemOperand(kStoreByteLocation, operand);
|
|
}
|
|
|
|
void Disassembler::stlexd(Condition cond,
|
|
Register rd,
|
|
Register rt,
|
|
Register rt2,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kStlexd, kAddress | kLoadStore);
|
|
os() << ToCString(kStlexd) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rt << ", " << rt2 << ", "
|
|
<< PrintMemOperand(kStoreDoubleWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::stlexh(Condition cond,
|
|
Register rd,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kStlexh, kAddress | kLoadStore);
|
|
os() << ToCString(kStlexh) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rt << ", "
|
|
<< PrintMemOperand(kStoreHalfWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::stlh(Condition cond,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kStlh, kAddress | kLoadStore);
|
|
os() << ToCString(kStlh) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << PrintMemOperand(kStoreHalfWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::stm(Condition cond,
|
|
EncodingSize size,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kStm, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kStm) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rn << write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::stmda(Condition cond,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kStmda, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kStmda) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::stmdb(Condition cond,
|
|
EncodingSize size,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kStmdb, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kStmdb) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rn << write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::stmea(Condition cond,
|
|
EncodingSize size,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kStmea, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kStmea) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rn << write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::stmed(Condition cond,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kStmed, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kStmed) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::stmfa(Condition cond,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kStmfa, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kStmfa) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::stmfd(Condition cond,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kStmfd, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kStmfd) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::stmib(Condition cond,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
RegisterList registers) {
|
|
os().SetCurrentInstruction(kStmib, kLoadStore | kLoadStoreMultiple);
|
|
os() << ToCString(kStmib) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< write_back << ", " << registers;
|
|
}
|
|
|
|
void Disassembler::str(Condition cond,
|
|
EncodingSize size,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kStr, kAddress | kLoadStore);
|
|
os() << ToCString(kStr) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rt << ", " << PrintMemOperand(kStoreWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::strb(Condition cond,
|
|
EncodingSize size,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kStrb, kAddress | kLoadStore);
|
|
os() << ToCString(kStrb) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rt << ", " << PrintMemOperand(kStoreByteLocation, operand);
|
|
}
|
|
|
|
void Disassembler::strd(Condition cond,
|
|
Register rt,
|
|
Register rt2,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kStrd, kAddress | kLoadStore);
|
|
os() << ToCString(kStrd) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << rt2 << ", "
|
|
<< PrintMemOperand(kStoreDoubleWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::strex(Condition cond,
|
|
Register rd,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kStrex, kAddress | kLoadStore);
|
|
os() << ToCString(kStrex) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rt << ", " << PrintMemOperand(kStoreWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::strexb(Condition cond,
|
|
Register rd,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kStrexb, kAddress | kLoadStore);
|
|
os() << ToCString(kStrexb) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rt << ", " << PrintMemOperand(kStoreByteLocation, operand);
|
|
}
|
|
|
|
void Disassembler::strexd(Condition cond,
|
|
Register rd,
|
|
Register rt,
|
|
Register rt2,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kStrexd, kAddress | kLoadStore);
|
|
os() << ToCString(kStrexd) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rt << ", " << rt2 << ", "
|
|
<< PrintMemOperand(kStoreDoubleWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::strexh(Condition cond,
|
|
Register rd,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kStrexh, kAddress | kLoadStore);
|
|
os() << ToCString(kStrexh) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rt << ", "
|
|
<< PrintMemOperand(kStoreHalfWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::strh(Condition cond,
|
|
EncodingSize size,
|
|
Register rt,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kStrh, kAddress | kLoadStore);
|
|
os() << ToCString(kStrh) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rt << ", " << PrintMemOperand(kStoreHalfWordLocation, operand);
|
|
}
|
|
|
|
void Disassembler::sub(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kSub, kArithmetic);
|
|
os() << ToCString(kSub) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::sub(Condition cond, Register rd, const Operand& operand) {
|
|
os().SetCurrentInstruction(kSub, kArithmetic);
|
|
os() << ToCString(kSub) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << operand;
|
|
}
|
|
|
|
void Disassembler::subs(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kSubs, kArithmetic);
|
|
os() << ToCString(kSubs) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::subs(Register rd, const Operand& operand) {
|
|
os().SetCurrentInstruction(kSubs, kArithmetic);
|
|
os() << ToCString(kSubs) << " " << rd << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::subw(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kSubw, kArithmetic);
|
|
os() << ToCString(kSubw) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::svc(Condition cond, uint32_t imm) {
|
|
os().SetCurrentInstruction(kSvc, kSystem);
|
|
os() << ToCString(kSvc) << ConditionPrinter(it_block_, cond) << " "
|
|
<< RawImmediatePrinter(imm);
|
|
}
|
|
|
|
void Disassembler::sxtab(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kSxtab, kArithmetic);
|
|
os() << ToCString(kSxtab) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::sxtab16(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kSxtab16, kArithmetic);
|
|
os() << ToCString(kSxtab16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::sxtah(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kSxtah, kArithmetic);
|
|
os() << ToCString(kSxtah) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::sxtb(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kSxtb, kArithmetic);
|
|
os() << ToCString(kSxtb) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(operand.GetBaseRegister()) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << operand;
|
|
}
|
|
|
|
void Disassembler::sxtb16(Condition cond, Register rd, const Operand& operand) {
|
|
os().SetCurrentInstruction(kSxtb16, kArithmetic);
|
|
os() << ToCString(kSxtb16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(operand.GetBaseRegister()) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << operand;
|
|
}
|
|
|
|
void Disassembler::sxth(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kSxth, kArithmetic);
|
|
os() << ToCString(kSxth) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(operand.GetBaseRegister()) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << operand;
|
|
}
|
|
|
|
void Disassembler::tbb(Condition cond, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kTbb, kBranch);
|
|
os() << ToCString(kTbb) << ConditionPrinter(it_block_, cond) << " "
|
|
<< MemOperand(rn, rm);
|
|
}
|
|
|
|
void Disassembler::tbh(Condition cond, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kTbh, kBranch);
|
|
os() << ToCString(kTbh) << ConditionPrinter(it_block_, cond) << " "
|
|
<< MemOperand(rn, plus, rm, LSL, 1);
|
|
}
|
|
|
|
void Disassembler::teq(Condition cond, Register rn, const Operand& operand) {
|
|
os().SetCurrentInstruction(kTeq, kBitwise);
|
|
os() << ToCString(kTeq) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< ", " << operand;
|
|
}
|
|
|
|
void Disassembler::tst(Condition cond,
|
|
EncodingSize size,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kTst, kBitwise);
|
|
os() << ToCString(kTst) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::uadd16(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUadd16, kArithmetic);
|
|
os() << ToCString(kUadd16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::uadd8(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUadd8, kArithmetic);
|
|
os() << ToCString(kUadd8) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::uasx(Condition cond, Register rd, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kUasx, kArithmetic);
|
|
os() << ToCString(kUasx) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::ubfx(
|
|
Condition cond, Register rd, Register rn, uint32_t lsb, uint32_t width) {
|
|
os().SetCurrentInstruction(kUbfx, kShift);
|
|
os() << ToCString(kUbfx) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << ImmediatePrinter(lsb) << ", "
|
|
<< ImmediatePrinter(width);
|
|
}
|
|
|
|
void Disassembler::udf(Condition cond, EncodingSize size, uint32_t imm) {
|
|
os().SetCurrentInstruction(kUdf, kNoAttribute);
|
|
os() << ToCString(kUdf) << ConditionPrinter(it_block_, cond) << size << " "
|
|
<< RawImmediatePrinter(imm);
|
|
}
|
|
|
|
void Disassembler::udiv(Condition cond, Register rd, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kUdiv, kArithmetic);
|
|
os() << ToCString(kUdiv) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::uhadd16(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUhadd16, kArithmetic);
|
|
os() << ToCString(kUhadd16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::uhadd8(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUhadd8, kArithmetic);
|
|
os() << ToCString(kUhadd8) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::uhasx(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUhasx, kArithmetic);
|
|
os() << ToCString(kUhasx) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::uhsax(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUhsax, kArithmetic);
|
|
os() << ToCString(kUhsax) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::uhsub16(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUhsub16, kArithmetic);
|
|
os() << ToCString(kUhsub16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::uhsub8(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUhsub8, kArithmetic);
|
|
os() << ToCString(kUhsub8) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::umaal(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kUmaal, kArithmetic);
|
|
os() << ToCString(kUmaal) << ConditionPrinter(it_block_, cond) << " " << rdlo
|
|
<< ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::umlal(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kUmlal, kArithmetic);
|
|
os() << ToCString(kUmlal) << ConditionPrinter(it_block_, cond) << " " << rdlo
|
|
<< ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::umlals(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kUmlals, kArithmetic);
|
|
os() << ToCString(kUmlals) << ConditionPrinter(it_block_, cond) << " " << rdlo
|
|
<< ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::umull(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kUmull, kArithmetic);
|
|
os() << ToCString(kUmull) << ConditionPrinter(it_block_, cond) << " " << rdlo
|
|
<< ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::umulls(
|
|
Condition cond, Register rdlo, Register rdhi, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kUmulls, kArithmetic);
|
|
os() << ToCString(kUmulls) << ConditionPrinter(it_block_, cond) << " " << rdlo
|
|
<< ", " << rdhi << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::uqadd16(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUqadd16, kArithmetic);
|
|
os() << ToCString(kUqadd16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::uqadd8(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUqadd8, kArithmetic);
|
|
os() << ToCString(kUqadd8) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::uqasx(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUqasx, kArithmetic);
|
|
os() << ToCString(kUqasx) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::uqsax(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUqsax, kArithmetic);
|
|
os() << ToCString(kUqsax) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::uqsub16(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUqsub16, kArithmetic);
|
|
os() << ToCString(kUqsub16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::uqsub8(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUqsub8, kArithmetic);
|
|
os() << ToCString(kUqsub8) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::usad8(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUsad8, kArithmetic);
|
|
os() << ToCString(kUsad8) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::usada8(
|
|
Condition cond, Register rd, Register rn, Register rm, Register ra) {
|
|
os().SetCurrentInstruction(kUsada8, kArithmetic);
|
|
os() << ToCString(kUsada8) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << rn << ", " << rm << ", " << ra;
|
|
}
|
|
|
|
void Disassembler::usat(Condition cond,
|
|
Register rd,
|
|
uint32_t imm,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kUsat, kArithmetic);
|
|
os() << ToCString(kUsat) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << ImmediatePrinter(imm) << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::usat16(Condition cond,
|
|
Register rd,
|
|
uint32_t imm,
|
|
Register rn) {
|
|
os().SetCurrentInstruction(kUsat16, kArithmetic);
|
|
os() << ToCString(kUsat16) << ConditionPrinter(it_block_, cond) << " " << rd
|
|
<< ", " << ImmediatePrinter(imm) << ", " << rn;
|
|
}
|
|
|
|
void Disassembler::usax(Condition cond, Register rd, Register rn, Register rm) {
|
|
os().SetCurrentInstruction(kUsax, kArithmetic);
|
|
os() << ToCString(kUsax) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::usub16(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUsub16, kArithmetic);
|
|
os() << ToCString(kUsub16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::usub8(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
Register rm) {
|
|
os().SetCurrentInstruction(kUsub8, kArithmetic);
|
|
os() << ToCString(kUsub8) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::uxtab(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kUxtab, kArithmetic);
|
|
os() << ToCString(kUxtab) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::uxtab16(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kUxtab16, kArithmetic);
|
|
os() << ToCString(kUxtab16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::uxtah(Condition cond,
|
|
Register rd,
|
|
Register rn,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kUxtah, kArithmetic);
|
|
os() << ToCString(kUxtah) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::uxtb(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kUxtb, kArithmetic);
|
|
os() << ToCString(kUxtb) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(operand.GetBaseRegister()) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << operand;
|
|
}
|
|
|
|
void Disassembler::uxtb16(Condition cond, Register rd, const Operand& operand) {
|
|
os().SetCurrentInstruction(kUxtb16, kArithmetic);
|
|
os() << ToCString(kUxtb16) << ConditionPrinter(it_block_, cond);
|
|
os() << " ";
|
|
if (!rd.Is(operand.GetBaseRegister()) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << operand;
|
|
}
|
|
|
|
void Disassembler::uxth(Condition cond,
|
|
EncodingSize size,
|
|
Register rd,
|
|
const Operand& operand) {
|
|
os().SetCurrentInstruction(kUxth, kArithmetic);
|
|
os() << ToCString(kUxth) << ConditionPrinter(it_block_, cond) << size;
|
|
os() << " ";
|
|
if (!rd.Is(operand.GetBaseRegister()) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << operand;
|
|
}
|
|
|
|
void Disassembler::vaba(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVaba, kFpNeon);
|
|
os() << ToCString(kVaba) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vaba(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVaba, kFpNeon);
|
|
os() << ToCString(kVaba) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vabal(
|
|
Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVabal, kFpNeon);
|
|
os() << ToCString(kVabal) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vabd(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVabd, kFpNeon);
|
|
os() << ToCString(kVabd) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vabd(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVabd, kFpNeon);
|
|
os() << ToCString(kVabd) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vabdl(
|
|
Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVabdl, kFpNeon);
|
|
os() << ToCString(kVabdl) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vabs(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVabs, kFpNeon);
|
|
os() << ToCString(kVabs) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vabs(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVabs, kFpNeon);
|
|
os() << ToCString(kVabs) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vabs(Condition cond,
|
|
DataType dt,
|
|
SRegister rd,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVabs, kFpNeon);
|
|
os() << ToCString(kVabs) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vacge(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVacge, kFpNeon);
|
|
os() << ToCString(kVacge) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vacge(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVacge, kFpNeon);
|
|
os() << ToCString(kVacge) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vacgt(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVacgt, kFpNeon);
|
|
os() << ToCString(kVacgt) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vacgt(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVacgt, kFpNeon);
|
|
os() << ToCString(kVacgt) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vacle(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVacle, kFpNeon);
|
|
os() << ToCString(kVacle) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vacle(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVacle, kFpNeon);
|
|
os() << ToCString(kVacle) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vaclt(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVaclt, kFpNeon);
|
|
os() << ToCString(kVaclt) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vaclt(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVaclt, kFpNeon);
|
|
os() << ToCString(kVaclt) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vadd(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVadd, kFpNeon);
|
|
os() << ToCString(kVadd) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vadd(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVadd, kFpNeon);
|
|
os() << ToCString(kVadd) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vadd(
|
|
Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
|
|
os().SetCurrentInstruction(kVadd, kFpNeon);
|
|
os() << ToCString(kVadd) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vaddhn(
|
|
Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVaddhn, kFpNeon);
|
|
os() << ToCString(kVaddhn) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vaddl(
|
|
Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVaddl, kFpNeon);
|
|
os() << ToCString(kVaddl) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vaddw(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVaddw, kFpNeon);
|
|
os() << ToCString(kVaddw) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vand(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rn,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVand, kFpNeon);
|
|
os() << ToCString(kVand) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vand(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rn,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVand, kFpNeon);
|
|
os() << ToCString(kVand) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vbic(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rn,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVbic, kFpNeon);
|
|
os() << ToCString(kVbic) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vbic(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rn,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVbic, kFpNeon);
|
|
os() << ToCString(kVbic) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vbif(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVbif, kFpNeon);
|
|
os() << ToCString(kVbif) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vbif(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVbif, kFpNeon);
|
|
os() << ToCString(kVbif) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vbit(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVbit, kFpNeon);
|
|
os() << ToCString(kVbit) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vbit(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVbit, kFpNeon);
|
|
os() << ToCString(kVbit) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vbsl(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVbsl, kFpNeon);
|
|
os() << ToCString(kVbsl) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vbsl(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVbsl, kFpNeon);
|
|
os() << ToCString(kVbsl) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vceq(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVceq, kFpNeon);
|
|
os() << ToCString(kVceq) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vceq(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVceq, kFpNeon);
|
|
os() << ToCString(kVceq) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vceq(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVceq, kFpNeon);
|
|
os() << ToCString(kVceq) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vceq(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVceq, kFpNeon);
|
|
os() << ToCString(kVceq) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcge(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVcge, kFpNeon);
|
|
os() << ToCString(kVcge) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vcge(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVcge, kFpNeon);
|
|
os() << ToCString(kVcge) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vcge(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVcge, kFpNeon);
|
|
os() << ToCString(kVcge) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcge(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVcge, kFpNeon);
|
|
os() << ToCString(kVcge) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcgt(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVcgt, kFpNeon);
|
|
os() << ToCString(kVcgt) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vcgt(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVcgt, kFpNeon);
|
|
os() << ToCString(kVcgt) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vcgt(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVcgt, kFpNeon);
|
|
os() << ToCString(kVcgt) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcgt(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVcgt, kFpNeon);
|
|
os() << ToCString(kVcgt) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcle(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVcle, kFpNeon);
|
|
os() << ToCString(kVcle) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vcle(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVcle, kFpNeon);
|
|
os() << ToCString(kVcle) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vcle(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVcle, kFpNeon);
|
|
os() << ToCString(kVcle) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcle(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVcle, kFpNeon);
|
|
os() << ToCString(kVcle) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcls(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVcls, kFpNeon);
|
|
os() << ToCString(kVcls) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcls(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVcls, kFpNeon);
|
|
os() << ToCString(kVcls) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vclt(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVclt, kFpNeon);
|
|
os() << ToCString(kVclt) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vclt(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVclt, kFpNeon);
|
|
os() << ToCString(kVclt) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vclt(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVclt, kFpNeon);
|
|
os() << ToCString(kVclt) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vclt(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVclt, kFpNeon);
|
|
os() << ToCString(kVclt) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vclz(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVclz, kFpNeon);
|
|
os() << ToCString(kVclz) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vclz(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVclz, kFpNeon);
|
|
os() << ToCString(kVclz) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcmp(Condition cond,
|
|
DataType dt,
|
|
SRegister rd,
|
|
const SOperand& operand) {
|
|
os().SetCurrentInstruction(kVcmp, kFpNeon);
|
|
os() << ToCString(kVcmp) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vcmp(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVcmp, kFpNeon);
|
|
os() << ToCString(kVcmp) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vcmpe(Condition cond,
|
|
DataType dt,
|
|
SRegister rd,
|
|
const SOperand& operand) {
|
|
os().SetCurrentInstruction(kVcmpe, kFpNeon);
|
|
os() << ToCString(kVcmpe) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vcmpe(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVcmpe, kFpNeon);
|
|
os() << ToCString(kVcmpe) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vcnt(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVcnt, kFpNeon);
|
|
os() << ToCString(kVcnt) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcnt(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVcnt, kFpNeon);
|
|
os() << ToCString(kVcnt) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvt(
|
|
Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
|
|
os().SetCurrentInstruction(kVcvt, kFpNeon);
|
|
os() << ToCString(kVcvt) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvt(
|
|
Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
|
|
os().SetCurrentInstruction(kVcvt, kFpNeon);
|
|
os() << ToCString(kVcvt) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvt(Condition cond,
|
|
DataType dt1,
|
|
DataType dt2,
|
|
DRegister rd,
|
|
DRegister rm,
|
|
int32_t fbits) {
|
|
os().SetCurrentInstruction(kVcvt, kFpNeon);
|
|
os() << ToCString(kVcvt) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm << ", " << SignedImmediatePrinter(fbits);
|
|
}
|
|
|
|
void Disassembler::vcvt(Condition cond,
|
|
DataType dt1,
|
|
DataType dt2,
|
|
QRegister rd,
|
|
QRegister rm,
|
|
int32_t fbits) {
|
|
os().SetCurrentInstruction(kVcvt, kFpNeon);
|
|
os() << ToCString(kVcvt) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm << ", " << SignedImmediatePrinter(fbits);
|
|
}
|
|
|
|
void Disassembler::vcvt(Condition cond,
|
|
DataType dt1,
|
|
DataType dt2,
|
|
SRegister rd,
|
|
SRegister rm,
|
|
int32_t fbits) {
|
|
os().SetCurrentInstruction(kVcvt, kFpNeon);
|
|
os() << ToCString(kVcvt) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm << ", " << SignedImmediatePrinter(fbits);
|
|
}
|
|
|
|
void Disassembler::vcvt(
|
|
Condition cond, DataType dt1, DataType dt2, DRegister rd, DRegister rm) {
|
|
os().SetCurrentInstruction(kVcvt, kFpNeon);
|
|
os() << ToCString(kVcvt) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvt(
|
|
Condition cond, DataType dt1, DataType dt2, QRegister rd, QRegister rm) {
|
|
os().SetCurrentInstruction(kVcvt, kFpNeon);
|
|
os() << ToCString(kVcvt) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvt(
|
|
Condition cond, DataType dt1, DataType dt2, DRegister rd, QRegister rm) {
|
|
os().SetCurrentInstruction(kVcvt, kFpNeon);
|
|
os() << ToCString(kVcvt) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvt(
|
|
Condition cond, DataType dt1, DataType dt2, QRegister rd, DRegister rm) {
|
|
os().SetCurrentInstruction(kVcvt, kFpNeon);
|
|
os() << ToCString(kVcvt) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvt(
|
|
Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
|
|
os().SetCurrentInstruction(kVcvt, kFpNeon);
|
|
os() << ToCString(kVcvt) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvta(DataType dt1,
|
|
DataType dt2,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVcvta, kFpNeon);
|
|
os() << ToCString(kVcvta) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvta(DataType dt1,
|
|
DataType dt2,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVcvta, kFpNeon);
|
|
os() << ToCString(kVcvta) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvta(DataType dt1,
|
|
DataType dt2,
|
|
SRegister rd,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVcvta, kFpNeon);
|
|
os() << ToCString(kVcvta) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvta(DataType dt1,
|
|
DataType dt2,
|
|
SRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVcvta, kFpNeon);
|
|
os() << ToCString(kVcvta) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtb(
|
|
Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtb, kFpNeon);
|
|
os() << ToCString(kVcvtb) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtb(
|
|
Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtb, kFpNeon);
|
|
os() << ToCString(kVcvtb) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtb(
|
|
Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtb, kFpNeon);
|
|
os() << ToCString(kVcvtb) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtm(DataType dt1,
|
|
DataType dt2,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtm, kFpNeon);
|
|
os() << ToCString(kVcvtm) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtm(DataType dt1,
|
|
DataType dt2,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtm, kFpNeon);
|
|
os() << ToCString(kVcvtm) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtm(DataType dt1,
|
|
DataType dt2,
|
|
SRegister rd,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtm, kFpNeon);
|
|
os() << ToCString(kVcvtm) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtm(DataType dt1,
|
|
DataType dt2,
|
|
SRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtm, kFpNeon);
|
|
os() << ToCString(kVcvtm) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtn(DataType dt1,
|
|
DataType dt2,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtn, kFpNeon);
|
|
os() << ToCString(kVcvtn) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtn(DataType dt1,
|
|
DataType dt2,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtn, kFpNeon);
|
|
os() << ToCString(kVcvtn) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtn(DataType dt1,
|
|
DataType dt2,
|
|
SRegister rd,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtn, kFpNeon);
|
|
os() << ToCString(kVcvtn) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtn(DataType dt1,
|
|
DataType dt2,
|
|
SRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtn, kFpNeon);
|
|
os() << ToCString(kVcvtn) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtp(DataType dt1,
|
|
DataType dt2,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtp, kFpNeon);
|
|
os() << ToCString(kVcvtp) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtp(DataType dt1,
|
|
DataType dt2,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtp, kFpNeon);
|
|
os() << ToCString(kVcvtp) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtp(DataType dt1,
|
|
DataType dt2,
|
|
SRegister rd,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtp, kFpNeon);
|
|
os() << ToCString(kVcvtp) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtp(DataType dt1,
|
|
DataType dt2,
|
|
SRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtp, kFpNeon);
|
|
os() << ToCString(kVcvtp) << dt1 << dt2 << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtr(
|
|
Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtr, kFpNeon);
|
|
os() << ToCString(kVcvtr) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtr(
|
|
Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtr, kFpNeon);
|
|
os() << ToCString(kVcvtr) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtt(
|
|
Condition cond, DataType dt1, DataType dt2, SRegister rd, SRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtt, kFpNeon);
|
|
os() << ToCString(kVcvtt) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtt(
|
|
Condition cond, DataType dt1, DataType dt2, DRegister rd, SRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtt, kFpNeon);
|
|
os() << ToCString(kVcvtt) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vcvtt(
|
|
Condition cond, DataType dt1, DataType dt2, SRegister rd, DRegister rm) {
|
|
os().SetCurrentInstruction(kVcvtt, kFpNeon);
|
|
os() << ToCString(kVcvtt) << ConditionPrinter(it_block_, cond) << dt1 << dt2
|
|
<< " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vdiv(
|
|
Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
|
|
os().SetCurrentInstruction(kVdiv, kFpNeon);
|
|
os() << ToCString(kVdiv) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vdiv(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVdiv, kFpNeon);
|
|
os() << ToCString(kVdiv) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vdup(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
Register rt) {
|
|
os().SetCurrentInstruction(kVdup, kFpNeon);
|
|
os() << ToCString(kVdup) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rt;
|
|
}
|
|
|
|
void Disassembler::vdup(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
Register rt) {
|
|
os().SetCurrentInstruction(kVdup, kFpNeon);
|
|
os() << ToCString(kVdup) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rt;
|
|
}
|
|
|
|
void Disassembler::vdup(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegisterLane rm) {
|
|
os().SetCurrentInstruction(kVdup, kFpNeon);
|
|
os() << ToCString(kVdup) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vdup(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
DRegisterLane rm) {
|
|
os().SetCurrentInstruction(kVdup, kFpNeon);
|
|
os() << ToCString(kVdup) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::veor(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVeor, kFpNeon);
|
|
os() << ToCString(kVeor) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::veor(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVeor, kFpNeon);
|
|
os() << ToCString(kVeor) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vext(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rn,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVext, kFpNeon);
|
|
os() << ToCString(kVext) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vext(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rn,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVext, kFpNeon);
|
|
os() << ToCString(kVext) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vfma(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVfma, kFpNeon);
|
|
os() << ToCString(kVfma) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vfma(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVfma, kFpNeon);
|
|
os() << ToCString(kVfma) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vfma(
|
|
Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
|
|
os().SetCurrentInstruction(kVfma, kFpNeon);
|
|
os() << ToCString(kVfma) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vfms(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVfms, kFpNeon);
|
|
os() << ToCString(kVfms) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vfms(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVfms, kFpNeon);
|
|
os() << ToCString(kVfms) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vfms(
|
|
Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
|
|
os().SetCurrentInstruction(kVfms, kFpNeon);
|
|
os() << ToCString(kVfms) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vfnma(
|
|
Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
|
|
os().SetCurrentInstruction(kVfnma, kFpNeon);
|
|
os() << ToCString(kVfnma) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vfnma(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVfnma, kFpNeon);
|
|
os() << ToCString(kVfnma) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vfnms(
|
|
Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
|
|
os().SetCurrentInstruction(kVfnms, kFpNeon);
|
|
os() << ToCString(kVfnms) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vfnms(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVfnms, kFpNeon);
|
|
os() << ToCString(kVfnms) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vhadd(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVhadd, kFpNeon);
|
|
os() << ToCString(kVhadd) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vhadd(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVhadd, kFpNeon);
|
|
os() << ToCString(kVhadd) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vhsub(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVhsub, kFpNeon);
|
|
os() << ToCString(kVhsub) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vhsub(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVhsub, kFpNeon);
|
|
os() << ToCString(kVhsub) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vld1(Condition cond,
|
|
DataType dt,
|
|
const NeonRegisterList& nreglist,
|
|
const AlignedMemOperand& operand) {
|
|
os().SetCurrentInstruction(kVld1, kFpNeon);
|
|
os() << ToCString(kVld1) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< nreglist << ", " << PrintAlignedMemOperand(kVld1Location, operand);
|
|
}
|
|
|
|
void Disassembler::vld2(Condition cond,
|
|
DataType dt,
|
|
const NeonRegisterList& nreglist,
|
|
const AlignedMemOperand& operand) {
|
|
os().SetCurrentInstruction(kVld2, kFpNeon);
|
|
os() << ToCString(kVld2) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< nreglist << ", " << PrintAlignedMemOperand(kVld2Location, operand);
|
|
}
|
|
|
|
void Disassembler::vld3(Condition cond,
|
|
DataType dt,
|
|
const NeonRegisterList& nreglist,
|
|
const AlignedMemOperand& operand) {
|
|
os().SetCurrentInstruction(kVld3, kFpNeon);
|
|
os() << ToCString(kVld3) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< nreglist << ", " << PrintAlignedMemOperand(kVld3Location, operand);
|
|
}
|
|
|
|
void Disassembler::vld3(Condition cond,
|
|
DataType dt,
|
|
const NeonRegisterList& nreglist,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kVld3, kFpNeon);
|
|
os() << ToCString(kVld3) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< nreglist << ", " << PrintMemOperand(kVld3Location, operand);
|
|
}
|
|
|
|
void Disassembler::vld4(Condition cond,
|
|
DataType dt,
|
|
const NeonRegisterList& nreglist,
|
|
const AlignedMemOperand& operand) {
|
|
os().SetCurrentInstruction(kVld4, kFpNeon);
|
|
os() << ToCString(kVld4) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< nreglist << ", " << PrintAlignedMemOperand(kVld4Location, operand);
|
|
}
|
|
|
|
void Disassembler::vldm(Condition cond,
|
|
DataType dt,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
DRegisterList dreglist) {
|
|
os().SetCurrentInstruction(kVldm, kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVldm) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rn << write_back << ", " << dreglist;
|
|
}
|
|
|
|
void Disassembler::vldm(Condition cond,
|
|
DataType dt,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
SRegisterList sreglist) {
|
|
os().SetCurrentInstruction(kVldm, kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVldm) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rn << write_back << ", " << sreglist;
|
|
}
|
|
|
|
void Disassembler::vldmdb(Condition cond,
|
|
DataType dt,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
DRegisterList dreglist) {
|
|
os().SetCurrentInstruction(kVldmdb,
|
|
kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVldmdb) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rn << write_back << ", " << dreglist;
|
|
}
|
|
|
|
void Disassembler::vldmdb(Condition cond,
|
|
DataType dt,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
SRegisterList sreglist) {
|
|
os().SetCurrentInstruction(kVldmdb,
|
|
kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVldmdb) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rn << write_back << ", " << sreglist;
|
|
}
|
|
|
|
void Disassembler::vldmia(Condition cond,
|
|
DataType dt,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
DRegisterList dreglist) {
|
|
os().SetCurrentInstruction(kVldmia,
|
|
kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVldmia) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rn << write_back << ", " << dreglist;
|
|
}
|
|
|
|
void Disassembler::vldmia(Condition cond,
|
|
DataType dt,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
SRegisterList sreglist) {
|
|
os().SetCurrentInstruction(kVldmia,
|
|
kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVldmia) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rn << write_back << ", " << sreglist;
|
|
}
|
|
|
|
void Disassembler::vldr(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
Location* location) {
|
|
os().SetCurrentInstruction(kVldr, kFpNeon);
|
|
os() << ToCString(kVldr) << ConditionPrinter(it_block_, cond)
|
|
<< DtPrinter(dt, Untyped64) << " " << rd << ", "
|
|
<< PrintLabel(kLoadDoublePrecisionLocation,
|
|
location,
|
|
GetCodeAddress() & ~3);
|
|
}
|
|
|
|
void Disassembler::vldr(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kVldr, kFpNeon);
|
|
os() << ToCString(kVldr) << ConditionPrinter(it_block_, cond)
|
|
<< DtPrinter(dt, Untyped64) << " " << rd << ", "
|
|
<< PrintMemOperand(kLoadDoublePrecisionLocation, operand);
|
|
}
|
|
|
|
void Disassembler::vldr(Condition cond,
|
|
DataType dt,
|
|
SRegister rd,
|
|
Location* location) {
|
|
os().SetCurrentInstruction(kVldr, kFpNeon);
|
|
os() << ToCString(kVldr) << ConditionPrinter(it_block_, cond)
|
|
<< DtPrinter(dt, Untyped32) << " " << rd << ", "
|
|
<< PrintLabel(kLoadSinglePrecisionLocation,
|
|
location,
|
|
GetCodeAddress() & ~3);
|
|
}
|
|
|
|
void Disassembler::vldr(Condition cond,
|
|
DataType dt,
|
|
SRegister rd,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kVldr, kFpNeon);
|
|
os() << ToCString(kVldr) << ConditionPrinter(it_block_, cond)
|
|
<< DtPrinter(dt, Untyped32) << " " << rd << ", "
|
|
<< PrintMemOperand(kLoadSinglePrecisionLocation, operand);
|
|
}
|
|
|
|
void Disassembler::vmax(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVmax, kFpNeon);
|
|
os() << ToCString(kVmax) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmax(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVmax, kFpNeon);
|
|
os() << ToCString(kVmax) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmaxnm(DataType dt,
|
|
DRegister rd,
|
|
DRegister rn,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVmaxnm, kFpNeon);
|
|
os() << ToCString(kVmaxnm) << dt << " " << rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmaxnm(DataType dt,
|
|
QRegister rd,
|
|
QRegister rn,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVmaxnm, kFpNeon);
|
|
os() << ToCString(kVmaxnm) << dt << " " << rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmaxnm(DataType dt,
|
|
SRegister rd,
|
|
SRegister rn,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVmaxnm, kFpNeon);
|
|
os() << ToCString(kVmaxnm) << dt << " " << rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmin(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVmin, kFpNeon);
|
|
os() << ToCString(kVmin) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmin(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVmin, kFpNeon);
|
|
os() << ToCString(kVmin) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vminnm(DataType dt,
|
|
DRegister rd,
|
|
DRegister rn,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVminnm, kFpNeon);
|
|
os() << ToCString(kVminnm) << dt << " " << rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vminnm(DataType dt,
|
|
QRegister rd,
|
|
QRegister rn,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVminnm, kFpNeon);
|
|
os() << ToCString(kVminnm) << dt << " " << rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vminnm(DataType dt,
|
|
SRegister rd,
|
|
SRegister rn,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVminnm, kFpNeon);
|
|
os() << ToCString(kVminnm) << dt << " " << rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmla(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
|
|
os().SetCurrentInstruction(kVmla, kFpNeon);
|
|
os() << ToCString(kVmla) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmla(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
|
|
os().SetCurrentInstruction(kVmla, kFpNeon);
|
|
os() << ToCString(kVmla) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmla(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVmla, kFpNeon);
|
|
os() << ToCString(kVmla) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmla(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVmla, kFpNeon);
|
|
os() << ToCString(kVmla) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmla(
|
|
Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
|
|
os().SetCurrentInstruction(kVmla, kFpNeon);
|
|
os() << ToCString(kVmla) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmlal(
|
|
Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
|
|
os().SetCurrentInstruction(kVmlal, kFpNeon);
|
|
os() << ToCString(kVmlal) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmlal(
|
|
Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVmlal, kFpNeon);
|
|
os() << ToCString(kVmlal) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmls(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
|
|
os().SetCurrentInstruction(kVmls, kFpNeon);
|
|
os() << ToCString(kVmls) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmls(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
|
|
os().SetCurrentInstruction(kVmls, kFpNeon);
|
|
os() << ToCString(kVmls) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmls(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVmls, kFpNeon);
|
|
os() << ToCString(kVmls) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmls(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVmls, kFpNeon);
|
|
os() << ToCString(kVmls) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmls(
|
|
Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
|
|
os().SetCurrentInstruction(kVmls, kFpNeon);
|
|
os() << ToCString(kVmls) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmlsl(
|
|
Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
|
|
os().SetCurrentInstruction(kVmlsl, kFpNeon);
|
|
os() << ToCString(kVmlsl) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmlsl(
|
|
Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVmlsl, kFpNeon);
|
|
os() << ToCString(kVmlsl) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmov(Condition cond, Register rt, SRegister rn) {
|
|
os().SetCurrentInstruction(kVmov, kFpNeon);
|
|
os() << ToCString(kVmov) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << rn;
|
|
}
|
|
|
|
void Disassembler::vmov(Condition cond, SRegister rn, Register rt) {
|
|
os().SetCurrentInstruction(kVmov, kFpNeon);
|
|
os() << ToCString(kVmov) << ConditionPrinter(it_block_, cond) << " " << rn
|
|
<< ", " << rt;
|
|
}
|
|
|
|
void Disassembler::vmov(Condition cond,
|
|
Register rt,
|
|
Register rt2,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVmov, kFpNeon);
|
|
os() << ToCString(kVmov) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << rt2 << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmov(Condition cond,
|
|
DRegister rm,
|
|
Register rt,
|
|
Register rt2) {
|
|
os().SetCurrentInstruction(kVmov, kFpNeon);
|
|
os() << ToCString(kVmov) << ConditionPrinter(it_block_, cond) << " " << rm
|
|
<< ", " << rt << ", " << rt2;
|
|
}
|
|
|
|
void Disassembler::vmov(
|
|
Condition cond, Register rt, Register rt2, SRegister rm, SRegister rm1) {
|
|
os().SetCurrentInstruction(kVmov, kFpNeon);
|
|
os() << ToCString(kVmov) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << rt2 << ", " << rm << ", " << rm1;
|
|
}
|
|
|
|
void Disassembler::vmov(
|
|
Condition cond, SRegister rm, SRegister rm1, Register rt, Register rt2) {
|
|
os().SetCurrentInstruction(kVmov, kFpNeon);
|
|
os() << ToCString(kVmov) << ConditionPrinter(it_block_, cond) << " " << rm
|
|
<< ", " << rm1 << ", " << rt << ", " << rt2;
|
|
}
|
|
|
|
void Disassembler::vmov(Condition cond,
|
|
DataType dt,
|
|
DRegisterLane rd,
|
|
Register rt) {
|
|
os().SetCurrentInstruction(kVmov, kFpNeon);
|
|
os() << ToCString(kVmov) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rt;
|
|
}
|
|
|
|
void Disassembler::vmov(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVmov, kFpNeon);
|
|
os() << ToCString(kVmov) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vmov(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVmov, kFpNeon);
|
|
os() << ToCString(kVmov) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vmov(Condition cond,
|
|
DataType dt,
|
|
SRegister rd,
|
|
const SOperand& operand) {
|
|
os().SetCurrentInstruction(kVmov, kFpNeon);
|
|
os() << ToCString(kVmov) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vmov(Condition cond,
|
|
DataType dt,
|
|
Register rt,
|
|
DRegisterLane rn) {
|
|
os().SetCurrentInstruction(kVmov, kFpNeon);
|
|
os() << ToCString(kVmov) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rt << ", " << rn;
|
|
}
|
|
|
|
void Disassembler::vmovl(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVmovl, kFpNeon);
|
|
os() << ToCString(kVmovl) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmovn(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVmovn, kFpNeon);
|
|
os() << ToCString(kVmovn) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmrs(Condition cond,
|
|
RegisterOrAPSR_nzcv rt,
|
|
SpecialFPRegister spec_reg) {
|
|
os().SetCurrentInstruction(kVmrs, kFpNeon);
|
|
os() << ToCString(kVmrs) << ConditionPrinter(it_block_, cond) << " " << rt
|
|
<< ", " << spec_reg;
|
|
}
|
|
|
|
void Disassembler::vmsr(Condition cond,
|
|
SpecialFPRegister spec_reg,
|
|
Register rt) {
|
|
os().SetCurrentInstruction(kVmsr, kFpNeon);
|
|
os() << ToCString(kVmsr) << ConditionPrinter(it_block_, cond) << " "
|
|
<< spec_reg << ", " << rt;
|
|
}
|
|
|
|
void Disassembler::vmul(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rn,
|
|
DRegister dm,
|
|
unsigned index) {
|
|
os().SetCurrentInstruction(kVmul, kFpNeon);
|
|
os() << ToCString(kVmul) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << IndexedRegisterPrinter(dm, index);
|
|
}
|
|
|
|
void Disassembler::vmul(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rn,
|
|
DRegister dm,
|
|
unsigned index) {
|
|
os().SetCurrentInstruction(kVmul, kFpNeon);
|
|
os() << ToCString(kVmul) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << IndexedRegisterPrinter(dm, index);
|
|
}
|
|
|
|
void Disassembler::vmul(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVmul, kFpNeon);
|
|
os() << ToCString(kVmul) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmul(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVmul, kFpNeon);
|
|
os() << ToCString(kVmul) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmul(
|
|
Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
|
|
os().SetCurrentInstruction(kVmul, kFpNeon);
|
|
os() << ToCString(kVmul) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmull(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
DRegister rn,
|
|
DRegister dm,
|
|
unsigned index) {
|
|
os().SetCurrentInstruction(kVmull, kFpNeon);
|
|
os() << ToCString(kVmull) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << IndexedRegisterPrinter(dm, index);
|
|
}
|
|
|
|
void Disassembler::vmull(
|
|
Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVmull, kFpNeon);
|
|
os() << ToCString(kVmull) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vmvn(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVmvn, kFpNeon);
|
|
os() << ToCString(kVmvn) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vmvn(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVmvn, kFpNeon);
|
|
os() << ToCString(kVmvn) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vneg(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVneg, kFpNeon);
|
|
os() << ToCString(kVneg) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vneg(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVneg, kFpNeon);
|
|
os() << ToCString(kVneg) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vneg(Condition cond,
|
|
DataType dt,
|
|
SRegister rd,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVneg, kFpNeon);
|
|
os() << ToCString(kVneg) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vnmla(
|
|
Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
|
|
os().SetCurrentInstruction(kVnmla, kFpNeon);
|
|
os() << ToCString(kVnmla) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vnmla(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVnmla, kFpNeon);
|
|
os() << ToCString(kVnmla) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vnmls(
|
|
Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
|
|
os().SetCurrentInstruction(kVnmls, kFpNeon);
|
|
os() << ToCString(kVnmls) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vnmls(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVnmls, kFpNeon);
|
|
os() << ToCString(kVnmls) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vnmul(
|
|
Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
|
|
os().SetCurrentInstruction(kVnmul, kFpNeon);
|
|
os() << ToCString(kVnmul) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vnmul(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVnmul, kFpNeon);
|
|
os() << ToCString(kVnmul) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vorn(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rn,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVorn, kFpNeon);
|
|
os() << ToCString(kVorn) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vorn(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rn,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVorn, kFpNeon);
|
|
os() << ToCString(kVorn) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vorr(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rn,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVorr, kFpNeon);
|
|
os() << ToCString(kVorr) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vorr(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rn,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVorr, kFpNeon);
|
|
os() << ToCString(kVorr) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vpadal(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVpadal, kFpNeon);
|
|
os() << ToCString(kVpadal) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vpadal(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVpadal, kFpNeon);
|
|
os() << ToCString(kVpadal) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vpadd(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVpadd, kFpNeon);
|
|
os() << ToCString(kVpadd) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vpaddl(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVpaddl, kFpNeon);
|
|
os() << ToCString(kVpaddl) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vpaddl(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVpaddl, kFpNeon);
|
|
os() << ToCString(kVpaddl) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vpmax(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVpmax, kFpNeon);
|
|
os() << ToCString(kVpmax) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vpmin(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVpmin, kFpNeon);
|
|
os() << ToCString(kVpmin) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vpop(Condition cond, DataType dt, DRegisterList dreglist) {
|
|
os().SetCurrentInstruction(kVpop, kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVpop) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< dreglist;
|
|
}
|
|
|
|
void Disassembler::vpop(Condition cond, DataType dt, SRegisterList sreglist) {
|
|
os().SetCurrentInstruction(kVpop, kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVpop) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< sreglist;
|
|
}
|
|
|
|
void Disassembler::vpush(Condition cond, DataType dt, DRegisterList dreglist) {
|
|
os().SetCurrentInstruction(kVpush, kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVpush) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< dreglist;
|
|
}
|
|
|
|
void Disassembler::vpush(Condition cond, DataType dt, SRegisterList sreglist) {
|
|
os().SetCurrentInstruction(kVpush, kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVpush) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< sreglist;
|
|
}
|
|
|
|
void Disassembler::vqabs(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVqabs, kFpNeon);
|
|
os() << ToCString(kVqabs) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqabs(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVqabs, kFpNeon);
|
|
os() << ToCString(kVqabs) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqadd(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVqadd, kFpNeon);
|
|
os() << ToCString(kVqadd) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqadd(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVqadd, kFpNeon);
|
|
os() << ToCString(kVqadd) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqdmlal(
|
|
Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVqdmlal, kFpNeon);
|
|
os() << ToCString(kVqdmlal) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqdmlal(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
DRegister rn,
|
|
DRegister dm,
|
|
unsigned index) {
|
|
os().SetCurrentInstruction(kVqdmlal, kFpNeon);
|
|
os() << ToCString(kVqdmlal) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << IndexedRegisterPrinter(dm, index);
|
|
}
|
|
|
|
void Disassembler::vqdmlsl(
|
|
Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVqdmlsl, kFpNeon);
|
|
os() << ToCString(kVqdmlsl) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqdmlsl(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
DRegister rn,
|
|
DRegister dm,
|
|
unsigned index) {
|
|
os().SetCurrentInstruction(kVqdmlsl, kFpNeon);
|
|
os() << ToCString(kVqdmlsl) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << IndexedRegisterPrinter(dm, index);
|
|
}
|
|
|
|
void Disassembler::vqdmulh(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVqdmulh, kFpNeon);
|
|
os() << ToCString(kVqdmulh) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqdmulh(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVqdmulh, kFpNeon);
|
|
os() << ToCString(kVqdmulh) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqdmulh(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
|
|
os().SetCurrentInstruction(kVqdmulh, kFpNeon);
|
|
os() << ToCString(kVqdmulh) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqdmulh(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
|
|
os().SetCurrentInstruction(kVqdmulh, kFpNeon);
|
|
os() << ToCString(kVqdmulh) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqdmull(
|
|
Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVqdmull, kFpNeon);
|
|
os() << ToCString(kVqdmull) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqdmull(
|
|
Condition cond, DataType dt, QRegister rd, DRegister rn, DRegisterLane rm) {
|
|
os().SetCurrentInstruction(kVqdmull, kFpNeon);
|
|
os() << ToCString(kVqdmull) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqmovn(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVqmovn, kFpNeon);
|
|
os() << ToCString(kVqmovn) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqmovun(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVqmovun, kFpNeon);
|
|
os() << ToCString(kVqmovun) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqneg(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVqneg, kFpNeon);
|
|
os() << ToCString(kVqneg) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqneg(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVqneg, kFpNeon);
|
|
os() << ToCString(kVqneg) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqrdmulh(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVqrdmulh, kFpNeon);
|
|
os() << ToCString(kVqrdmulh) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqrdmulh(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVqrdmulh, kFpNeon);
|
|
os() << ToCString(kVqrdmulh) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqrdmulh(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegisterLane rm) {
|
|
os().SetCurrentInstruction(kVqrdmulh, kFpNeon);
|
|
os() << ToCString(kVqrdmulh) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqrdmulh(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, DRegisterLane rm) {
|
|
os().SetCurrentInstruction(kVqrdmulh, kFpNeon);
|
|
os() << ToCString(kVqrdmulh) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqrshl(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
|
|
os().SetCurrentInstruction(kVqrshl, kFpNeon);
|
|
os() << ToCString(kVqrshl) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << rn;
|
|
}
|
|
|
|
void Disassembler::vqrshl(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
|
|
os().SetCurrentInstruction(kVqrshl, kFpNeon);
|
|
os() << ToCString(kVqrshl) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << rn;
|
|
}
|
|
|
|
void Disassembler::vqrshrn(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVqrshrn, kFpNeon);
|
|
os() << ToCString(kVqrshrn) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vqrshrun(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVqrshrun, kFpNeon);
|
|
os() << ToCString(kVqrshrun) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vqshl(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVqshl, kFpNeon);
|
|
os() << ToCString(kVqshl) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vqshl(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVqshl, kFpNeon);
|
|
os() << ToCString(kVqshl) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vqshlu(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVqshlu, kFpNeon);
|
|
os() << ToCString(kVqshlu) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vqshlu(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVqshlu, kFpNeon);
|
|
os() << ToCString(kVqshlu) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vqshrn(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVqshrn, kFpNeon);
|
|
os() << ToCString(kVqshrn) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vqshrun(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVqshrun, kFpNeon);
|
|
os() << ToCString(kVqshrun) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vqsub(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVqsub, kFpNeon);
|
|
os() << ToCString(kVqsub) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vqsub(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVqsub, kFpNeon);
|
|
os() << ToCString(kVqsub) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vraddhn(
|
|
Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVraddhn, kFpNeon);
|
|
os() << ToCString(kVraddhn) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrecpe(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVrecpe, kFpNeon);
|
|
os() << ToCString(kVrecpe) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrecpe(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVrecpe, kFpNeon);
|
|
os() << ToCString(kVrecpe) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrecps(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVrecps, kFpNeon);
|
|
os() << ToCString(kVrecps) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrecps(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVrecps, kFpNeon);
|
|
os() << ToCString(kVrecps) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrev16(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVrev16, kFpNeon);
|
|
os() << ToCString(kVrev16) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrev16(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVrev16, kFpNeon);
|
|
os() << ToCString(kVrev16) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrev32(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVrev32, kFpNeon);
|
|
os() << ToCString(kVrev32) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrev32(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVrev32, kFpNeon);
|
|
os() << ToCString(kVrev32) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrev64(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVrev64, kFpNeon);
|
|
os() << ToCString(kVrev64) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrev64(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVrev64, kFpNeon);
|
|
os() << ToCString(kVrev64) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrhadd(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVrhadd, kFpNeon);
|
|
os() << ToCString(kVrhadd) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrhadd(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVrhadd, kFpNeon);
|
|
os() << ToCString(kVrhadd) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrinta(DataType dt, DRegister rd, DRegister rm) {
|
|
os().SetCurrentInstruction(kVrinta, kFpNeon);
|
|
os() << ToCString(kVrinta) << dt << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrinta(DataType dt, QRegister rd, QRegister rm) {
|
|
os().SetCurrentInstruction(kVrinta, kFpNeon);
|
|
os() << ToCString(kVrinta) << dt << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrinta(DataType dt, SRegister rd, SRegister rm) {
|
|
os().SetCurrentInstruction(kVrinta, kFpNeon);
|
|
os() << ToCString(kVrinta) << dt << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintm(DataType dt, DRegister rd, DRegister rm) {
|
|
os().SetCurrentInstruction(kVrintm, kFpNeon);
|
|
os() << ToCString(kVrintm) << dt << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintm(DataType dt, QRegister rd, QRegister rm) {
|
|
os().SetCurrentInstruction(kVrintm, kFpNeon);
|
|
os() << ToCString(kVrintm) << dt << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintm(DataType dt, SRegister rd, SRegister rm) {
|
|
os().SetCurrentInstruction(kVrintm, kFpNeon);
|
|
os() << ToCString(kVrintm) << dt << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintn(DataType dt, DRegister rd, DRegister rm) {
|
|
os().SetCurrentInstruction(kVrintn, kFpNeon);
|
|
os() << ToCString(kVrintn) << dt << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintn(DataType dt, QRegister rd, QRegister rm) {
|
|
os().SetCurrentInstruction(kVrintn, kFpNeon);
|
|
os() << ToCString(kVrintn) << dt << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintn(DataType dt, SRegister rd, SRegister rm) {
|
|
os().SetCurrentInstruction(kVrintn, kFpNeon);
|
|
os() << ToCString(kVrintn) << dt << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintp(DataType dt, DRegister rd, DRegister rm) {
|
|
os().SetCurrentInstruction(kVrintp, kFpNeon);
|
|
os() << ToCString(kVrintp) << dt << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintp(DataType dt, QRegister rd, QRegister rm) {
|
|
os().SetCurrentInstruction(kVrintp, kFpNeon);
|
|
os() << ToCString(kVrintp) << dt << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintp(DataType dt, SRegister rd, SRegister rm) {
|
|
os().SetCurrentInstruction(kVrintp, kFpNeon);
|
|
os() << ToCString(kVrintp) << dt << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintr(Condition cond,
|
|
DataType dt,
|
|
SRegister rd,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVrintr, kFpNeon);
|
|
os() << ToCString(kVrintr) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintr(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVrintr, kFpNeon);
|
|
os() << ToCString(kVrintr) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintx(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVrintx, kFpNeon);
|
|
os() << ToCString(kVrintx) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintx(DataType dt, QRegister rd, QRegister rm) {
|
|
os().SetCurrentInstruction(kVrintx, kFpNeon);
|
|
os() << ToCString(kVrintx) << dt << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintx(Condition cond,
|
|
DataType dt,
|
|
SRegister rd,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVrintx, kFpNeon);
|
|
os() << ToCString(kVrintx) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintz(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVrintz, kFpNeon);
|
|
os() << ToCString(kVrintz) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintz(DataType dt, QRegister rd, QRegister rm) {
|
|
os().SetCurrentInstruction(kVrintz, kFpNeon);
|
|
os() << ToCString(kVrintz) << dt << " " << rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrintz(Condition cond,
|
|
DataType dt,
|
|
SRegister rd,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVrintz, kFpNeon);
|
|
os() << ToCString(kVrintz) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrshl(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rm, DRegister rn) {
|
|
os().SetCurrentInstruction(kVrshl, kFpNeon);
|
|
os() << ToCString(kVrshl) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << rn;
|
|
}
|
|
|
|
void Disassembler::vrshl(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rm, QRegister rn) {
|
|
os().SetCurrentInstruction(kVrshl, kFpNeon);
|
|
os() << ToCString(kVrshl) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << rn;
|
|
}
|
|
|
|
void Disassembler::vrshr(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVrshr, kFpNeon);
|
|
os() << ToCString(kVrshr) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vrshr(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVrshr, kFpNeon);
|
|
os() << ToCString(kVrshr) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vrshrn(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVrshrn, kFpNeon);
|
|
os() << ToCString(kVrshrn) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vrsqrte(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVrsqrte, kFpNeon);
|
|
os() << ToCString(kVrsqrte) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrsqrte(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVrsqrte, kFpNeon);
|
|
os() << ToCString(kVrsqrte) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrsqrts(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVrsqrts, kFpNeon);
|
|
os() << ToCString(kVrsqrts) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrsqrts(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVrsqrts, kFpNeon);
|
|
os() << ToCString(kVrsqrts) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vrsra(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVrsra, kFpNeon);
|
|
os() << ToCString(kVrsra) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vrsra(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVrsra, kFpNeon);
|
|
os() << ToCString(kVrsra) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vrsubhn(
|
|
Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVrsubhn, kFpNeon);
|
|
os() << ToCString(kVrsubhn) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vseleq(DataType dt,
|
|
DRegister rd,
|
|
DRegister rn,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVseleq, kFpNeon);
|
|
os() << ToCString(kVseleq) << dt << " " << rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vseleq(DataType dt,
|
|
SRegister rd,
|
|
SRegister rn,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVseleq, kFpNeon);
|
|
os() << ToCString(kVseleq) << dt << " " << rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vselge(DataType dt,
|
|
DRegister rd,
|
|
DRegister rn,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVselge, kFpNeon);
|
|
os() << ToCString(kVselge) << dt << " " << rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vselge(DataType dt,
|
|
SRegister rd,
|
|
SRegister rn,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVselge, kFpNeon);
|
|
os() << ToCString(kVselge) << dt << " " << rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vselgt(DataType dt,
|
|
DRegister rd,
|
|
DRegister rn,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVselgt, kFpNeon);
|
|
os() << ToCString(kVselgt) << dt << " " << rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vselgt(DataType dt,
|
|
SRegister rd,
|
|
SRegister rn,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVselgt, kFpNeon);
|
|
os() << ToCString(kVselgt) << dt << " " << rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vselvs(DataType dt,
|
|
DRegister rd,
|
|
DRegister rn,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVselvs, kFpNeon);
|
|
os() << ToCString(kVselvs) << dt << " " << rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vselvs(DataType dt,
|
|
SRegister rd,
|
|
SRegister rn,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVselvs, kFpNeon);
|
|
os() << ToCString(kVselvs) << dt << " " << rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vshl(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVshl, kFpNeon);
|
|
os() << ToCString(kVshl) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vshl(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVshl, kFpNeon);
|
|
os() << ToCString(kVshl) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vshll(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVshll, kFpNeon);
|
|
os() << ToCString(kVshll) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vshr(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVshr, kFpNeon);
|
|
os() << ToCString(kVshr) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vshr(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVshr, kFpNeon);
|
|
os() << ToCString(kVshr) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vshrn(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVshrn, kFpNeon);
|
|
os() << ToCString(kVshrn) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vsli(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVsli, kFpNeon);
|
|
os() << ToCString(kVsli) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vsli(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVsli, kFpNeon);
|
|
os() << ToCString(kVsli) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vsqrt(Condition cond,
|
|
DataType dt,
|
|
SRegister rd,
|
|
SRegister rm) {
|
|
os().SetCurrentInstruction(kVsqrt, kFpNeon);
|
|
os() << ToCString(kVsqrt) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vsqrt(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVsqrt, kFpNeon);
|
|
os() << ToCString(kVsqrt) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vsra(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVsra, kFpNeon);
|
|
os() << ToCString(kVsra) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vsra(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVsra, kFpNeon);
|
|
os() << ToCString(kVsra) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vsri(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm,
|
|
const DOperand& operand) {
|
|
os().SetCurrentInstruction(kVsri, kFpNeon);
|
|
os() << ToCString(kVsri) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vsri(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm,
|
|
const QOperand& operand) {
|
|
os().SetCurrentInstruction(kVsri, kFpNeon);
|
|
os() << ToCString(kVsri) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rm) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rm << ", " << operand;
|
|
}
|
|
|
|
void Disassembler::vst1(Condition cond,
|
|
DataType dt,
|
|
const NeonRegisterList& nreglist,
|
|
const AlignedMemOperand& operand) {
|
|
os().SetCurrentInstruction(kVst1, kFpNeon);
|
|
os() << ToCString(kVst1) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< nreglist << ", " << PrintAlignedMemOperand(kVst1Location, operand);
|
|
}
|
|
|
|
void Disassembler::vst2(Condition cond,
|
|
DataType dt,
|
|
const NeonRegisterList& nreglist,
|
|
const AlignedMemOperand& operand) {
|
|
os().SetCurrentInstruction(kVst2, kFpNeon);
|
|
os() << ToCString(kVst2) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< nreglist << ", " << PrintAlignedMemOperand(kVst2Location, operand);
|
|
}
|
|
|
|
void Disassembler::vst3(Condition cond,
|
|
DataType dt,
|
|
const NeonRegisterList& nreglist,
|
|
const AlignedMemOperand& operand) {
|
|
os().SetCurrentInstruction(kVst3, kFpNeon);
|
|
os() << ToCString(kVst3) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< nreglist << ", " << PrintAlignedMemOperand(kVst3Location, operand);
|
|
}
|
|
|
|
void Disassembler::vst3(Condition cond,
|
|
DataType dt,
|
|
const NeonRegisterList& nreglist,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kVst3, kFpNeon);
|
|
os() << ToCString(kVst3) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< nreglist << ", " << PrintMemOperand(kVst3Location, operand);
|
|
}
|
|
|
|
void Disassembler::vst4(Condition cond,
|
|
DataType dt,
|
|
const NeonRegisterList& nreglist,
|
|
const AlignedMemOperand& operand) {
|
|
os().SetCurrentInstruction(kVst4, kFpNeon);
|
|
os() << ToCString(kVst4) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< nreglist << ", " << PrintAlignedMemOperand(kVst4Location, operand);
|
|
}
|
|
|
|
void Disassembler::vstm(Condition cond,
|
|
DataType dt,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
DRegisterList dreglist) {
|
|
os().SetCurrentInstruction(kVstm, kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVstm) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rn << write_back << ", " << dreglist;
|
|
}
|
|
|
|
void Disassembler::vstm(Condition cond,
|
|
DataType dt,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
SRegisterList sreglist) {
|
|
os().SetCurrentInstruction(kVstm, kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVstm) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rn << write_back << ", " << sreglist;
|
|
}
|
|
|
|
void Disassembler::vstmdb(Condition cond,
|
|
DataType dt,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
DRegisterList dreglist) {
|
|
os().SetCurrentInstruction(kVstmdb,
|
|
kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVstmdb) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rn << write_back << ", " << dreglist;
|
|
}
|
|
|
|
void Disassembler::vstmdb(Condition cond,
|
|
DataType dt,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
SRegisterList sreglist) {
|
|
os().SetCurrentInstruction(kVstmdb,
|
|
kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVstmdb) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rn << write_back << ", " << sreglist;
|
|
}
|
|
|
|
void Disassembler::vstmia(Condition cond,
|
|
DataType dt,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
DRegisterList dreglist) {
|
|
os().SetCurrentInstruction(kVstmia,
|
|
kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVstmia) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rn << write_back << ", " << dreglist;
|
|
}
|
|
|
|
void Disassembler::vstmia(Condition cond,
|
|
DataType dt,
|
|
Register rn,
|
|
WriteBack write_back,
|
|
SRegisterList sreglist) {
|
|
os().SetCurrentInstruction(kVstmia,
|
|
kLoadStore | kLoadStoreMultiple | kFpNeon);
|
|
os() << ToCString(kVstmia) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rn << write_back << ", " << sreglist;
|
|
}
|
|
|
|
void Disassembler::vstr(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kVstr, kFpNeon);
|
|
os() << ToCString(kVstr) << ConditionPrinter(it_block_, cond)
|
|
<< DtPrinter(dt, Untyped64) << " " << rd << ", "
|
|
<< PrintMemOperand(kStoreDoublePrecisionLocation, operand);
|
|
}
|
|
|
|
void Disassembler::vstr(Condition cond,
|
|
DataType dt,
|
|
SRegister rd,
|
|
const MemOperand& operand) {
|
|
os().SetCurrentInstruction(kVstr, kFpNeon);
|
|
os() << ToCString(kVstr) << ConditionPrinter(it_block_, cond)
|
|
<< DtPrinter(dt, Untyped32) << " " << rd << ", "
|
|
<< PrintMemOperand(kStoreSinglePrecisionLocation, operand);
|
|
}
|
|
|
|
void Disassembler::vsub(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVsub, kFpNeon);
|
|
os() << ToCString(kVsub) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vsub(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVsub, kFpNeon);
|
|
os() << ToCString(kVsub) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vsub(
|
|
Condition cond, DataType dt, SRegister rd, SRegister rn, SRegister rm) {
|
|
os().SetCurrentInstruction(kVsub, kFpNeon);
|
|
os() << ToCString(kVsub) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vsubhn(
|
|
Condition cond, DataType dt, DRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVsubhn, kFpNeon);
|
|
os() << ToCString(kVsubhn) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vsubl(
|
|
Condition cond, DataType dt, QRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVsubl, kFpNeon);
|
|
os() << ToCString(kVsubl) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vsubw(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVsubw, kFpNeon);
|
|
os() << ToCString(kVsubw) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vswp(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVswp, kFpNeon);
|
|
os() << ToCString(kVswp) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vswp(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVswp, kFpNeon);
|
|
os() << ToCString(kVswp) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vtbl(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
const NeonRegisterList& nreglist,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVtbl, kFpNeon);
|
|
os() << ToCString(kVtbl) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << nreglist << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vtbx(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
const NeonRegisterList& nreglist,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVtbx, kFpNeon);
|
|
os() << ToCString(kVtbx) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << nreglist << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vtrn(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVtrn, kFpNeon);
|
|
os() << ToCString(kVtrn) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vtrn(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVtrn, kFpNeon);
|
|
os() << ToCString(kVtrn) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vtst(
|
|
Condition cond, DataType dt, DRegister rd, DRegister rn, DRegister rm) {
|
|
os().SetCurrentInstruction(kVtst, kFpNeon);
|
|
os() << ToCString(kVtst) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vtst(
|
|
Condition cond, DataType dt, QRegister rd, QRegister rn, QRegister rm) {
|
|
os().SetCurrentInstruction(kVtst, kFpNeon);
|
|
os() << ToCString(kVtst) << ConditionPrinter(it_block_, cond) << dt;
|
|
os() << " ";
|
|
if (!rd.Is(rn) || !use_short_hand_form_) {
|
|
os() << rd << ", ";
|
|
}
|
|
os() << rn << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vuzp(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVuzp, kFpNeon);
|
|
os() << ToCString(kVuzp) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vuzp(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVuzp, kFpNeon);
|
|
os() << ToCString(kVuzp) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vzip(Condition cond,
|
|
DataType dt,
|
|
DRegister rd,
|
|
DRegister rm) {
|
|
os().SetCurrentInstruction(kVzip, kFpNeon);
|
|
os() << ToCString(kVzip) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::vzip(Condition cond,
|
|
DataType dt,
|
|
QRegister rd,
|
|
QRegister rm) {
|
|
os().SetCurrentInstruction(kVzip, kFpNeon);
|
|
os() << ToCString(kVzip) << ConditionPrinter(it_block_, cond) << dt << " "
|
|
<< rd << ", " << rm;
|
|
}
|
|
|
|
void Disassembler::yield(Condition cond, EncodingSize size) {
|
|
os().SetCurrentInstruction(kYield, kNoAttribute);
|
|
os() << ToCString(kYield) << ConditionPrinter(it_block_, cond) << size;
|
|
}
|
|
|
|
int Disassembler::T32Size(uint32_t instr) {
|
|
if ((instr & 0xe0000000) == 0xe0000000) {
|
|
switch (instr & 0x08000000) {
|
|
case 0x00000000:
|
|
if ((instr & 0x10000000) == 0x10000000) return 4;
|
|
return 2;
|
|
case 0x08000000:
|
|
return 4;
|
|
default:
|
|
return 2;
|
|
}
|
|
}
|
|
return 2;
|
|
}
|
|
|
|
void Disassembler::DecodeT32(uint32_t instr) {
|
|
T32CodeAddressIncrementer incrementer(instr, &code_address_);
|
|
ITBlockScope it_scope(&it_block_);
|
|
|
|
switch (instr & 0xe0000000) {
|
|
case 0x00000000: {
|
|
// 0x00000000
|
|
switch (instr & 0x18000000) {
|
|
case 0x18000000: {
|
|
// 0x18000000
|
|
switch (instr & 0x06000000) {
|
|
case 0x00000000: {
|
|
// 0x18000000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
unsigned rm = (instr >> 22) & 0x7;
|
|
if (InITBlock()) {
|
|
// ADD<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
|
|
add(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// ADDS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
adds(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
}
|
|
break;
|
|
}
|
|
case 0x02000000: {
|
|
// 0x1a000000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
unsigned rm = (instr >> 22) & 0x7;
|
|
if (InITBlock()) {
|
|
// SUB<c>{<q>} <Rd>, <Rn>, <Rm> ; T1
|
|
sub(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// SUBS{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
subs(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
}
|
|
break;
|
|
}
|
|
case 0x04000000: {
|
|
// 0x1c000000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
uint32_t imm = (instr >> 22) & 0x7;
|
|
if (InITBlock()) {
|
|
// ADD<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
|
|
add(CurrentCond(), Narrow, Register(rd), Register(rn), imm);
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// ADDS{<q>} <Rd>, <Rn>, #<imm3> ; T1
|
|
adds(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
}
|
|
break;
|
|
}
|
|
case 0x06000000: {
|
|
// 0x1e000000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
uint32_t imm = (instr >> 22) & 0x7;
|
|
if (InITBlock()) {
|
|
// SUB<c>{<q>} <Rd>, <Rn>, #<imm3> ; T1
|
|
sub(CurrentCond(), Narrow, Register(rd), Register(rn), imm);
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// SUBS{<q>} <Rd>, <Rn>, #<imm3> ; T1
|
|
subs(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x18000000) == 0x18000000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 27)) & Uint32(0x3)) == Uint32(0x2)) &&
|
|
InITBlock()) {
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
uint32_t amount = (instr >> 22) & 0x1f;
|
|
if (amount == 0) amount = 32;
|
|
// ASR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
|
|
asr(CurrentCond(), Narrow, Register(rd), Register(rm), amount);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 27)) & Uint32(0x3)) == Uint32(0x2)) &&
|
|
!InITBlock()) {
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
uint32_t amount = (instr >> 22) & 0x1f;
|
|
if (amount == 0) amount = 32;
|
|
// ASRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
|
|
asrs(Condition::None(), Narrow, Register(rd), Register(rm), amount);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 27)) & Uint32(0x3)) == Uint32(0x0)) &&
|
|
((instr & 0x07c00000) != 0x00000000) && InITBlock()) {
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
uint32_t amount = (instr >> 22) & 0x1f;
|
|
// LSL<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
|
|
lsl(CurrentCond(), Narrow, Register(rd), Register(rm), amount);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 27)) & Uint32(0x3)) == Uint32(0x0)) &&
|
|
((instr & 0x07c00000) != 0x00000000) && !InITBlock()) {
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
uint32_t amount = (instr >> 22) & 0x1f;
|
|
// LSLS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
|
|
lsls(Condition::None(), Narrow, Register(rd), Register(rm), amount);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 27)) & Uint32(0x3)) == Uint32(0x1)) &&
|
|
InITBlock()) {
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
uint32_t amount = (instr >> 22) & 0x1f;
|
|
if (amount == 0) amount = 32;
|
|
// LSR<c>{<q>} {<Rd>}, <Rm>, #<imm> ; T2
|
|
lsr(CurrentCond(), Narrow, Register(rd), Register(rm), amount);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 27)) & Uint32(0x3)) == Uint32(0x1)) &&
|
|
!InITBlock()) {
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
uint32_t amount = (instr >> 22) & 0x1f;
|
|
if (amount == 0) amount = 32;
|
|
// LSRS{<q>} {<Rd>}, <Rm>, #<imm> ; T2
|
|
lsrs(Condition::None(), Narrow, Register(rd), Register(rm), amount);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
ImmediateShiftOperand shift_operand((instr >> 27) & 0x3,
|
|
(instr >> 22) & 0x1f);
|
|
if (InITBlock()) {
|
|
// MOV<c>{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
|
|
mov(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// MOVS{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2
|
|
movs(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x20000000: {
|
|
// 0x20000000
|
|
switch (instr & 0x18000000) {
|
|
case 0x00000000: {
|
|
// 0x20000000
|
|
unsigned rd = (instr >> 24) & 0x7;
|
|
uint32_t imm = (instr >> 16) & 0xff;
|
|
if (InITBlock()) {
|
|
// MOV<c>{<q>} <Rd>, #<imm8> ; T1
|
|
mov(CurrentCond(), Narrow, Register(rd), imm);
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// MOVS{<q>} <Rd>, #<imm8> ; T1
|
|
movs(Condition::None(), Narrow, Register(rd), imm);
|
|
}
|
|
break;
|
|
}
|
|
case 0x08000000: {
|
|
// 0x28000000
|
|
unsigned rn = (instr >> 24) & 0x7;
|
|
uint32_t imm = (instr >> 16) & 0xff;
|
|
// CMP{<c>}{<q>} <Rn>, #<imm8> ; T1
|
|
cmp(CurrentCond(), Narrow, Register(rn), imm);
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0x30000000
|
|
unsigned rd = (instr >> 24) & 0x7;
|
|
uint32_t imm = (instr >> 16) & 0xff;
|
|
if (InITBlock() && ((imm <= 7))) {
|
|
// ADD<c>{<q>} <Rdn>, #<imm8> ; T2
|
|
add(CurrentCond(), Register(rd), imm);
|
|
} else if (InITBlock() && ((imm > 7))) {
|
|
// ADD<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
|
|
add(CurrentCond(), Narrow, Register(rd), Register(rd), imm);
|
|
} else if (OutsideITBlock() && ((imm <= 7))) {
|
|
// ADDS{<q>} <Rdn>, #<imm8> ; T2
|
|
adds(Register(rd), imm);
|
|
} else if (OutsideITBlock() && ((imm > 7))) {
|
|
// ADDS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
|
|
adds(Condition::None(), Narrow, Register(rd), Register(rd), imm);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x18000000: {
|
|
// 0x38000000
|
|
unsigned rd = (instr >> 24) & 0x7;
|
|
uint32_t imm = (instr >> 16) & 0xff;
|
|
if (InITBlock() && ((imm <= 7))) {
|
|
// SUB<c>{<q>} <Rdn>, #<imm8> ; T2
|
|
sub(CurrentCond(), Register(rd), imm);
|
|
} else if (InITBlock() && ((imm > 7))) {
|
|
// SUB<c>{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
|
|
sub(CurrentCond(), Narrow, Register(rd), Register(rd), imm);
|
|
} else if (OutsideITBlock() && ((imm <= 7))) {
|
|
// SUBS{<q>} <Rdn>, #<imm8> ; T2
|
|
subs(Register(rd), imm);
|
|
} else if (OutsideITBlock() && ((imm > 7))) {
|
|
// SUBS{<q>} {<Rdn>}, <Rdn>, #<imm8> ; T2
|
|
subs(Condition::None(), Narrow, Register(rd), Register(rd), imm);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x40000000: {
|
|
// 0x40000000
|
|
switch (instr & 0x18000000) {
|
|
case 0x00000000: {
|
|
// 0x40000000
|
|
switch (instr & 0x07000000) {
|
|
case 0x00000000: {
|
|
// 0x40000000
|
|
switch (instr & 0x00c00000) {
|
|
case 0x00000000: {
|
|
// 0x40000000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
if (InITBlock()) {
|
|
// AND<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
|
|
and_(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rm));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// ANDS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
|
|
ands(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rm));
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x40400000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
if (InITBlock()) {
|
|
// EOR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
|
|
eor(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rm));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// EORS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
|
|
eors(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rm));
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x40800000
|
|
if (InITBlock()) {
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rs = (instr >> 19) & 0x7;
|
|
// LSL<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
|
|
lsl(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rs));
|
|
return;
|
|
}
|
|
if (!InITBlock()) {
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rs = (instr >> 19) & 0x7;
|
|
// LSLS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
|
|
lsls(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rs));
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 16) & 0x7;
|
|
unsigned rs = (instr >> 19) & 0x7;
|
|
if (InITBlock()) {
|
|
// MOV<c>{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
|
|
mov(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Operand(Register(rm), LSL, Register(rs)));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// MOVS{<q>} <Rdm>, <Rdm>, LSL <Rs> ; T1
|
|
movs(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Operand(Register(rm), LSL, Register(rs)));
|
|
}
|
|
break;
|
|
}
|
|
case 0x00c00000: {
|
|
// 0x40c00000
|
|
if (InITBlock()) {
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rs = (instr >> 19) & 0x7;
|
|
// LSR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
|
|
lsr(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rs));
|
|
return;
|
|
}
|
|
if (!InITBlock()) {
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rs = (instr >> 19) & 0x7;
|
|
// LSRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
|
|
lsrs(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rs));
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 16) & 0x7;
|
|
unsigned rs = (instr >> 19) & 0x7;
|
|
if (InITBlock()) {
|
|
// MOV<c>{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
|
|
mov(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Operand(Register(rm), LSR, Register(rs)));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// MOVS{<q>} <Rdm>, <Rdm>, LSR <Rs> ; T1
|
|
movs(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Operand(Register(rm), LSR, Register(rs)));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x41000000
|
|
switch (instr & 0x00c00000) {
|
|
case 0x00000000: {
|
|
// 0x41000000
|
|
if (InITBlock()) {
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rs = (instr >> 19) & 0x7;
|
|
// ASR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
|
|
asr(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rs));
|
|
return;
|
|
}
|
|
if (!InITBlock()) {
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rs = (instr >> 19) & 0x7;
|
|
// ASRS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
|
|
asrs(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rs));
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 16) & 0x7;
|
|
unsigned rs = (instr >> 19) & 0x7;
|
|
if (InITBlock()) {
|
|
// MOV<c>{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
|
|
mov(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Operand(Register(rm), ASR, Register(rs)));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// MOVS{<q>} <Rdm>, <Rdm>, ASR <Rs> ; T1
|
|
movs(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Operand(Register(rm), ASR, Register(rs)));
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x41400000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
if (InITBlock()) {
|
|
// ADC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
|
|
adc(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rm));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// ADCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
|
|
adcs(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rm));
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x41800000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
if (InITBlock()) {
|
|
// SBC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
|
|
sbc(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rm));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// SBCS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
|
|
sbcs(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rm));
|
|
}
|
|
break;
|
|
}
|
|
case 0x00c00000: {
|
|
// 0x41c00000
|
|
if (InITBlock()) {
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rs = (instr >> 19) & 0x7;
|
|
// ROR<c>{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
|
|
ror(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rs));
|
|
return;
|
|
}
|
|
if (!InITBlock()) {
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rs = (instr >> 19) & 0x7;
|
|
// RORS{<q>} {<Rdm>}, <Rdm>, <Rs> ; T1
|
|
rors(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rs));
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 16) & 0x7;
|
|
unsigned rs = (instr >> 19) & 0x7;
|
|
if (InITBlock()) {
|
|
// MOV<c>{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
|
|
mov(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Operand(Register(rm), ROR, Register(rs)));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// MOVS{<q>} <Rdm>, <Rdm>, ROR <Rs> ; T1
|
|
movs(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Operand(Register(rm), ROR, Register(rs)));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x02000000: {
|
|
// 0x42000000
|
|
switch (instr & 0x00c00000) {
|
|
case 0x00000000: {
|
|
// 0x42000000
|
|
unsigned rn = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
// TST{<c>}{<q>} <Rn>, <Rm> ; T1
|
|
tst(CurrentCond(), Narrow, Register(rn), Register(rm));
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x42400000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
if (InITBlock()) {
|
|
// RSB<c>{<q>} {<Rd>}, <Rn>, #0 ; T1
|
|
rsb(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rn),
|
|
UINT32_C(0));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// RSBS{<q>} {<Rd>}, <Rn>, #0 ; T1
|
|
rsbs(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rn),
|
|
UINT32_C(0));
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x42800000
|
|
unsigned rn = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
// CMP{<c>}{<q>} <Rn>, <Rm> ; T1
|
|
cmp(CurrentCond(), Narrow, Register(rn), Register(rm));
|
|
break;
|
|
}
|
|
case 0x00c00000: {
|
|
// 0x42c00000
|
|
unsigned rn = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
// CMN{<c>}{<q>} <Rn>, <Rm> ; T1
|
|
cmn(CurrentCond(), Narrow, Register(rn), Register(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x03000000: {
|
|
// 0x43000000
|
|
switch (instr & 0x00c00000) {
|
|
case 0x00000000: {
|
|
// 0x43000000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
if (InITBlock()) {
|
|
// ORR<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
|
|
orr(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rm));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// ORRS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
|
|
orrs(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rm));
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x43400000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
if (InITBlock()) {
|
|
// MUL<c>{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
|
|
mul(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rd));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// MULS{<q>} <Rdm>, <Rn>, {<Rdm>} ; T1
|
|
muls(Condition::None(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rd));
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x43800000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
if (InITBlock()) {
|
|
// BIC<c>{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
|
|
bic(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rm));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// BICS{<q>} {<Rdn>}, <Rdn>, <Rm> ; T1
|
|
bics(Condition::None(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rm));
|
|
}
|
|
break;
|
|
}
|
|
case 0x00c00000: {
|
|
// 0x43c00000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
if (InITBlock()) {
|
|
// MVN<c>{<q>} <Rd>, <Rm> ; T1
|
|
mvn(CurrentCond(), Narrow, Register(rd), Register(rm));
|
|
} else {
|
|
VIXL_ASSERT(OutsideITBlock());
|
|
// MVNS{<q>} <Rd>, <Rm> ; T1
|
|
mvns(Condition::None(), Narrow, Register(rd), Register(rm));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x04000000: {
|
|
// 0x44000000
|
|
switch (instr & 0x00780000) {
|
|
case 0x00680000: {
|
|
// 0x44680000
|
|
unsigned rd = ((instr >> 16) & 0x7) | ((instr >> 20) & 0x8);
|
|
// ADD{<c>}{<q>} {<Rdm>}, SP, <Rdm> ; T1
|
|
add(CurrentCond(), Narrow, Register(rd), sp, Register(rd));
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00870000) {
|
|
case 0x00850000: {
|
|
// 0x44850000
|
|
if (((instr & 0x780000) == 0x680000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = (instr >> 19) & 0xf;
|
|
// ADD{<c>}{<q>} {SP}, SP, <Rm> ; T2
|
|
add(CurrentCond(), Narrow, sp, sp, Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x780000) == 0x680000) ||
|
|
((instr & 0x870000) == 0x850000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
((instr >> 16) & 0x7) | ((instr >> 20) & 0x8);
|
|
unsigned rm = (instr >> 19) & 0xf;
|
|
if (InITBlock()) {
|
|
// ADD<c>{<q>} <Rdn>, <Rm> ; T2
|
|
add(CurrentCond(), Register(rd), Register(rm));
|
|
} else {
|
|
// ADD{<c>}{<q>} {<Rdn>}, <Rdn>, <Rm> ; T2
|
|
add(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rd),
|
|
Register(rm));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x05000000: {
|
|
// 0x45000000
|
|
unsigned rn = ((instr >> 16) & 0x7) | ((instr >> 20) & 0x8);
|
|
unsigned rm = (instr >> 19) & 0xf;
|
|
// CMP{<c>}{<q>} <Rn>, <Rm> ; T2
|
|
cmp(CurrentCond(), Narrow, Register(rn), Register(rm));
|
|
break;
|
|
}
|
|
case 0x06000000: {
|
|
// 0x46000000
|
|
unsigned rd = ((instr >> 16) & 0x7) | ((instr >> 20) & 0x8);
|
|
unsigned rm = (instr >> 19) & 0xf;
|
|
// MOV{<c>}{<q>} <Rd>, <Rm> ; T1
|
|
mov(CurrentCond(), Narrow, Register(rd), Register(rm));
|
|
break;
|
|
}
|
|
case 0x07000000: {
|
|
// 0x47000000
|
|
switch (instr & 0x00800000) {
|
|
case 0x00000000: {
|
|
// 0x47000000
|
|
unsigned rm = (instr >> 19) & 0xf;
|
|
// BX{<c>}{<q>} <Rm> ; T1
|
|
bx(CurrentCond(), Register(rm));
|
|
if (((instr & 0xff870000) != 0x47000000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x47800000
|
|
unsigned rm = (instr >> 19) & 0xf;
|
|
// BLX{<c>}{<q>} <Rm> ; T1
|
|
blx(CurrentCond(), Register(rm));
|
|
if (((instr & 0xff870000) != 0x47800000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x08000000: {
|
|
// 0x48000000
|
|
unsigned rt = (instr >> 24) & 0x7;
|
|
int32_t imm = ((instr >> 16) & 0xff) << 2;
|
|
Location location(imm, kT32PcDelta);
|
|
// LDR{<c>}{<q>} <Rt>, <label> ; T1
|
|
ldr(CurrentCond(), Narrow, Register(rt), &location);
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0x50000000
|
|
switch (instr & 0x06000000) {
|
|
case 0x00000000: {
|
|
// 0x50000000
|
|
unsigned rt = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
Sign sign(plus);
|
|
unsigned rm = (instr >> 22) & 0x7;
|
|
AddrMode addrmode = Offset;
|
|
// STR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
|
|
str(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, Register(rm), addrmode));
|
|
break;
|
|
}
|
|
case 0x02000000: {
|
|
// 0x52000000
|
|
unsigned rt = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
Sign sign(plus);
|
|
unsigned rm = (instr >> 22) & 0x7;
|
|
AddrMode addrmode = Offset;
|
|
// STRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
|
|
strh(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, Register(rm), addrmode));
|
|
break;
|
|
}
|
|
case 0x04000000: {
|
|
// 0x54000000
|
|
unsigned rt = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
Sign sign(plus);
|
|
unsigned rm = (instr >> 22) & 0x7;
|
|
AddrMode addrmode = Offset;
|
|
// STRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
|
|
strb(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, Register(rm), addrmode));
|
|
break;
|
|
}
|
|
case 0x06000000: {
|
|
// 0x56000000
|
|
unsigned rt = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
Sign sign(plus);
|
|
unsigned rm = (instr >> 22) & 0x7;
|
|
AddrMode addrmode = Offset;
|
|
// LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
|
|
ldrsb(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, Register(rm), addrmode));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x18000000: {
|
|
// 0x58000000
|
|
switch (instr & 0x06000000) {
|
|
case 0x00000000: {
|
|
// 0x58000000
|
|
unsigned rt = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
Sign sign(plus);
|
|
unsigned rm = (instr >> 22) & 0x7;
|
|
AddrMode addrmode = Offset;
|
|
// LDR{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
|
|
ldr(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, Register(rm), addrmode));
|
|
break;
|
|
}
|
|
case 0x02000000: {
|
|
// 0x5a000000
|
|
unsigned rt = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
Sign sign(plus);
|
|
unsigned rm = (instr >> 22) & 0x7;
|
|
AddrMode addrmode = Offset;
|
|
// LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
|
|
ldrh(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, Register(rm), addrmode));
|
|
break;
|
|
}
|
|
case 0x04000000: {
|
|
// 0x5c000000
|
|
unsigned rt = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
Sign sign(plus);
|
|
unsigned rm = (instr >> 22) & 0x7;
|
|
AddrMode addrmode = Offset;
|
|
// LDRB{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
|
|
ldrb(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, Register(rm), addrmode));
|
|
break;
|
|
}
|
|
case 0x06000000: {
|
|
// 0x5e000000
|
|
unsigned rt = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
Sign sign(plus);
|
|
unsigned rm = (instr >> 22) & 0x7;
|
|
AddrMode addrmode = Offset;
|
|
// LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+}<Rm>] ; T1
|
|
ldrsh(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, Register(rm), addrmode));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x60000000: {
|
|
// 0x60000000
|
|
switch (instr & 0x18000000) {
|
|
case 0x00000000: {
|
|
// 0x60000000
|
|
unsigned rt = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
int32_t offset = ((instr >> 22) & 0x1f) << 2;
|
|
// STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
|
|
str(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(Register(rn), plus, offset, Offset));
|
|
break;
|
|
}
|
|
case 0x08000000: {
|
|
// 0x68000000
|
|
unsigned rt = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
int32_t offset = ((instr >> 22) & 0x1f) << 2;
|
|
// LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
|
|
ldr(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(Register(rn), plus, offset, Offset));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0x70000000
|
|
unsigned rt = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
int32_t offset = (instr >> 22) & 0x1f;
|
|
// STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
|
|
strb(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(Register(rn), plus, offset, Offset));
|
|
break;
|
|
}
|
|
case 0x18000000: {
|
|
// 0x78000000
|
|
unsigned rt = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
int32_t offset = (instr >> 22) & 0x1f;
|
|
// LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
|
|
ldrb(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(Register(rn), plus, offset, Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x80000000: {
|
|
// 0x80000000
|
|
switch (instr & 0x18000000) {
|
|
case 0x00000000: {
|
|
// 0x80000000
|
|
unsigned rt = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
int32_t offset = ((instr >> 22) & 0x1f) << 1;
|
|
// STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
|
|
strh(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(Register(rn), plus, offset, Offset));
|
|
break;
|
|
}
|
|
case 0x08000000: {
|
|
// 0x88000000
|
|
unsigned rt = (instr >> 16) & 0x7;
|
|
unsigned rn = (instr >> 19) & 0x7;
|
|
int32_t offset = ((instr >> 22) & 0x1f) << 1;
|
|
// LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1
|
|
ldrh(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(Register(rn), plus, offset, Offset));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0x90000000
|
|
unsigned rt = (instr >> 24) & 0x7;
|
|
int32_t offset = ((instr >> 16) & 0xff) << 2;
|
|
// STR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
|
|
str(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(sp, plus, offset, Offset));
|
|
break;
|
|
}
|
|
case 0x18000000: {
|
|
// 0x98000000
|
|
unsigned rt = (instr >> 24) & 0x7;
|
|
int32_t offset = ((instr >> 16) & 0xff) << 2;
|
|
// LDR{<c>}{<q>} <Rt>, [SP{, #{+}<imm>}] ; T2
|
|
ldr(CurrentCond(),
|
|
Narrow,
|
|
Register(rt),
|
|
MemOperand(sp, plus, offset, Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0xa0000000: {
|
|
// 0xa0000000
|
|
switch (instr & 0x18000000) {
|
|
case 0x00000000: {
|
|
// 0xa0000000
|
|
unsigned rd = (instr >> 24) & 0x7;
|
|
int32_t imm = ((instr >> 16) & 0xff) << 2;
|
|
Location location(imm, kT32PcDelta);
|
|
// ADR{<c>}{<q>} <Rd>, <label> ; T1
|
|
adr(CurrentCond(), Narrow, Register(rd), &location);
|
|
break;
|
|
}
|
|
case 0x08000000: {
|
|
// 0xa8000000
|
|
unsigned rd = (instr >> 24) & 0x7;
|
|
uint32_t imm = ((instr >> 16) & 0xff) << 2;
|
|
// ADD{<c>}{<q>} <Rd>, SP, #<imm8> ; T1
|
|
add(CurrentCond(), Narrow, Register(rd), sp, imm);
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xb0000000
|
|
switch (instr & 0x04000000) {
|
|
case 0x00000000: {
|
|
// 0xb0000000
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xb0000000
|
|
switch (instr & 0x02800000) {
|
|
case 0x00000000: {
|
|
// 0xb0000000
|
|
uint32_t imm = ((instr >> 16) & 0x7f) << 2;
|
|
// ADD{<c>}{<q>} {SP}, SP, #<imm7> ; T2
|
|
add(CurrentCond(), Narrow, sp, sp, imm);
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xb0800000
|
|
uint32_t imm = ((instr >> 16) & 0x7f) << 2;
|
|
// SUB{<c>}{<q>} {SP}, SP, #<imm7> ; T1
|
|
sub(CurrentCond(), Narrow, sp, sp, imm);
|
|
break;
|
|
}
|
|
case 0x02000000: {
|
|
// 0xb2000000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0xb2000000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
// SXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
|
|
sxth(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xb2400000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
// SXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
|
|
sxtb(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x02800000: {
|
|
// 0xb2800000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0xb2800000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
// UXTH{<c>}{<q>} {<Rd>}, <Rm> ; T1
|
|
uxth(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xb2c00000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
// UXTB{<c>}{<q>} {<Rd>}, <Rm> ; T1
|
|
uxtb(CurrentCond(),
|
|
Narrow,
|
|
Register(rd),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xb1000000
|
|
unsigned rn = (instr >> 16) & 0x7;
|
|
int32_t imm =
|
|
(((instr >> 19) & 0x1f) | ((instr >> 20) & 0x20)) << 1;
|
|
Location location(imm, kT32PcDelta);
|
|
// CBZ{<q>} <Rn>, <label> ; T1
|
|
cbz(Register(rn), &location);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x04000000: {
|
|
// 0xb4000000
|
|
switch (instr & 0x02000000) {
|
|
case 0x00000000: {
|
|
// 0xb4000000
|
|
RegisterList registers((((instr >> 24) & 0x1) << kLRRegNum) |
|
|
((instr >> 16) & 0xff));
|
|
// PUSH{<c>}{<q>} <registers> ; T1
|
|
push(CurrentCond(), Narrow, registers);
|
|
break;
|
|
}
|
|
case 0x02000000: {
|
|
// 0xb6000000
|
|
switch (instr & 0x01e00000) {
|
|
case 0x00400000: {
|
|
// 0xb6400000
|
|
UnimplementedT32_16("SETEND", instr);
|
|
break;
|
|
}
|
|
case 0x00600000: {
|
|
// 0xb6600000
|
|
switch (instr & 0x00100000) {
|
|
case 0x00000000: {
|
|
// 0xb6600000
|
|
UnimplementedT32_16("CPSIE", instr);
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xb6700000
|
|
UnimplementedT32_16("CPSID", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x18000000: {
|
|
// 0xb8000000
|
|
switch (instr & 0x04000000) {
|
|
case 0x00000000: {
|
|
// 0xb8000000
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xb8000000
|
|
switch (instr & 0x02c00000) {
|
|
case 0x02000000: {
|
|
// 0xba000000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
// REV{<c>}{<q>} <Rd>, <Rm> ; T1
|
|
rev(CurrentCond(), Narrow, Register(rd), Register(rm));
|
|
break;
|
|
}
|
|
case 0x02400000: {
|
|
// 0xba400000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
// REV16{<c>}{<q>} <Rd>, <Rm> ; T1
|
|
rev16(CurrentCond(), Narrow, Register(rd), Register(rm));
|
|
break;
|
|
}
|
|
case 0x02800000: {
|
|
// 0xba800000
|
|
uint32_t imm = (instr >> 16) & 0x3f;
|
|
// HLT{<q>} {#}<imm> ; T1
|
|
hlt(Condition::None(), imm);
|
|
break;
|
|
}
|
|
case 0x02c00000: {
|
|
// 0xbac00000
|
|
unsigned rd = (instr >> 16) & 0x7;
|
|
unsigned rm = (instr >> 19) & 0x7;
|
|
// REVSH{<c>}{<q>} <Rd>, <Rm> ; T1
|
|
revsh(CurrentCond(), Narrow, Register(rd), Register(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xb9000000
|
|
unsigned rn = (instr >> 16) & 0x7;
|
|
int32_t imm =
|
|
(((instr >> 19) & 0x1f) | ((instr >> 20) & 0x20)) << 1;
|
|
Location location(imm, kT32PcDelta);
|
|
// CBNZ{<q>} <Rn>, <label> ; T1
|
|
cbnz(Register(rn), &location);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x04000000: {
|
|
// 0xbc000000
|
|
switch (instr & 0x02000000) {
|
|
case 0x00000000: {
|
|
// 0xbc000000
|
|
RegisterList registers((((instr >> 24) & 0x1) << kPCRegNum) |
|
|
((instr >> 16) & 0xff));
|
|
// POP{<c>}{<q>} <registers> ; T1
|
|
pop(CurrentCond(), Narrow, registers);
|
|
break;
|
|
}
|
|
case 0x02000000: {
|
|
// 0xbe000000
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xbe000000
|
|
uint32_t imm = (instr >> 16) & 0xff;
|
|
// BKPT{<q>} {#}<imm> ; T1
|
|
bkpt(Condition::None(), imm);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xbf000000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x00000000: {
|
|
// 0xbf000000
|
|
switch (instr & 0x00f00000) {
|
|
case 0x00000000: {
|
|
// 0xbf000000
|
|
// NOP{<c>}{<q>} ; T1
|
|
nop(CurrentCond(), Narrow);
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xbf100000
|
|
// YIELD{<c>}{<q>} ; T1
|
|
yield(CurrentCond(), Narrow);
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xbf200000
|
|
UnimplementedT32_16("WFE", instr);
|
|
break;
|
|
}
|
|
case 0x00300000: {
|
|
// 0xbf300000
|
|
UnimplementedT32_16("WFI", instr);
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xbf400000
|
|
UnimplementedT32_16("SEV", instr);
|
|
break;
|
|
}
|
|
case 0x00500000: {
|
|
// 0xbf500000
|
|
UnimplementedT32_16("SEVL", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned firstcond = (instr >> 20) & 0xf;
|
|
unsigned mask = (instr >> 16) & 0xf;
|
|
bool wasInITBlock = InITBlock();
|
|
SetIT(Condition(firstcond), mask);
|
|
it(Condition(firstcond), mask);
|
|
if (wasInITBlock || (firstcond == 15) ||
|
|
((firstcond == al) &&
|
|
(BitCount(Uint32(mask)) != 1))) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0xc0000000: {
|
|
// 0xc0000000
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xc0000000
|
|
switch (instr & 0x08000000) {
|
|
case 0x00000000: {
|
|
// 0xc0000000
|
|
unsigned rn = (instr >> 24) & 0x7;
|
|
RegisterList registers(((instr >> 16) & 0xff));
|
|
// STM{<c>}{<q>} <Rn>!, <registers> ; T1
|
|
stm(CurrentCond(),
|
|
Narrow,
|
|
Register(rn),
|
|
WriteBack(WRITE_BACK),
|
|
registers);
|
|
break;
|
|
}
|
|
case 0x08000000: {
|
|
// 0xc8000000
|
|
unsigned rn = (instr >> 24) & 0x7;
|
|
RegisterList registers(((instr >> 16) & 0xff));
|
|
// LDM{<c>}{<q>} <Rn>{!}, <registers> ; T1
|
|
ldm(CurrentCond(),
|
|
Narrow,
|
|
Register(rn),
|
|
WriteBack(!registers.Includes(Register(rn))),
|
|
registers);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xd0000000
|
|
switch (instr & 0x0e000000) {
|
|
case 0x0e000000: {
|
|
// 0xde000000
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xde000000
|
|
uint32_t imm = (instr >> 16) & 0xff;
|
|
// UDF{<c>}{<q>} {#}<imm> ; T1
|
|
udf(CurrentCond(), Narrow, imm);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xdf000000
|
|
uint32_t imm = (instr >> 16) & 0xff;
|
|
// SVC{<c>}{<q>} {#}<imm> ; T1
|
|
svc(CurrentCond(), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xe000000) == 0xe000000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 24) & 0xf);
|
|
int32_t imm = SignExtend<int32_t>(((instr >> 16) & 0xff) << 1, 9);
|
|
Location location(imm, kT32PcDelta);
|
|
// B<c>{<q>} <label> ; T1
|
|
b(condition, Narrow, &location);
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0xe0000000: {
|
|
// 0xe0000000
|
|
switch (instr & 0x08000000) {
|
|
case 0x00000000: {
|
|
// 0xe0000000
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xe0000000
|
|
int32_t imm =
|
|
SignExtend<int32_t>(((instr >> 16) & 0x7ff) << 1, 12);
|
|
Location location(imm, kT32PcDelta);
|
|
// B{<c>}{<q>} <label> ; T2
|
|
b(CurrentCond(), Narrow, &location);
|
|
if (!OutsideITBlockOrLast()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xf0000000
|
|
switch (instr & 0x00008000) {
|
|
case 0x00000000: {
|
|
// 0xf0000000
|
|
switch (instr & 0x03f00000) {
|
|
case 0x00000000: {
|
|
// 0xf0000000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
|
|
and_(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xf0100000
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000f00: {
|
|
// 0xf0100f00
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// TST{<c>}{<q>} <Rn>, #<const> ; T1
|
|
tst(CurrentCond(), Best, Register(rn), imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
|
|
ands(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf0200000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
|
|
bic(CurrentCond(), Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
case 0x00300000: {
|
|
// 0xf0300000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
|
|
bics(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xf0400000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xf04f0000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
if (InITBlock() &&
|
|
(instr & 0x00100000) == 0x00000000 &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(imm <= 255))) {
|
|
// MOV<c>.W <Rd>, #<const> ; T2
|
|
mov(CurrentCond(), Wide, Register(rd), imm);
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// MOV{<c>}{<q>} <Rd>, #<const> ; T2
|
|
mov(CurrentCond(), Best, Register(rd), imm);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
|
|
orr(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00500000: {
|
|
// 0xf0500000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xf05f0000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
if (OutsideITBlock() &&
|
|
(instr & 0x00100000) == 0x00100000 &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(imm <= 255))) {
|
|
// MOVS.W <Rd>, #<const> ; T2
|
|
movs(Condition::None(), Wide, Register(rd), imm);
|
|
} else if ((instr & 0x00100000) == 0x00100000) {
|
|
// MOVS{<c>}{<q>} <Rd>, #<const> ; T2
|
|
movs(CurrentCond(), Best, Register(rd), imm);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
|
|
orrs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00600000: {
|
|
// 0xf0600000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xf06f0000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// MVN{<c>}{<q>} <Rd>, #<const> ; T1
|
|
mvn(CurrentCond(), Best, Register(rd), imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// ORN{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
|
|
orn(CurrentCond(), Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00700000: {
|
|
// 0xf0700000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xf07f0000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// MVNS{<c>}{<q>} <Rd>, #<const> ; T1
|
|
mvns(CurrentCond(), Best, Register(rd), imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// ORNS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
|
|
orns(CurrentCond(), Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xf0800000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
|
|
eor(CurrentCond(), Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
case 0x00900000: {
|
|
// 0xf0900000
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000f00: {
|
|
// 0xf0900f00
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// TEQ{<c>}{<q>} <Rn>, #<const> ; T1
|
|
teq(CurrentCond(), Register(rn), imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
|
|
eors(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf1000000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000d0000: {
|
|
// 0xf10d0000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
if ((instr & 0x00100000) == 0x00000000 &&
|
|
(((rd < kNumberOfT32LowRegisters) &&
|
|
((imm <= 1020) && ((imm & 3) == 0))) ||
|
|
((rd == sp.GetCode()) &&
|
|
((imm <= 508) && ((imm & 3) == 0))))) {
|
|
// ADD{<c>}.W {<Rd>}, SP, #<const> ; T3
|
|
add(CurrentCond(), Wide, Register(rd), sp, imm);
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
|
|
add(CurrentCond(), Best, Register(rd), sp, imm);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xd0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
if (InITBlock() &&
|
|
(instr & 0x00100000) == 0x00000000 &&
|
|
(((rd < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
(imm <= 7)) ||
|
|
((rd == rn) && (rd < kNumberOfT32LowRegisters) &&
|
|
(imm <= 255)))) {
|
|
// ADD<c>.W {<Rd>}, <Rn>, #<const> ; T3
|
|
add(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
|
|
add(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01100000: {
|
|
// 0xf1100000
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000f00: {
|
|
// 0xf1100f00
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// CMN{<c>}{<q>} <Rn>, #<const> ; T1
|
|
cmn(CurrentCond(), Best, Register(rn), imm);
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000d0000: {
|
|
// 0xf11d0000
|
|
if (((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; T3
|
|
adds(CurrentCond(), Best, Register(rd), sp, imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xd0000) ||
|
|
((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
if (OutsideITBlock() &&
|
|
(instr & 0x00100000) == 0x00100000 &&
|
|
(((rd < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
(imm <= 7)) ||
|
|
((rd == rn) &&
|
|
(rd < kNumberOfT32LowRegisters) &&
|
|
(imm <= 255)))) {
|
|
// ADDS.W {<Rd>}, <Rn>, #<const> ; T3
|
|
adds(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
} else if ((instr & 0x00100000) == 0x00100000) {
|
|
// ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
|
|
adds(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01400000: {
|
|
// 0xf1400000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
|
|
adc(CurrentCond(), Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
case 0x01500000: {
|
|
// 0xf1500000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
|
|
adcs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x01600000: {
|
|
// 0xf1600000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
|
|
sbc(CurrentCond(), Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
case 0x01700000: {
|
|
// 0xf1700000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T1
|
|
sbcs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x01a00000: {
|
|
// 0xf1a00000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000d0000: {
|
|
// 0xf1ad0000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
if ((instr & 0x00100000) == 0x00000000 &&
|
|
((rd == sp.GetCode()) &&
|
|
((imm <= 508) && ((imm & 3) == 0)))) {
|
|
// SUB{<c>}.W {<Rd>}, SP, #<const> ; T2
|
|
sub(CurrentCond(), Wide, Register(rd), sp, imm);
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
|
|
sub(CurrentCond(), Best, Register(rd), sp, imm);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xd0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
if (InITBlock() &&
|
|
(instr & 0x00100000) == 0x00000000 &&
|
|
(((rd < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
(imm <= 7)) ||
|
|
((rd == rn) && (rd < kNumberOfT32LowRegisters) &&
|
|
(imm <= 255)))) {
|
|
// SUB<c>.W {<Rd>}, <Rn>, #<const> ; T3
|
|
sub(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
|
|
sub(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01b00000: {
|
|
// 0xf1b00000
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000f00: {
|
|
// 0xf1b00f00
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
if ((rn < kNumberOfT32LowRegisters) && (imm <= 255)) {
|
|
// CMP{<c>}.W <Rn>, #<const> ; T2
|
|
cmp(CurrentCond(), Wide, Register(rn), imm);
|
|
} else {
|
|
// CMP{<c>}{<q>} <Rn>, #<const> ; T2
|
|
cmp(CurrentCond(), Best, Register(rn), imm);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000d0000: {
|
|
// 0xf1bd0000
|
|
if (((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
// SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; T2
|
|
subs(CurrentCond(), Best, Register(rd), sp, imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xd0000) ||
|
|
((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
if (OutsideITBlock() &&
|
|
(instr & 0x00100000) == 0x00100000 &&
|
|
(((rd < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
(imm <= 7)) ||
|
|
((rd == rn) &&
|
|
(rd < kNumberOfT32LowRegisters) &&
|
|
(imm <= 255)))) {
|
|
// SUBS.W {<Rd>}, <Rn>, #<const> ; T3
|
|
subs(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
} else if ((instr & 0x00100000) == 0x00100000) {
|
|
// SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T3
|
|
subs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01c00000: {
|
|
// 0xf1c00000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
if (InITBlock() && (instr & 0x00100000) == 0x00000000 &&
|
|
(imm == 0) &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) && (imm == 0))) {
|
|
// RSB<c>.W {<Rd>}, <Rn>, #0 ; T2
|
|
rsb(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
UINT32_C(0));
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
|
|
rsb(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01d00000: {
|
|
// 0xf1d00000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateT32::Decode(
|
|
(instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800));
|
|
if (OutsideITBlock() &&
|
|
(instr & 0x00100000) == 0x00100000 && (imm == 0) &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) && (imm == 0))) {
|
|
// RSBS.W {<Rd>}, <Rn>, #0 ; T2
|
|
rsbs(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
UINT32_C(0));
|
|
} else if ((instr & 0x00100000) == 0x00100000) {
|
|
// RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; T2
|
|
rsbs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x02000000: {
|
|
// 0xf2000000
|
|
switch (instr & 0x000d0000) {
|
|
case 0x000d0000: {
|
|
// 0xf20d0000
|
|
switch (instr & 0x00020000) {
|
|
case 0x00000000: {
|
|
// 0xf20d0000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = (instr & 0xff) |
|
|
((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800);
|
|
if (((rd >= kNumberOfT32LowRegisters) ||
|
|
((imm > 1020) || ((imm & 3) != 0))) &&
|
|
((rd != sp.GetCode()) ||
|
|
((imm > 508) || ((imm & 3) != 0))) &&
|
|
(!ImmediateT32::IsImmediateT32(imm))) {
|
|
// ADD{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
|
|
add(CurrentCond(), Best, Register(rd), sp, imm);
|
|
} else {
|
|
// ADDW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T4
|
|
addw(CurrentCond(), Register(rd), sp, imm);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00020000: {
|
|
// 0xf20f0000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
int32_t imm = (instr & 0xff) |
|
|
((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800);
|
|
Location location(imm, kT32PcDelta);
|
|
if ((imm >= 0) && (imm <= 4095) &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(imm >= 0) && (imm <= 1020) &&
|
|
((imm & 3) == 0))) {
|
|
// ADR{<c>}.W <Rd>, <label> ; T3
|
|
adr(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
&location);
|
|
} else if ((imm >= 0) && (imm <= 4095)) {
|
|
// ADR{<c>}{<q>} <Rd>, <label> ; T3
|
|
adr(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
&location);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xd0000) == 0xd0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = (instr & 0xff) |
|
|
((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800);
|
|
if ((InITBlock() ||
|
|
(rd >= kNumberOfT32LowRegisters) ||
|
|
(rn >= kNumberOfT32LowRegisters) || (imm > 7)) &&
|
|
(InITBlock() || (rd != rn) ||
|
|
(rd >= kNumberOfT32LowRegisters) ||
|
|
(imm > 255)) &&
|
|
(!ImmediateT32::IsImmediateT32(imm))) {
|
|
// ADD{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
|
|
add(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
} else {
|
|
// ADDW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
|
|
addw(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x02400000: {
|
|
// 0xf2400000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = (instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800) |
|
|
((instr >> 4) & 0xf000);
|
|
if ((InITBlock() || (rd >= kNumberOfT32LowRegisters) ||
|
|
(imm > 255)) &&
|
|
(!ImmediateT32::IsImmediateT32(imm))) {
|
|
// MOV{<c>}{<q>} <Rd>, #<imm16> ; T3
|
|
mov(CurrentCond(), Best, Register(rd), imm);
|
|
} else {
|
|
// MOVW{<c>}{<q>} <Rd>, #<imm16> ; T3
|
|
movw(CurrentCond(), Register(rd), imm);
|
|
}
|
|
break;
|
|
}
|
|
case 0x02a00000: {
|
|
// 0xf2a00000
|
|
switch (instr & 0x000d0000) {
|
|
case 0x000d0000: {
|
|
// 0xf2ad0000
|
|
switch (instr & 0x00020000) {
|
|
case 0x00000000: {
|
|
// 0xf2ad0000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = (instr & 0xff) |
|
|
((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800);
|
|
if (((rd != sp.GetCode()) ||
|
|
((imm > 508) || ((imm & 3) != 0))) &&
|
|
(!ImmediateT32::IsImmediateT32(imm))) {
|
|
// SUB{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
|
|
sub(CurrentCond(), Best, Register(rd), sp, imm);
|
|
} else {
|
|
// SUBW{<c>}{<q>} {<Rd>}, SP, #<imm12> ; T3
|
|
subw(CurrentCond(), Register(rd), sp, imm);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00020000: {
|
|
// 0xf2af0000
|
|
if (((((Uint32((instr >> 26)) & Uint32(0x1))
|
|
<< 11) |
|
|
((Uint32((instr >> 12)) & Uint32(0x7))
|
|
<< 8) |
|
|
(Uint32(instr) & Uint32(0xff))) ==
|
|
Uint32(0x0))) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = (instr & 0xff) |
|
|
((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800);
|
|
// SUB{<c>}{<q>} <Rd>, PC, #<imm12> ; T2
|
|
sub(CurrentCond(), Best, Register(rd), pc, imm);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
int32_t imm = (instr & 0xff) |
|
|
((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800);
|
|
Location location(-imm, kT32PcDelta);
|
|
// ADR{<c>}{<q>} <Rd>, <label> ; T2
|
|
adr(CurrentCond(), Best, Register(rd), &location);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xd0000) == 0xd0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = (instr & 0xff) |
|
|
((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800);
|
|
if ((InITBlock() ||
|
|
(rd >= kNumberOfT32LowRegisters) ||
|
|
(rn >= kNumberOfT32LowRegisters) || (imm > 7)) &&
|
|
(InITBlock() || (rd != rn) ||
|
|
(rd >= kNumberOfT32LowRegisters) ||
|
|
(imm > 255)) &&
|
|
(!ImmediateT32::IsImmediateT32(imm))) {
|
|
// SUB{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
|
|
sub(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
} else {
|
|
// SUBW{<c>}{<q>} {<Rd>}, <Rn>, #<imm12> ; T4
|
|
subw(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
imm);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x02c00000: {
|
|
// 0xf2c00000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = (instr & 0xff) | ((instr >> 4) & 0x700) |
|
|
((instr >> 15) & 0x800) |
|
|
((instr >> 4) & 0xf000);
|
|
// MOVT{<c>}{<q>} <Rd>, #<imm16> ; T1
|
|
movt(CurrentCond(), Register(rd), imm);
|
|
break;
|
|
}
|
|
case 0x03000000: {
|
|
// 0xf3000000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = (instr & 0x1f) + 1;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t amount =
|
|
((instr >> 6) & 0x3) | ((instr >> 10) & 0x1c);
|
|
// SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
ssat(CurrentCond(),
|
|
Register(rd),
|
|
imm,
|
|
Operand(Register(rn), LSL, amount));
|
|
if (((instr & 0xfff08020) != 0xf3000000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x03200000: {
|
|
// 0xf3200000
|
|
switch (instr & 0x000070c0) {
|
|
case 0x00000000: {
|
|
// 0xf3200000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = (instr & 0xf) + 1;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
|
|
ssat16(CurrentCond(),
|
|
Register(rd),
|
|
imm,
|
|
Register(rn));
|
|
if (((instr & 0xfff0f0f0) != 0xf3200000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70c0) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = (instr & 0x1f) + 1;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t amount =
|
|
((instr >> 6) & 0x3) | ((instr >> 10) & 0x1c);
|
|
// SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1 NOLINT(whitespace/line_length)
|
|
ssat(CurrentCond(),
|
|
Register(rd),
|
|
imm,
|
|
Operand(Register(rn), ASR, amount));
|
|
if (((instr & 0xfff08020) != 0xf3200000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x03400000: {
|
|
// 0xf3400000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t lsb =
|
|
((instr >> 6) & 0x3) | ((instr >> 10) & 0x1c);
|
|
uint32_t widthm1 = instr & 0x1f;
|
|
uint32_t width = widthm1 + 1;
|
|
// SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
|
|
sbfx(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
lsb,
|
|
width);
|
|
if (((instr & 0xfff08020) != 0xf3400000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x03600000: {
|
|
// 0xf3600000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xf36f0000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t lsb =
|
|
((instr >> 6) & 0x3) | ((instr >> 10) & 0x1c);
|
|
uint32_t msb = instr & 0x1f;
|
|
uint32_t width = msb - lsb + 1;
|
|
// BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; T1
|
|
bfc(CurrentCond(), Register(rd), lsb, width);
|
|
if (((instr & 0xffff8020) != 0xf36f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t lsb =
|
|
((instr >> 6) & 0x3) | ((instr >> 10) & 0x1c);
|
|
uint32_t msb = instr & 0x1f;
|
|
uint32_t width = msb - lsb + 1;
|
|
// BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
|
|
bfi(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
lsb,
|
|
width);
|
|
if (((instr & 0xfff08020) != 0xf3600000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x03800000: {
|
|
// 0xf3800000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = instr & 0x1f;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t amount =
|
|
((instr >> 6) & 0x3) | ((instr >> 10) & 0x1c);
|
|
// USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
usat(CurrentCond(),
|
|
Register(rd),
|
|
imm,
|
|
Operand(Register(rn), LSL, amount));
|
|
if (((instr & 0xfff08020) != 0xf3800000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x03a00000: {
|
|
// 0xf3a00000
|
|
switch (instr & 0x000070c0) {
|
|
case 0x00000000: {
|
|
// 0xf3a00000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; T1
|
|
usat16(CurrentCond(),
|
|
Register(rd),
|
|
imm,
|
|
Register(rn));
|
|
if (((instr & 0xfff0f0f0) != 0xf3a00000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70c0) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
uint32_t imm = instr & 0x1f;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t amount =
|
|
((instr >> 6) & 0x3) | ((instr >> 10) & 0x1c);
|
|
// USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; T1 NOLINT(whitespace/line_length)
|
|
usat(CurrentCond(),
|
|
Register(rd),
|
|
imm,
|
|
Operand(Register(rn), ASR, amount));
|
|
if (((instr & 0xfff08020) != 0xf3a00000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x03c00000: {
|
|
// 0xf3c00000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t lsb =
|
|
((instr >> 6) & 0x3) | ((instr >> 10) & 0x1c);
|
|
uint32_t widthm1 = instr & 0x1f;
|
|
uint32_t width = widthm1 + 1;
|
|
// UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; T1
|
|
ubfx(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
lsb,
|
|
width);
|
|
if (((instr & 0xfff08020) != 0xf3c00000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00008000: {
|
|
// 0xf0008000
|
|
switch (instr & 0x00005000) {
|
|
case 0x00000000: {
|
|
// 0xf0008000
|
|
switch (instr & 0x03800000) {
|
|
case 0x03800000: {
|
|
// 0xf3808000
|
|
switch (instr & 0x04600000) {
|
|
case 0x00000000: {
|
|
// 0xf3808000
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000000: {
|
|
// 0xf3808000
|
|
unsigned spec_reg = ((instr >> 8) & 0xf) |
|
|
((instr >> 16) & 0x10);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// MSR{<c>}{<q>} <spec_reg>, <Rn> ; T1
|
|
msr(CurrentCond(),
|
|
MaskedSpecialRegister(spec_reg),
|
|
Register(rn));
|
|
if (((instr & 0xffe0f0ff) != 0xf3808000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xf3808020
|
|
UnimplementedT32_32("MSR", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf3a08000
|
|
switch (instr & 0x00100000) {
|
|
case 0x00000000: {
|
|
// 0xf3a08000
|
|
switch (instr & 0x00000700) {
|
|
case 0x00000000: {
|
|
// 0xf3a08000
|
|
switch (instr & 0x000000f0) {
|
|
case 0x00000000: {
|
|
// 0xf3a08000
|
|
switch (instr & 0x0000000f) {
|
|
case 0x00000000: {
|
|
// 0xf3a08000
|
|
// NOP{<c>}.W ; T2
|
|
nop(CurrentCond(), Wide);
|
|
if (((instr & 0xffffffff) !=
|
|
0xf3af8000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000001: {
|
|
// 0xf3a08001
|
|
// YIELD{<c>}.W ; T2
|
|
yield(CurrentCond(), Wide);
|
|
if (((instr & 0xffffffff) !=
|
|
0xf3af8001)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf3a08002
|
|
UnimplementedT32_32("WFE", instr);
|
|
break;
|
|
}
|
|
case 0x00000003: {
|
|
// 0xf3a08003
|
|
UnimplementedT32_32("WFI", instr);
|
|
break;
|
|
}
|
|
case 0x00000004: {
|
|
// 0xf3a08004
|
|
UnimplementedT32_32("SEV", instr);
|
|
break;
|
|
}
|
|
case 0x00000005: {
|
|
// 0xf3a08005
|
|
UnimplementedT32_32("SEVL",
|
|
instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000f0: {
|
|
// 0xf3a080f0
|
|
UnimplementedT32_32("DBG", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf3a08100
|
|
if ((instr & 0x000000e0) == 0x00000000) {
|
|
UnimplementedT32_32("CPS", instr);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf3a08400
|
|
if ((instr & 0x0000001f) == 0x00000000) {
|
|
UnimplementedT32_32("CPSIE", instr);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf3a08500
|
|
UnimplementedT32_32("CPSIE", instr);
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf3a08600
|
|
if ((instr & 0x0000001f) == 0x00000000) {
|
|
UnimplementedT32_32("CPSID", instr);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xf3a08700
|
|
UnimplementedT32_32("CPSID", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xf3b08000
|
|
switch (instr & 0x000000f0) {
|
|
case 0x00000020: {
|
|
// 0xf3b08020
|
|
// CLREX{<c>}{<q>} ; T1
|
|
clrex(CurrentCond());
|
|
if (((instr & 0xffffffff) !=
|
|
0xf3bf8f2f)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf3b08040
|
|
MemoryBarrier option(instr & 0xf);
|
|
// DSB{<c>}{<q>} {<option>} ; T1
|
|
dsb(CurrentCond(), option);
|
|
if (((instr & 0xfffffff0) !=
|
|
0xf3bf8f40)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000050: {
|
|
// 0xf3b08050
|
|
MemoryBarrier option(instr & 0xf);
|
|
// DMB{<c>}{<q>} {<option>} ; T1
|
|
dmb(CurrentCond(), option);
|
|
if (((instr & 0xfffffff0) !=
|
|
0xf3bf8f50)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000060: {
|
|
// 0xf3b08060
|
|
MemoryBarrier option(instr & 0xf);
|
|
// ISB{<c>}{<q>} {<option>} ; T1
|
|
isb(CurrentCond(), option);
|
|
if (((instr & 0xfffffff0) !=
|
|
0xf3bf8f60)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xf3c08000
|
|
switch (instr & 0x00100000) {
|
|
case 0x00000000: {
|
|
// 0xf3c08000
|
|
unsigned rm = (instr >> 16) & 0xf;
|
|
// BXJ{<c>}{<q>} <Rm> ; T1
|
|
bxj(CurrentCond(), Register(rm));
|
|
if (((instr & 0xfff0ffff) != 0xf3c08f00)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xf3d08000
|
|
switch (instr & 0x000000ff) {
|
|
case 0x00000000: {
|
|
// 0xf3d08000
|
|
if ((instr & 0x000f0000) == 0x000e0000) {
|
|
UnimplementedT32_32("ERET", instr);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xff) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
uint32_t imm = instr & 0xff;
|
|
// SUBS{<c>}{<q>} PC, LR, #<imm8> ; T5
|
|
subs(CurrentCond(), Best, pc, lr, imm);
|
|
if (((instr & 0xffffff00) !=
|
|
0xf3de8f00)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00600000: {
|
|
// 0xf3e08000
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000000: {
|
|
// 0xf3e08000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned spec_reg = (instr >> 20) & 0x1;
|
|
// MRS{<c>}{<q>} <Rd>, <spec_reg> ; T1
|
|
mrs(CurrentCond(),
|
|
Register(rd),
|
|
SpecialRegister(spec_reg));
|
|
if (((instr & 0xffeff0ff) != 0xf3ef8000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xf3e08020
|
|
UnimplementedT32_32("MRS", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x04000000: {
|
|
// 0xf7808000
|
|
switch (instr & 0x001f2fff) {
|
|
case 0x000f0001: {
|
|
// 0xf78f8001
|
|
UnimplementedT32_32("DCPS1", instr);
|
|
break;
|
|
}
|
|
case 0x000f0002: {
|
|
// 0xf78f8002
|
|
UnimplementedT32_32("DCPS2", instr);
|
|
break;
|
|
}
|
|
case 0x000f0003: {
|
|
// 0xf78f8003
|
|
UnimplementedT32_32("DCPS3", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x04600000: {
|
|
// 0xf7e08000
|
|
switch (instr & 0x00102000) {
|
|
case 0x00000000: {
|
|
// 0xf7e08000
|
|
uint32_t imm =
|
|
(instr & 0xfff) | ((instr >> 4) & 0xf000);
|
|
// HVC{<q>} {#}<imm16> ; T1
|
|
hvc(Condition::None(), imm);
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xf7f08000
|
|
UnimplementedT32_32("SMC", instr);
|
|
break;
|
|
}
|
|
case 0x00102000: {
|
|
// 0xf7f0a000
|
|
uint32_t imm =
|
|
(instr & 0xfff) | ((instr >> 4) & 0xf000);
|
|
if ((imm <= 255)) {
|
|
// UDF{<c>}.W {#}<imm> ; T2
|
|
udf(CurrentCond(), Wide, imm);
|
|
} else {
|
|
// UDF{<c>}{<q>} {#}<imm> ; T2
|
|
udf(CurrentCond(), Best, imm);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x3800000) == 0x3800000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 22) & 0xf);
|
|
int32_t imm =
|
|
SignExtend<int32_t>(((instr & 0x7ff) |
|
|
((instr >> 5) & 0x1f800) |
|
|
((instr << 4) & 0x20000) |
|
|
((instr << 7) & 0x40000) |
|
|
((instr >> 7) & 0x80000))
|
|
<< 1,
|
|
21);
|
|
Location location(imm, kT32PcDelta);
|
|
if ((imm >= -1048576) && (imm <= 1048574) &&
|
|
((imm & 1) == 0) &&
|
|
((imm >= -256) && (imm <= 254) &&
|
|
((imm & 1) == 0))) {
|
|
// B<c>.W <label> ; T3
|
|
b(condition, Wide, &location);
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((imm >= -1048576) && (imm <= 1048574) &&
|
|
((imm & 1) == 0)) {
|
|
// B<c>{<q>} <label> ; T3
|
|
b(condition, Best, &location);
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00001000: {
|
|
// 0xf0009000
|
|
uint32_t encoded_imm =
|
|
(instr & 0x7ff) | ((instr >> 5) & 0x1ff800) |
|
|
((instr << 10) & 0x200000) |
|
|
((instr << 9) & 0x400000) | ((instr >> 3) & 0x800000);
|
|
uint32_t S = encoded_imm & (1 << 23);
|
|
encoded_imm ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
|
|
int32_t imm = SignExtend<int32_t>(encoded_imm << 1, 25);
|
|
Location location(imm, kT32PcDelta);
|
|
if ((imm >= -16777216) && (imm <= 16777214) &&
|
|
((imm & 1) == 0) &&
|
|
((imm >= -2048) && (imm <= 2046) &&
|
|
((imm & 1) == 0))) {
|
|
// B{<c>}.W <label> ; T4
|
|
b(CurrentCond(), Wide, &location);
|
|
} else if ((imm >= -16777216) && (imm <= 16777214) &&
|
|
((imm & 1) == 0)) {
|
|
// B{<c>}{<q>} <label> ; T4
|
|
b(CurrentCond(), Best, &location);
|
|
if (!OutsideITBlockOrLast()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00004000: {
|
|
// 0xf000c000
|
|
if ((instr & 0x00000001) == 0x00000000) {
|
|
uint32_t encoded_imm = ((instr >> 1) & 0x3ff) |
|
|
((instr >> 6) & 0xffc00) |
|
|
((instr << 9) & 0x100000) |
|
|
((instr << 8) & 0x200000) |
|
|
((instr >> 4) & 0x400000);
|
|
uint32_t S = encoded_imm & (1 << 22);
|
|
encoded_imm ^= ((S >> 1) | (S >> 2)) ^ (3 << 20);
|
|
int32_t imm = SignExtend<int32_t>(encoded_imm << 2, 25);
|
|
Location location(imm, kT32PcDelta);
|
|
// BLX{<c>}{<q>} <label> ; T2
|
|
blx(CurrentCond(), &location);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00005000: {
|
|
// 0xf000d000
|
|
uint32_t encoded_imm =
|
|
(instr & 0x7ff) | ((instr >> 5) & 0x1ff800) |
|
|
((instr << 10) & 0x200000) |
|
|
((instr << 9) & 0x400000) | ((instr >> 3) & 0x800000);
|
|
uint32_t S = encoded_imm & (1 << 23);
|
|
encoded_imm ^= ((S >> 1) | (S >> 2)) ^ (3 << 21);
|
|
int32_t imm = SignExtend<int32_t>(encoded_imm << 1, 25);
|
|
Location location(imm, kT32PcDelta);
|
|
// BL{<c>}{<q>} <label> ; T1
|
|
bl(CurrentCond(), &location);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x08000000: {
|
|
// 0xe8000000
|
|
switch (instr & 0x06000000) {
|
|
case 0x00000000: {
|
|
// 0xe8000000
|
|
switch (instr & 0x10100000) {
|
|
case 0x00000000: {
|
|
// 0xe8000000
|
|
switch (instr & 0x01400000) {
|
|
case 0x00000000: {
|
|
// 0xe8000000
|
|
switch (instr & 0x00800000) {
|
|
case 0x00000000: {
|
|
// 0xe8000000
|
|
UnimplementedT32_32("SRSDB", instr);
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xe8800000
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
RegisterList registers(
|
|
(((instr >> 14) & 0x1) << kLRRegNum) |
|
|
(instr & 0x1fff));
|
|
if ((rn < kNumberOfT32LowRegisters) &&
|
|
write_back.DoesWriteBack() &&
|
|
((registers.GetList() & ~0xff) == 0)) {
|
|
// STM{<c>}.W <Rn>{!}, <registers> ; T2
|
|
stm(CurrentCond(),
|
|
Wide,
|
|
Register(rn),
|
|
write_back,
|
|
registers);
|
|
if (((instr & 0xffd0a000) != 0xe8800000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// STM{<c>}{<q>} <Rn>{!}, <registers> ; T2
|
|
stm(CurrentCond(),
|
|
Best,
|
|
Register(rn),
|
|
write_back,
|
|
registers);
|
|
if (((instr & 0xffd0a000) != 0xe8800000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xe8400000
|
|
switch (instr & 0x00200000) {
|
|
case 0x00000000: {
|
|
// 0xe8400000
|
|
switch (instr & 0x00800000) {
|
|
case 0x00000000: {
|
|
// 0xe8400000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm>}] ; T1 NOLINT(whitespace/line_length)
|
|
strex(CurrentCond(),
|
|
Register(rd),
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
plus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xe8c00000
|
|
switch (instr & 0x000000f0) {
|
|
case 0x00000040: {
|
|
// 0xe8c00040
|
|
unsigned rd = instr & 0xf;
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
|
|
strexb(CurrentCond(),
|
|
Register(rd),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00ff0) != 0xe8c00f40)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000050: {
|
|
// 0xe8c00050
|
|
unsigned rd = instr & 0xf;
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
|
|
strexh(CurrentCond(),
|
|
Register(rd),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00ff0) != 0xe8c00f50)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000070: {
|
|
// 0xe8c00070
|
|
unsigned rd = instr & 0xf;
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1 NOLINT(whitespace/line_length)
|
|
strexd(CurrentCond(),
|
|
Register(rd),
|
|
Register(rt),
|
|
Register(rt2),
|
|
MemOperand(Register(rn), Offset));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xe8c00080
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STLB{<c>}{<q>} <Rt>, [<Rn>] ; T1
|
|
stlb(CurrentCond(),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00fff) != 0xe8c00f8f)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000090: {
|
|
// 0xe8c00090
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STLH{<c>}{<q>} <Rt>, [<Rn>] ; T1
|
|
stlh(CurrentCond(),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00fff) != 0xe8c00f9f)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000a0: {
|
|
// 0xe8c000a0
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STL{<c>}{<q>} <Rt>, [<Rn>] ; T1
|
|
stl(CurrentCond(),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00fff) != 0xe8c00faf)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000c0: {
|
|
// 0xe8c000c0
|
|
unsigned rd = instr & 0xf;
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
|
|
stlexb(CurrentCond(),
|
|
Register(rd),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00ff0) != 0xe8c00fc0)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000d0: {
|
|
// 0xe8c000d0
|
|
unsigned rd = instr & 0xf;
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
|
|
stlexh(CurrentCond(),
|
|
Register(rd),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00ff0) != 0xe8c00fd0)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000e0: {
|
|
// 0xe8c000e0
|
|
unsigned rd = instr & 0xf;
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; T1
|
|
stlex(CurrentCond(),
|
|
Register(rd),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00ff0) != 0xe8c00fe0)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000f0: {
|
|
// 0xe8c000f0
|
|
unsigned rd = instr & 0xf;
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; T1 NOLINT(whitespace/line_length)
|
|
stlexd(CurrentCond(),
|
|
Register(rd),
|
|
Register(rt),
|
|
Register(rt2),
|
|
MemOperand(Register(rn), Offset));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xe8600000
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1 NOLINT(whitespace/line_length)
|
|
strd(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xe9000000
|
|
switch (instr & 0x00800000) {
|
|
case 0x00000000: {
|
|
// 0xe9000000
|
|
if (((Uint32((instr >> 21)) & Uint32(0x1)) ==
|
|
Uint32(0x1)) &&
|
|
((Uint32((instr >> 16)) & Uint32(0xf)) ==
|
|
Uint32(0xd)) &&
|
|
(BitCount(((Uint32((instr >> 14)) & Uint32(0x1))
|
|
<< 13) |
|
|
(Uint32(instr) & Uint32(0x1fff))) >
|
|
Int64(1))) {
|
|
RegisterList registers(
|
|
(((instr >> 14) & 0x1) << kLRRegNum) |
|
|
(instr & 0x1fff));
|
|
if (registers.IsR0toR7orLR()) {
|
|
// PUSH{<c>}.W <registers> ; T1
|
|
push(CurrentCond(), Wide, registers);
|
|
if (((instr & 0xffffa000) != 0xe92d0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// PUSH{<c>}{<q>} <registers> ; T1
|
|
push(CurrentCond(), Best, registers);
|
|
if (((instr & 0xffffa000) != 0xe92d0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
RegisterList registers(
|
|
(((instr >> 14) & 0x1) << kLRRegNum) |
|
|
(instr & 0x1fff));
|
|
// STMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
|
|
stmdb(CurrentCond(),
|
|
Best,
|
|
Register(rn),
|
|
write_back,
|
|
registers);
|
|
if (((instr & 0xffd0a000) != 0xe9000000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xe9800000
|
|
UnimplementedT32_32("SRS{IA}", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01400000: {
|
|
// 0xe9400000
|
|
switch (instr & 0x00200000) {
|
|
case 0x00000000: {
|
|
// 0xe9400000
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1 NOLINT(whitespace/line_length)
|
|
strd(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
MemOperand(Register(rn), sign, offset, Offset));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xe9600000
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1 NOLINT(whitespace/line_length)
|
|
strd(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PreIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xe8100000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0xe8100000
|
|
switch (instr & 0x01800000) {
|
|
case 0x00000000: {
|
|
// 0xe8100000
|
|
UnimplementedT32_32("RFEDB", instr);
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xe8900000
|
|
if (((Uint32((instr >> 21)) & Uint32(0x1)) ==
|
|
Uint32(0x1)) &&
|
|
((Uint32((instr >> 16)) & Uint32(0xf)) ==
|
|
Uint32(0xd)) &&
|
|
(BitCount(((Uint32((instr >> 15)) & Uint32(0x1))
|
|
<< 14) |
|
|
((Uint32((instr >> 14)) & Uint32(0x1))
|
|
<< 13) |
|
|
(Uint32(instr) & Uint32(0x1fff))) >
|
|
Int64(1))) {
|
|
RegisterList registers(
|
|
(((instr >> 15) & 0x1) << kPCRegNum) |
|
|
(((instr >> 14) & 0x1) << kLRRegNum) |
|
|
(instr & 0x1fff));
|
|
if (registers.IsR0toR7orPC()) {
|
|
// POP{<c>}.W <registers> ; T2
|
|
pop(CurrentCond(), Wide, registers);
|
|
if (((instr & 0xffff2000) != 0xe8bd0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// POP{<c>}{<q>} <registers> ; T2
|
|
pop(CurrentCond(), Best, registers);
|
|
if (((instr & 0xffff2000) != 0xe8bd0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
RegisterList registers(
|
|
(((instr >> 15) & 0x1) << kPCRegNum) |
|
|
(((instr >> 14) & 0x1) << kLRRegNum) |
|
|
(instr & 0x1fff));
|
|
if ((rn < kNumberOfT32LowRegisters) &&
|
|
(((registers.GetList() & (1 << rn)) == 0) ==
|
|
write_back.DoesWriteBack()) &&
|
|
((registers.GetList() & ~0xff) == 0)) {
|
|
// LDM{<c>}.W <Rn>{!}, <registers> ; T2
|
|
ldm(CurrentCond(),
|
|
Wide,
|
|
Register(rn),
|
|
write_back,
|
|
registers);
|
|
if (((instr & 0xffd02000) != 0xe8900000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// LDM{<c>}{<q>} <Rn>{!}, <registers> ; T2
|
|
ldm(CurrentCond(),
|
|
Best,
|
|
Register(rn),
|
|
write_back,
|
|
registers);
|
|
if (((instr & 0xffd02000) != 0xe8900000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xe9100000
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
RegisterList registers(
|
|
(((instr >> 15) & 0x1) << kPCRegNum) |
|
|
(((instr >> 14) & 0x1) << kLRRegNum) |
|
|
(instr & 0x1fff));
|
|
// LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; T1
|
|
ldmdb(CurrentCond(),
|
|
Register(rn),
|
|
write_back,
|
|
registers);
|
|
if (((instr & 0xffd02000) != 0xe9100000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01800000: {
|
|
// 0xe9900000
|
|
UnimplementedT32_32("RFE{IA}", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xe8500000
|
|
switch (instr & 0x01200000) {
|
|
case 0x00000000: {
|
|
// 0xe8500000
|
|
switch (instr & 0x00800000) {
|
|
case 0x00000000: {
|
|
// 0xe8500000
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm>}] ; T1
|
|
ldrex(CurrentCond(),
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
plus,
|
|
offset,
|
|
Offset));
|
|
if (((instr & 0xfff00f00) != 0xe8500f00)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xe8d00000
|
|
switch (instr & 0x000000f0) {
|
|
case 0x00000000: {
|
|
// 0xe8d00000
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// TBB{<c>}{<q>} [<Rn>, <Rm>] ; T1
|
|
tbb(CurrentCond(),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff0fff0) != 0xe8d0f000) ||
|
|
!OutsideITBlockOrLast()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000010: {
|
|
// 0xe8d00010
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// TBH{<c>}{<q>} [<Rn>, <Rm>, LSL #1] ; T1
|
|
tbh(CurrentCond(),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff0fff0) != 0xe8d0f010) ||
|
|
!OutsideITBlockOrLast()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xe8d00040
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
|
|
ldrexb(CurrentCond(),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00fff) != 0xe8d00f4f)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000050: {
|
|
// 0xe8d00050
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
|
|
ldrexh(CurrentCond(),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00fff) != 0xe8d00f5f)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000070: {
|
|
// 0xe8d00070
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
|
|
ldrexd(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff000ff) != 0xe8d0007f)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xe8d00080
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDAB{<c>}{<q>} <Rt>, [<Rn>] ; T1
|
|
ldab(CurrentCond(),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00fff) != 0xe8d00f8f)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000090: {
|
|
// 0xe8d00090
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDAH{<c>}{<q>} <Rt>, [<Rn>] ; T1
|
|
ldah(CurrentCond(),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00fff) != 0xe8d00f9f)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000a0: {
|
|
// 0xe8d000a0
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDA{<c>}{<q>} <Rt>, [<Rn>] ; T1
|
|
lda(CurrentCond(),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00fff) != 0xe8d00faf)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000c0: {
|
|
// 0xe8d000c0
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; T1
|
|
ldaexb(CurrentCond(),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00fff) != 0xe8d00fcf)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000d0: {
|
|
// 0xe8d000d0
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; T1
|
|
ldaexh(CurrentCond(),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00fff) != 0xe8d00fdf)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000e0: {
|
|
// 0xe8d000e0
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; T1
|
|
ldaex(CurrentCond(),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff00fff) != 0xe8d00fef)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000f0: {
|
|
// 0xe8d000f0
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; T1
|
|
ldaexd(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xfff000ff) != 0xe8d000ff)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xe8700000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xe87f0000
|
|
if (((instr & 0x1200000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 8) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xff;
|
|
imm <<= 2;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kT32PcDelta);
|
|
// LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
|
|
if (minus_zero) {
|
|
ldrd(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrd(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
&location);
|
|
}
|
|
if (((instr & 0xff7f0000) != 0xe95f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm> ; T1 NOLINT(whitespace/line_length)
|
|
ldrd(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xe9500000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xe95f0000
|
|
if (((instr & 0x1200000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 8) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xff;
|
|
imm <<= 2;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kT32PcDelta);
|
|
// LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
|
|
if (minus_zero) {
|
|
ldrd(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrd(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
&location);
|
|
}
|
|
if (((instr & 0xff7f0000) != 0xe95f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}] ; T1 NOLINT(whitespace/line_length)
|
|
ldrd(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0xe9700000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xe97f0000
|
|
if (((instr & 0x1200000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 8) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xff;
|
|
imm <<= 2;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kT32PcDelta);
|
|
// LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; T1
|
|
if (minus_zero) {
|
|
ldrd(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrd(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
&location);
|
|
}
|
|
if (((instr & 0xff7f0000) != 0xe95f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm>}]! ; T1 NOLINT(whitespace/line_length)
|
|
ldrd(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PreIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xf8000000
|
|
switch (instr & 0x01a00000) {
|
|
case 0x00000000: {
|
|
// 0xf8000000
|
|
switch (instr & 0x00400d00) {
|
|
case 0x00000000: {
|
|
// 0xf8000000
|
|
if ((instr & 0x000002c0) == 0x00000000) {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift = LSL;
|
|
uint32_t amount = (instr >> 4) & 0x3;
|
|
AddrMode addrmode = Offset;
|
|
if ((rt < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters) &&
|
|
shift.IsLSL() && (amount == 0) &&
|
|
sign.IsPlus()) {
|
|
// STRB{<c>}.W <Rt>, [<Rn>, #{+}<Rm>] ; T2
|
|
strb(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
} else {
|
|
// STRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 NOLINT(whitespace/line_length)
|
|
strb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf8000900
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xff;
|
|
// STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
|
|
strb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xf8000c00
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0xf8000c00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xff;
|
|
// STRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
|
|
strb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
minus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf8000e00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
UnimplementedT32_32("STRBT", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xf8000d00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xff;
|
|
// STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
|
|
strb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PreIndex));
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xf8400000
|
|
if ((instr & 0x000002c0) == 0x00000000) {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift = LSL;
|
|
uint32_t amount = (instr >> 4) & 0x3;
|
|
AddrMode addrmode = Offset;
|
|
if ((rt < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters) &&
|
|
shift.IsLSL() && (amount == 0) &&
|
|
sign.IsPlus()) {
|
|
// STR{<c>}.W <Rt>, [<Rn>, #{+}<Rm>] ; T2
|
|
str(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
} else {
|
|
// STR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 NOLINT(whitespace/line_length)
|
|
str(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400900: {
|
|
// 0xf8400900
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xff;
|
|
// STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4
|
|
str(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00400c00: {
|
|
// 0xf8400c00
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0xf8400c00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xff;
|
|
// STR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4
|
|
str(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
minus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf8400e00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
UnimplementedT32_32("STRT", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400d00: {
|
|
// 0xf8400d00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 16)) & Uint32(0xf)) ==
|
|
Uint32(0xd)) &&
|
|
((Uint32((instr >> 9)) & Uint32(0x1)) ==
|
|
Uint32(0x0)) &&
|
|
((Uint32(instr) & Uint32(0xff)) == Uint32(0x4))) {
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
if ((rt <= 7) || (rt == kLRRegNum)) {
|
|
// PUSH{<c>}.W <single_register_list> ; T4
|
|
push(CurrentCond(), Wide, Register(rt));
|
|
} else {
|
|
// PUSH{<c>}{<q>} <single_register_list> ; T4
|
|
push(CurrentCond(), Best, Register(rt));
|
|
}
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xff;
|
|
// STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4
|
|
str(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, PreIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf8200000
|
|
switch (instr & 0x00400d00) {
|
|
case 0x00000000: {
|
|
// 0xf8200000
|
|
if ((instr & 0x000002c0) == 0x00000000) {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift = LSL;
|
|
uint32_t amount = (instr >> 4) & 0x3;
|
|
AddrMode addrmode = Offset;
|
|
if ((rt < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters) &&
|
|
shift.IsLSL() && (amount == 0) &&
|
|
sign.IsPlus()) {
|
|
// STRH{<c>}.W <Rt>, [<Rn>, #{+}<Rm>] ; T2
|
|
strh(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
} else {
|
|
// STRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 NOLINT(whitespace/line_length)
|
|
strh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf8200900
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xff;
|
|
// STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3
|
|
strh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xf8200c00
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0xf8200c00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xff;
|
|
// STRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3
|
|
strh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
minus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf8200e00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
UnimplementedT32_32("STRHT", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xf8200d00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xff;
|
|
// STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3
|
|
strh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PreIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xf8800000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0xf8800000
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xfff;
|
|
if ((rt < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
((offset >= 0) && (offset <= 31))) {
|
|
// STRB{<c>}.W <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
|
|
strb(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
plus,
|
|
offset,
|
|
Offset));
|
|
} else {
|
|
// STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
|
|
strb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
plus,
|
|
offset,
|
|
Offset));
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xf8c00000
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xfff;
|
|
if (((rt < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
((offset >= 0) && (offset <= 124) &&
|
|
((offset & 3) == 0))) ||
|
|
((rt < kNumberOfT32LowRegisters) &&
|
|
(rn == sp.GetCode()) &&
|
|
((offset >= 0) && (offset <= 1020) &&
|
|
((offset & 3) == 0)))) {
|
|
// STR{<c>}.W <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
|
|
str(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
MemOperand(Register(rn), plus, offset, Offset));
|
|
} else {
|
|
// STR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3
|
|
str(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), plus, offset, Offset));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00a00000: {
|
|
// 0xf8a00000
|
|
if ((instr & 0x00400000) == 0x00000000) {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xfff;
|
|
if ((rt < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
((offset >= 0) && (offset <= 62) &&
|
|
((offset & 1) == 0))) {
|
|
// STRH{<c>}.W <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
|
|
strh(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
MemOperand(Register(rn), plus, offset, Offset));
|
|
} else {
|
|
// STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2
|
|
strh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), plus, offset, Offset));
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf9000000
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf900000d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf900000d
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000000: {
|
|
// 0xf900000d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vst4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf900010d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vst4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf900020d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vst1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf900030d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vst2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf900040d
|
|
if (((instr & 0x20) == 0x20)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vst3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf900050d
|
|
if (((instr & 0x20) == 0x20)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vst3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf900060d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vst1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xf900070d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vst1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf900080d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vst2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf900090d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vst2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf9000a0d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vst1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf900000f
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000000: {
|
|
// 0xf900000d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vst4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf900010d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vst4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf900020d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vst1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf900030d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vst2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf900040d
|
|
if (((instr & 0x20) == 0x20)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vst3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf900050d
|
|
if (((instr & 0x20) == 0x20)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vst3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf900060d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vst1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xf900070d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vst1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf900080d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vst2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf900090d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vst2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf9000a0d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vst1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000000: {
|
|
// 0xf9000000
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vst4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf9000100
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vst4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf9000200
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vst1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf9000300
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vst2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf9000400
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0x20) == 0x20)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vst3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf9000500
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0x20) == 0x20)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vst3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf9000600
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vst1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xf9000700
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vst1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf9000800
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vst2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf9000900
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vst2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf9000a00
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vst1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0xf9200000
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf920000d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf920000d
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000000: {
|
|
// 0xf920000d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf920010d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf920020d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf920030d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf920040d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf920050d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf920060d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xf920070d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf920080d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf920090d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf9200a0d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf920000f
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000000: {
|
|
// 0xf920000d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf920010d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf920020d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf920030d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf920040d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf920050d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf920060d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xf920070d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf920080d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf920090d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf9200a0d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000000: {
|
|
// 0xf9200000
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf9200100
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf9200200
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf9200300
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf9200400
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf9200500
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf9200600
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xf9200700
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf9200800
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf9200900
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf9200a00
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01800000: {
|
|
// 0xf9800000
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf9800000
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000c00: {
|
|
// 0xf9800c00
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf980000d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf980000d
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_1_Decode((instr >>
|
|
4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 1;
|
|
unsigned last = first + length - 1;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vst1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf980000f
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_1_Decode((instr >>
|
|
4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 1;
|
|
unsigned last = first + length - 1;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vst1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_1_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 1;
|
|
unsigned last = first + length - 1;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vst1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf9800100
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000c00: {
|
|
// 0xf9800d00
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf980010d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf980010d
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_2_Decode((instr >>
|
|
4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 2;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vst2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf980010f
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_2_Decode((instr >>
|
|
4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 2;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vst2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_2_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 2;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vst2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf9800200
|
|
switch (instr & 0x00000c30) {
|
|
case 0x00000010: {
|
|
// 0xf9800210
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
case 0x00000030: {
|
|
// 0xf9800230
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
case 0x00000410: {
|
|
// 0xf9800610
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
case 0x00000430: {
|
|
// 0xf9800630
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
case 0x00000810: {
|
|
// 0xf9800a10
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
case 0x00000820: {
|
|
// 0xf9800a20
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
case 0x00000830: {
|
|
// 0xf9800a30
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xf9800e00
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
case 0x00000c10: {
|
|
// 0xf9800e10
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
case 0x00000c20: {
|
|
// 0xf9800e20
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
case 0x00000c30: {
|
|
// 0xf9800e30
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf980020d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf980020d
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0x810) == 0x10) ||
|
|
((instr & 0xc30) == 0x810) ||
|
|
((instr & 0xc30) == 0x820) ||
|
|
((instr & 0xc30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeon decode_neon =
|
|
Index_1_Decode((instr >> 4) & 0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 3;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1 NOLINT(whitespace/line_length)
|
|
vst3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
MemOperand(Register(rn), PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf980020f
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0x810) == 0x10) ||
|
|
((instr & 0xc30) == 0x810) ||
|
|
((instr & 0xc30) == 0x820) ||
|
|
((instr & 0xc30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeon decode_neon =
|
|
Index_1_Decode((instr >> 4) & 0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 3;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
|
|
vst3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
MemOperand(Register(rn), Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd) ||
|
|
((instr & 0x810) == 0x10) ||
|
|
((instr & 0xc30) == 0x810) ||
|
|
((instr & 0xc30) == 0x820) ||
|
|
((instr & 0xc30) == 0x830)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeon decode_neon =
|
|
Index_1_Decode((instr >> 4) & 0xf, dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 3;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vst3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf9800300
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000c00: {
|
|
// 0xf9800f00
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf980030d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf980030d
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_3_Decode((instr >>
|
|
4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 4;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vst4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf980030f
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_3_Decode((instr >>
|
|
4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 4;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vst4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_3_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 4;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vst4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01a00000: {
|
|
// 0xf9a00000
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf9a00000
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000c00: {
|
|
// 0xf9a00c00
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf9a00c0d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf9a00c0d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_1_Decode((instr >> 4) & 0x1,
|
|
dt);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 1;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf9a00c0f
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_1_Decode((instr >> 4) & 0x1,
|
|
dt);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 1;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_1_Decode((instr >> 4) & 0x1, dt);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 1;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf9a0000d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf9a0000d
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_1_Decode((instr >>
|
|
4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 1;
|
|
unsigned last = first + length - 1;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf9a0000f
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_1_Decode((instr >>
|
|
4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 1;
|
|
unsigned last = first + length - 1;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_1_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 1;
|
|
unsigned last = first + length - 1;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld1(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf9a00100
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000c00: {
|
|
// 0xf9a00d00
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf9a00d0d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf9a00d0d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_2_Decode((instr >> 4) & 0x1,
|
|
dt);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf9a00d0f
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_2_Decode((instr >> 4) & 0x1,
|
|
dt);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_2_Decode((instr >> 4) & 0x1, dt);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf9a0010d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf9a0010d
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_2_Decode((instr >>
|
|
4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 2;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf9a0010f
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_2_Decode((instr >>
|
|
4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 2;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_2_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 2;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld2(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf9a00200
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000c00: {
|
|
// 0xf9a00e00
|
|
switch (instr & 0x00000010) {
|
|
case 0x00000000: {
|
|
// 0xf9a00e00
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf9a00e0d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf9a00e0d
|
|
DataType dt = Dt_size_7_Decode(
|
|
(instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1 NOLINT(whitespace/line_length)
|
|
vld3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(
|
|
first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
MemOperand(Register(rn),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf9a00e0f
|
|
DataType dt = Dt_size_7_Decode(
|
|
(instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1 NOLINT(whitespace/line_length)
|
|
vld3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(
|
|
first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
MemOperand(Register(rn),
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf9a0020d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf9a0020d
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeon decode_neon =
|
|
Index_1_Decode((instr >> 4) & 0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 3;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; T1 NOLINT(whitespace/line_length)
|
|
vld3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
MemOperand(Register(rn), PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf9a0020f
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeon decode_neon =
|
|
Index_1_Decode((instr >> 4) & 0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 3;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; T1
|
|
vld3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
MemOperand(Register(rn), Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeon decode_neon =
|
|
Index_1_Decode((instr >> 4) & 0xf, dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 3;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld3(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf9a00300
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000c00: {
|
|
// 0xf9a00f00
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf9a00f0d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf9a00f0d
|
|
DataType dt =
|
|
Dt_size_8_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_3_Decode((instr >> 4) & 0x1,
|
|
dt,
|
|
(instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf9a00f0f
|
|
DataType dt =
|
|
Dt_size_8_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_3_Decode((instr >> 4) & 0x1,
|
|
dt,
|
|
(instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_8_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_3_Decode((instr >> 4) & 0x1,
|
|
dt,
|
|
(instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf9a0030d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf9a0030d
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_3_Decode((instr >>
|
|
4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 4;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; T1 NOLINT(whitespace/line_length)
|
|
vld4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf9a0030f
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_3_Decode((instr >>
|
|
4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 4;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; T1 NOLINT(whitespace/line_length)
|
|
vld4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_3_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing =
|
|
decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 4;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; T1 NOLINT(whitespace/line_length)
|
|
vld4(CurrentCond(),
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x10100000: {
|
|
// 0xf8100000
|
|
switch (instr & 0x01400000) {
|
|
case 0x00000000: {
|
|
// 0xf8100000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xf81f0000
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xf81ff000
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xfff;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kT32PcDelta);
|
|
// PLD{<c>}{<q>} <label> ; T1
|
|
if (minus_zero) {
|
|
pld(CurrentCond(), MemOperand(pc, minus, 0));
|
|
} else {
|
|
pld(CurrentCond(), &location);
|
|
}
|
|
if (((instr & 0xff7ff000) != 0xf81ff000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00200000) {
|
|
case 0x00000000: {
|
|
// 0xf81f0000
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xfff;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kT32PcDelta);
|
|
// LDRB{<c>}{<q>} <Rt>, <label> ; T1
|
|
if (minus_zero) {
|
|
ldrb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrb(CurrentCond(),
|
|
Register(rt),
|
|
&location);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf83f0000
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xfff;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kT32PcDelta);
|
|
// LDRH{<c>}{<q>} <Rt>, <label> ; T1
|
|
if (minus_zero) {
|
|
ldrh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrh(CurrentCond(),
|
|
Register(rt),
|
|
&location);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00a00000) {
|
|
case 0x00000000: {
|
|
// 0xf8100000
|
|
switch (instr & 0x00000d00) {
|
|
case 0x00000000: {
|
|
// 0xf8100000
|
|
switch (instr & 0x000002c0) {
|
|
case 0x00000000: {
|
|
// 0xf8100000
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xf810f000
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift = LSL;
|
|
uint32_t amount = (instr >> 4) & 0x3;
|
|
AddrMode addrmode = Offset;
|
|
// PLD{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1 NOLINT(whitespace/line_length)
|
|
pld(CurrentCond(),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift = LSL;
|
|
uint32_t amount = (instr >> 4) & 0x3;
|
|
AddrMode addrmode = Offset;
|
|
if ((rt < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters) &&
|
|
shift.IsLSL() && (amount == 0) &&
|
|
sign.IsPlus()) {
|
|
// LDRB{<c>}.W <Rt>, [<Rn>, #{+}<Rm>] ; T2 NOLINT(whitespace/line_length)
|
|
ldrb(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
} else {
|
|
// LDRB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 NOLINT(whitespace/line_length)
|
|
ldrb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf8100900
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset = instr & 0xff;
|
|
// LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3 NOLINT(whitespace/line_length)
|
|
ldrb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xf8100c00
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0xf8100c00
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xf810fc00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xff;
|
|
// PLD{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2 NOLINT(whitespace/line_length)
|
|
pld(CurrentCond(),
|
|
MemOperand(Register(rn),
|
|
minus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xff;
|
|
// LDRB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3 NOLINT(whitespace/line_length)
|
|
ldrb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
minus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf8100e00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
UnimplementedT32_32("LDRBT", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xf8100d00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset = instr & 0xff;
|
|
// LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3 NOLINT(whitespace/line_length)
|
|
ldrb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PreIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf8300000
|
|
switch (instr & 0x00000d00) {
|
|
case 0x00000000: {
|
|
// 0xf8300000
|
|
switch (instr & 0x000002c0) {
|
|
case 0x00000000: {
|
|
// 0xf8300000
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xf830f000
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift = LSL;
|
|
uint32_t amount = (instr >> 4) & 0x3;
|
|
AddrMode addrmode = Offset;
|
|
// PLDW{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1 NOLINT(whitespace/line_length)
|
|
pldw(CurrentCond(),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift = LSL;
|
|
uint32_t amount = (instr >> 4) & 0x3;
|
|
AddrMode addrmode = Offset;
|
|
if ((rt < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters) &&
|
|
shift.IsLSL() && (amount == 0) &&
|
|
sign.IsPlus()) {
|
|
// LDRH{<c>}.W <Rt>, [<Rn>, #{+}<Rm>] ; T2 NOLINT(whitespace/line_length)
|
|
ldrh(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
} else {
|
|
// LDRH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 NOLINT(whitespace/line_length)
|
|
ldrh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf8300900
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset = instr & 0xff;
|
|
// LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T3 NOLINT(whitespace/line_length)
|
|
ldrh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xf8300c00
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0xf8300c00
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xf830fc00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xff;
|
|
// PLDW{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2 NOLINT(whitespace/line_length)
|
|
pldw(CurrentCond(),
|
|
MemOperand(Register(rn),
|
|
minus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xff;
|
|
// LDRH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T3 NOLINT(whitespace/line_length)
|
|
ldrh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
minus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf8300e00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
UnimplementedT32_32("LDRHT", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xf8300d00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset = instr & 0xff;
|
|
// LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T3 NOLINT(whitespace/line_length)
|
|
ldrh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PreIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xf8900000
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xf890f000
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xfff;
|
|
// PLD{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
|
|
pld(CurrentCond(),
|
|
MemOperand(Register(rn),
|
|
plus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xfff;
|
|
if ((rt < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
((offset >= 0) && (offset <= 31))) {
|
|
// LDRB{<c>}.W <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 NOLINT(whitespace/line_length)
|
|
ldrb(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
plus,
|
|
offset,
|
|
Offset));
|
|
} else {
|
|
// LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 NOLINT(whitespace/line_length)
|
|
ldrb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
plus,
|
|
offset,
|
|
Offset));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00a00000: {
|
|
// 0xf8b00000
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xf8b0f000
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xfff;
|
|
// PLDW{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
|
|
pldw(CurrentCond(),
|
|
MemOperand(Register(rn),
|
|
plus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xfff;
|
|
if ((rt < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
((offset >= 0) && (offset <= 62) &&
|
|
((offset & 1) == 0))) {
|
|
// LDRH{<c>}.W <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 NOLINT(whitespace/line_length)
|
|
ldrh(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
plus,
|
|
offset,
|
|
Offset));
|
|
} else {
|
|
// LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T2 NOLINT(whitespace/line_length)
|
|
ldrh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
plus,
|
|
offset,
|
|
Offset));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xf8500000
|
|
switch (instr & 0x00200000) {
|
|
case 0x00000000: {
|
|
// 0xf8500000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xf85f0000
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xfff;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kT32PcDelta);
|
|
if ((imm >= -4095) && (imm <= 4095) &&
|
|
((rt < kNumberOfT32LowRegisters) &&
|
|
(imm >= 0) && (imm <= 1020) &&
|
|
((imm & 3) == 0))) {
|
|
// LDR{<c>}.W <Rt>, <label> ; T2
|
|
if (minus_zero) {
|
|
ldr(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldr(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
&location);
|
|
}
|
|
} else if ((imm >= -4095) && (imm <= 4095)) {
|
|
// LDR{<c>}{<q>} <Rt>, <label> ; T2
|
|
if (minus_zero) {
|
|
ldr(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldr(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
&location);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00800000) {
|
|
case 0x00000000: {
|
|
// 0xf8500000
|
|
switch (instr & 0x00000d00) {
|
|
case 0x00000000: {
|
|
// 0xf8500000
|
|
if ((instr & 0x000002c0) == 0x00000000) {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift = LSL;
|
|
uint32_t amount = (instr >> 4) & 0x3;
|
|
AddrMode addrmode = Offset;
|
|
if ((rt < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters) &&
|
|
shift.IsLSL() && (amount == 0) &&
|
|
sign.IsPlus()) {
|
|
// LDR{<c>}.W <Rt>, [<Rn>, #{+}<Rm>] ; T2 NOLINT(whitespace/line_length)
|
|
ldr(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
} else {
|
|
// LDR{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 NOLINT(whitespace/line_length)
|
|
ldr(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf8500900
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 16)) &
|
|
Uint32(0xf)) == Uint32(0xd)) &&
|
|
((Uint32((instr >> 9)) &
|
|
Uint32(0x1)) == Uint32(0x1)) &&
|
|
((Uint32(instr) & Uint32(0xff)) ==
|
|
Uint32(0x4))) {
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
if ((rt <= 7) || (rt == kPCRegNum)) {
|
|
// POP{<c>}.W <single_register_list> ; T4 NOLINT(whitespace/line_length)
|
|
pop(CurrentCond(),
|
|
Wide,
|
|
Register(rt));
|
|
} else {
|
|
// POP{<c>}{<q>} <single_register_list> ; T4 NOLINT(whitespace/line_length)
|
|
pop(CurrentCond(),
|
|
Best,
|
|
Register(rt));
|
|
}
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0)
|
|
? minus
|
|
: plus);
|
|
int32_t offset = instr & 0xff;
|
|
// LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; T4 NOLINT(whitespace/line_length)
|
|
ldr(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xf8500c00
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0xf8500c00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xff;
|
|
// LDR{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_2>}] ; T4 NOLINT(whitespace/line_length)
|
|
ldr(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
minus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf8500e00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
UnimplementedT32_32("LDRT", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xf8500d00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0)
|
|
? minus
|
|
: plus);
|
|
int32_t offset = instr & 0xff;
|
|
// LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; T4 NOLINT(whitespace/line_length)
|
|
ldr(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PreIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xf8d00000
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xfff;
|
|
if (((rt < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
((offset >= 0) && (offset <= 124) &&
|
|
((offset & 3) == 0))) ||
|
|
((rt < kNumberOfT32LowRegisters) &&
|
|
(rn == sp.GetCode()) &&
|
|
((offset >= 0) && (offset <= 1020) &&
|
|
((offset & 3) == 0)))) {
|
|
// LDR{<c>}.W <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3 NOLINT(whitespace/line_length)
|
|
ldr(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
plus,
|
|
offset,
|
|
Offset));
|
|
} else {
|
|
// LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm_1>}] ; T3 NOLINT(whitespace/line_length)
|
|
ldr(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
plus,
|
|
offset,
|
|
Offset));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf9100000
|
|
switch (instr & 0x00200000) {
|
|
case 0x00000000: {
|
|
// 0xf9100000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xf91f0000
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xf91ff000
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xfff;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kT32PcDelta);
|
|
// PLI{<c>}{<q>} <label> ; T3
|
|
if (minus_zero) {
|
|
pli(CurrentCond(),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
pli(CurrentCond(), &location);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xfff;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kT32PcDelta);
|
|
// LDRSB{<c>}{<q>} <Rt>, <label> ; T1
|
|
if (minus_zero) {
|
|
ldrsb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrsb(CurrentCond(),
|
|
Register(rt),
|
|
&location);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00800000) {
|
|
case 0x00000000: {
|
|
// 0xf9100000
|
|
switch (instr & 0x00000d00) {
|
|
case 0x00000000: {
|
|
// 0xf9100000
|
|
switch (instr & 0x000002c0) {
|
|
case 0x00000000: {
|
|
// 0xf9100000
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xf910f000
|
|
if (((instr & 0xf0000) ==
|
|
0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift = LSL;
|
|
uint32_t amount =
|
|
(instr >> 4) & 0x3;
|
|
AddrMode addrmode = Offset;
|
|
// PLI{<c>}{<q>} [<Rn>, {+}<Rm>{, LSL #<amount>}] ; T1 NOLINT(whitespace/line_length)
|
|
pli(CurrentCond(),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) ==
|
|
0xf0000) ||
|
|
((instr & 0xf000) ==
|
|
0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift = LSL;
|
|
uint32_t amount =
|
|
(instr >> 4) & 0x3;
|
|
AddrMode addrmode = Offset;
|
|
if ((rt <
|
|
kNumberOfT32LowRegisters) &&
|
|
(rn <
|
|
kNumberOfT32LowRegisters) &&
|
|
(rm <
|
|
kNumberOfT32LowRegisters) &&
|
|
shift.IsLSL() &&
|
|
(amount == 0) &&
|
|
sign.IsPlus()) {
|
|
// LDRSB{<c>}.W <Rt>, [<Rn>, #{+}<Rm>] ; T2 NOLINT(whitespace/line_length)
|
|
ldrsb(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
} else {
|
|
// LDRSB{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 NOLINT(whitespace/line_length)
|
|
ldrsb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf9100900
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0)
|
|
? minus
|
|
: plus);
|
|
int32_t offset = instr & 0xff;
|
|
// LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2 NOLINT(whitespace/line_length)
|
|
ldrsb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xf9100c00
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0xf9100c00
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xf910fc00
|
|
if (((instr & 0xf0000) ==
|
|
0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xff;
|
|
// PLI{<c>}{<q>} [<Rn>{, #-<imm_1>}] ; T2 NOLINT(whitespace/line_length)
|
|
pli(CurrentCond(),
|
|
MemOperand(Register(rn),
|
|
minus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) ==
|
|
0xf0000) ||
|
|
((instr & 0xf000) ==
|
|
0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xff;
|
|
// LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2 NOLINT(whitespace/line_length)
|
|
ldrsb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
minus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf9100e00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
UnimplementedT32_32("LDRSBT", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xf9100d00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0)
|
|
? minus
|
|
: plus);
|
|
int32_t offset = instr & 0xff;
|
|
// LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2 NOLINT(whitespace/line_length)
|
|
ldrsb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PreIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xf9900000
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xf990f000
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xfff;
|
|
// PLI{<c>}{<q>} [<Rn>{, #{+}<imm>}] ; T1
|
|
pli(CurrentCond(),
|
|
MemOperand(Register(rn),
|
|
plus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xfff;
|
|
// LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 NOLINT(whitespace/line_length)
|
|
ldrsb(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
plus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf9300000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xf93f0000
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xfff;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kT32PcDelta);
|
|
// LDRSH{<c>}{<q>} <Rt>, <label> ; T1
|
|
if (minus_zero) {
|
|
ldrsh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrsh(CurrentCond(), Register(rt), &location);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00800000) {
|
|
case 0x00000000: {
|
|
// 0xf9300000
|
|
switch (instr & 0x00000d00) {
|
|
case 0x00000000: {
|
|
// 0xf9300000
|
|
if ((instr & 0x000002c0) == 0x00000000) {
|
|
if (((instr & 0xf0000) == 0xf0000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift = LSL;
|
|
uint32_t amount = (instr >> 4) & 0x3;
|
|
AddrMode addrmode = Offset;
|
|
if ((rt < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters) &&
|
|
shift.IsLSL() && (amount == 0) &&
|
|
sign.IsPlus()) {
|
|
// LDRSH{<c>}.W <Rt>, [<Rn>, #{+}<Rm>] ; T2 NOLINT(whitespace/line_length)
|
|
ldrsh(CurrentCond(),
|
|
Wide,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
} else {
|
|
// LDRSH{<c>}{<q>} <Rt>, [<Rn>, {+}<Rm>{, LSL #<imm>}] ; T2 NOLINT(whitespace/line_length)
|
|
ldrsh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf9300900
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0)
|
|
? minus
|
|
: plus);
|
|
int32_t offset = instr & 0xff;
|
|
// LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_1> ; T2 NOLINT(whitespace/line_length)
|
|
ldrsh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xf9300c00
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0xf9300c00
|
|
if (((instr & 0xf0000) == 0xf0000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xff;
|
|
// LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #-<imm_1>}] ; T2 NOLINT(whitespace/line_length)
|
|
ldrsh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
minus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf9300e00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
UnimplementedT32_32("LDRSHT", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xf9300d00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 9) & 0x1) == 0)
|
|
? minus
|
|
: plus);
|
|
int32_t offset = instr & 0xff;
|
|
// LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_1>}]! ; T2 NOLINT(whitespace/line_length)
|
|
ldrsh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PreIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xf9b00000
|
|
if (((instr & 0xf0000) == 0xf0000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
int32_t offset = instr & 0xfff;
|
|
// LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+}<imm>}] ; T1 NOLINT(whitespace/line_length)
|
|
ldrsh(CurrentCond(),
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
plus,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x02000000: {
|
|
// 0xea000000
|
|
switch (instr & 0x11900000) {
|
|
case 0x00000000: {
|
|
// 0xea000000
|
|
switch (instr & 0x00600000) {
|
|
case 0x00000000: {
|
|
// 0xea000000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea000030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T2
|
|
and_(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xea000030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (InITBlock() &&
|
|
(instr & 0x00100000) == 0x00000000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd == rn) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// AND<c>.W {<Rd>}, <Rn>, <Rm> ; T2
|
|
and_(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xea000000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
and_(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xea000000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xea200000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea200030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T2
|
|
bic(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xea200030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (InITBlock() &&
|
|
(instr & 0x00100000) == 0x00000000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd == rn) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// BIC<c>.W {<Rd>}, <Rn>, <Rm> ; T2
|
|
bic(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xea200000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
bic(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xea200000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xea400000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xea4f0000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea4f0030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// RRX{<c>}{<q>} {<Rd>}, <Rm> ; T3
|
|
rrx(CurrentCond(), Register(rd), Register(rm));
|
|
if (((instr & 0xfffff0f0) != 0xea4f0030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 4)) & Uint32(0x3)) ==
|
|
Uint32(0x2))) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c);
|
|
if (amount == 0) amount = 32;
|
|
if (InITBlock() &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters) &&
|
|
((amount >= 1) && (amount <= 32)))) {
|
|
// ASR<c>.W {<Rd>}, <Rm>, #<imm> ; T3
|
|
asr(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xffff8030) != 0xea4f0020)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
|
|
asr(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xffff8030) != 0xea4f0020)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 4)) & Uint32(0x3)) ==
|
|
Uint32(0x0)) &&
|
|
((instr & 0x000070c0) != 0x00000000)) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c);
|
|
if (InITBlock() &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters) &&
|
|
((amount >= 1) && (amount <= 31)))) {
|
|
// LSL<c>.W {<Rd>}, <Rm>, #<imm> ; T3
|
|
lsl(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xffff8030) != 0xea4f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
|
|
lsl(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xffff8030) != 0xea4f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 4)) & Uint32(0x3)) ==
|
|
Uint32(0x1))) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c);
|
|
if (amount == 0) amount = 32;
|
|
if (InITBlock() &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters) &&
|
|
((amount >= 1) && (amount <= 32)))) {
|
|
// LSR<c>.W {<Rd>}, <Rm>, #<imm> ; T3
|
|
lsr(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xffff8030) != 0xea4f0010)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
|
|
lsr(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xffff8030) != 0xea4f0010)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 4)) & Uint32(0x3)) ==
|
|
Uint32(0x3)) &&
|
|
((instr & 0x000070c0) != 0x00000000)) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c);
|
|
// ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
|
|
ror(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xffff8030) != 0xea4f0030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if ((instr & 0x00100000) == 0x00000000 &&
|
|
(shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0))) {
|
|
// MOV<c>.W <Rd>, <Rm> {, <shift> #<amount> } ; T3 NOLINT(whitespace/line_length)
|
|
mov(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xffff8000) != 0xea4f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if (InITBlock() &&
|
|
(instr & 0x00100000) == 0x00000000 &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// MOV<c>.W <Rd>, <Rm> {, <shift> #<amount> } ; T3 NOLINT(whitespace/line_length)
|
|
mov(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xffff8000) != 0xea4f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3 NOLINT(whitespace/line_length)
|
|
mov(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xffff8000) != 0xea4f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea400030
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T2
|
|
orr(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xea400030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000) ||
|
|
((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (InITBlock() &&
|
|
(instr & 0x00100000) == 0x00000000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd == rn) &&
|
|
(rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// ORR<c>.W {<Rd>}, <Rn>, <Rm> ; T2
|
|
orr(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xea400000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
orr(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xea400000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00600000: {
|
|
// 0xea600000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xea6f0000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea6f0030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// MVN{<c>}{<q>} <Rd>, <Rm>, RRX ; T2
|
|
mvn(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfffff0f0) != 0xea6f0030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (InITBlock() &&
|
|
(instr & 0x00100000) == 0x00000000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// MVN<c>.W <Rd>, <Rm> ; T2
|
|
mvn(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm));
|
|
if (((instr & 0xffff8000) != 0xea6f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
mvn(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xffff8000) != 0xea6f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea600030
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ORN{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T1
|
|
orn(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xea600030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000) ||
|
|
((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
// ORN{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
orn(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xea600000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xea100000
|
|
switch (instr & 0x00600000) {
|
|
case 0x00000000: {
|
|
// 0xea100000
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000f00: {
|
|
// 0xea100f00
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea100f30
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// TST{<c>}{<q>} <Rn>, <Rm>, RRX ; T2
|
|
tst(CurrentCond(),
|
|
Best,
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0fff0) != 0xea100f30)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rn < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// TST{<c>}.W <Rn>, <Rm> ; T2
|
|
tst(CurrentCond(),
|
|
Wide,
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08f00) != 0xea100f00)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
tst(CurrentCond(),
|
|
Best,
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08f00) != 0xea100f00)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea100030
|
|
if (((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T2
|
|
ands(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xea100030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30) ||
|
|
((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (OutsideITBlock() &&
|
|
(instr & 0x00100000) == 0x00100000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd == rn) &&
|
|
(rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// ANDS.W {<Rd>}, <Rn>, <Rm> ; T2
|
|
ands(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xea100000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00100000) {
|
|
// ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
ands(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xea100000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xea300000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea300030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T2
|
|
bics(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xea300030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (OutsideITBlock() &&
|
|
(instr & 0x00100000) == 0x00100000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd == rn) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// BICS.W {<Rd>}, <Rn>, <Rm> ; T2
|
|
bics(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xea300000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00100000) {
|
|
// BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
bics(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xea300000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xea500000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xea5f0000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea5f0030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// RRXS{<c>}{<q>} {<Rd>}, <Rm> ; T3
|
|
rrxs(CurrentCond(), Register(rd), Register(rm));
|
|
if (((instr & 0xfffff0f0) != 0xea5f0030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 4)) & Uint32(0x3)) ==
|
|
Uint32(0x2))) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c);
|
|
if (amount == 0) amount = 32;
|
|
if (OutsideITBlock() &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters) &&
|
|
((amount >= 1) && (amount <= 32)))) {
|
|
// ASRS.W {<Rd>}, <Rm>, #<imm> ; T3
|
|
asrs(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xffff8030) != 0xea5f0020)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
|
|
asrs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xffff8030) != 0xea5f0020)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 4)) & Uint32(0x3)) ==
|
|
Uint32(0x0)) &&
|
|
((instr & 0x000070c0) != 0x00000000)) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c);
|
|
if (OutsideITBlock() &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters) &&
|
|
((amount >= 1) && (amount <= 31)))) {
|
|
// LSLS.W {<Rd>}, <Rm>, #<imm> ; T3
|
|
lsls(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xffff8030) != 0xea5f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
|
|
lsls(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xffff8030) != 0xea5f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 4)) & Uint32(0x3)) ==
|
|
Uint32(0x1))) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c);
|
|
if (amount == 0) amount = 32;
|
|
if (OutsideITBlock() &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters) &&
|
|
((amount >= 1) && (amount <= 32)))) {
|
|
// LSRS.W {<Rd>}, <Rm>, #<imm> ; T3
|
|
lsrs(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xffff8030) != 0xea5f0010)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
|
|
lsrs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xffff8030) != 0xea5f0010)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 4)) & Uint32(0x3)) ==
|
|
Uint32(0x3)) &&
|
|
((instr & 0x000070c0) != 0x00000000)) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c);
|
|
// RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; T3
|
|
rors(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xffff8030) != 0xea5f0030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (OutsideITBlock() &&
|
|
(instr & 0x00100000) == 0x00100000 &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// MOVS.W <Rd>, <Rm> {, <shift> #<amount> } ; T3
|
|
movs(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xffff8000) != 0xea5f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00100000) {
|
|
// MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T3 NOLINT(whitespace/line_length)
|
|
movs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xffff8000) != 0xea5f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea500030
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T2
|
|
orrs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xea500030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000) ||
|
|
((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (OutsideITBlock() &&
|
|
(instr & 0x00100000) == 0x00100000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd == rn) &&
|
|
(rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// ORRS.W {<Rd>}, <Rn>, <Rm> ; T2
|
|
orrs(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xea500000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00100000) {
|
|
// ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
orrs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xea500000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00600000: {
|
|
// 0xea700000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xea7f0000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea7f0030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// MVNS{<c>}{<q>} <Rd>, <Rm>, RRX ; T2
|
|
mvns(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfffff0f0) != 0xea7f0030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (OutsideITBlock() &&
|
|
(instr & 0x00100000) == 0x00100000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// MVNS.W <Rd>, <Rm> ; T2
|
|
mvns(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm));
|
|
if (((instr & 0xffff8000) != 0xea7f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00100000) {
|
|
// MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
mvns(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xffff8000) != 0xea7f0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea700030
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ORNS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T1
|
|
orns(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xea700030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000) ||
|
|
((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
// ORNS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
orns(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xea700000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xea800000
|
|
switch (instr & 0x00600000) {
|
|
case 0x00000000: {
|
|
// 0xea800000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea800030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T2
|
|
eor(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xea800030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (InITBlock() &&
|
|
(instr & 0x00100000) == 0x00000000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd == rn) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// EOR<c>.W {<Rd>}, <Rn>, <Rm> ; T2
|
|
eor(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xea800000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
eor(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xea800000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xeac00000
|
|
switch (instr & 0x00000030) {
|
|
case 0x00000000: {
|
|
// 0xeac00000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount =
|
|
((instr >> 6) & 0x3) | ((instr >> 10) & 0x1c);
|
|
// PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; T1 NOLINT(whitespace/line_length)
|
|
pkhbt(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), LSL, amount));
|
|
if (((instr & 0xfff08030) != 0xeac00000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xeac00020
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount =
|
|
((instr >> 6) & 0x3) | ((instr >> 10) & 0x1c);
|
|
if (amount == 0) amount = 32;
|
|
// PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; T1 NOLINT(whitespace/line_length)
|
|
pkhtb(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), ASR, amount));
|
|
if (((instr & 0xfff08030) != 0xeac00020)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00900000: {
|
|
// 0xea900000
|
|
switch (instr & 0x00600000) {
|
|
case 0x00000000: {
|
|
// 0xea900000
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000f00: {
|
|
// 0xea900f00
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea900f30
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// TEQ{<c>}{<q>} <Rn>, <Rm>, RRX ; T1
|
|
teq(CurrentCond(),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0fff0) != 0xea900f30)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
// TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
teq(CurrentCond(),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08f00) != 0xea900f00)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xea900030
|
|
if (((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T2
|
|
eors(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xea900030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30) ||
|
|
((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (OutsideITBlock() &&
|
|
(instr & 0x00100000) == 0x00100000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd == rn) &&
|
|
(rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// EORS.W {<Rd>}, <Rn>, <Rm> ; T2
|
|
eors(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xea900000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00100000) {
|
|
// EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
eors(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xea900000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xeb000000
|
|
switch (instr & 0x00600000) {
|
|
case 0x00000000: {
|
|
// 0xeb000000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000d0000: {
|
|
// 0xeb0d0000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xeb0d0030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ADD{<c>}{<q>} {<Rd>}, SP, <Rm>, RRX ; T3
|
|
add(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfffff0f0) != 0xeb0d0030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if ((instr & 0x00100000) == 0x00000000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
(((rd == rm)) || ((rd == sp.GetCode())))) {
|
|
// ADD{<c>}.W {<Rd>}, SP, <Rm> ; T3
|
|
add(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
sp,
|
|
Register(rm));
|
|
if (((instr & 0xffff8000) != 0xeb0d0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3 NOLINT(whitespace/line_length)
|
|
add(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xffff8000) != 0xeb0d0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xeb000030
|
|
if (((instr & 0xf0000) == 0xd0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T3
|
|
add(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xeb000030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xd0000) ||
|
|
((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (InITBlock() &&
|
|
(instr & 0x00100000) == 0x00000000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// ADD<c>.W {<Rd>}, <Rn>, <Rm> ; T3
|
|
add(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xeb000000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00000000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd == rn))) {
|
|
// ADD<c>.W {<Rd>}, <Rn>, <Rm> ; T3
|
|
add(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xeb000000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3 NOLINT(whitespace/line_length)
|
|
add(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xeb000000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xeb400000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xeb400030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T2
|
|
adc(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xeb400030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (InITBlock() &&
|
|
(instr & 0x00100000) == 0x00000000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd == rn) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// ADC<c>.W {<Rd>}, <Rn>, <Rm> ; T2
|
|
adc(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xeb400000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
adc(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xeb400000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00600000: {
|
|
// 0xeb600000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xeb600030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T2
|
|
sbc(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xeb600030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (InITBlock() &&
|
|
(instr & 0x00100000) == 0x00000000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd == rn) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// SBC<c>.W {<Rd>}, <Rn>, <Rm> ; T2
|
|
sbc(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xeb600000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
sbc(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xeb600000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01100000: {
|
|
// 0xeb100000
|
|
switch (instr & 0x00600000) {
|
|
case 0x00000000: {
|
|
// 0xeb100000
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000f00: {
|
|
// 0xeb100f00
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xeb100f30
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CMN{<c>}{<q>} <Rn>, <Rm>, RRX ; T2
|
|
cmn(CurrentCond(),
|
|
Best,
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0fff0) != 0xeb100f30)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rn < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// CMN{<c>}.W <Rn>, <Rm> ; T2
|
|
cmn(CurrentCond(),
|
|
Wide,
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08f00) != 0xeb100f00)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
cmn(CurrentCond(),
|
|
Best,
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08f00) != 0xeb100f00)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000d0000: {
|
|
// 0xeb1d0000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xeb1d0030
|
|
if (((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ADDS{<c>}{<q>} {<Rd>}, SP, <Rm>, RRX ; T3
|
|
adds(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfffff0f0) != 0xeb1d0030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30) ||
|
|
((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
// ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T3 NOLINT(whitespace/line_length)
|
|
adds(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xffff8000) != 0xeb1d0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xeb100030
|
|
if (((instr & 0xf0000) == 0xd0000) ||
|
|
((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T3
|
|
adds(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xeb100030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xd0000) ||
|
|
((instr & 0x70f0) == 0x30) ||
|
|
((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (OutsideITBlock() &&
|
|
(instr & 0x00100000) == 0x00100000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// ADDS.W {<Rd>}, <Rn>, <Rm> ; T3
|
|
adds(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xeb100000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) ==
|
|
0x00100000) {
|
|
// ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T3 NOLINT(whitespace/line_length)
|
|
adds(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xeb100000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xeb500000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xeb500030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T2
|
|
adcs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xeb500030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (OutsideITBlock() &&
|
|
(instr & 0x00100000) == 0x00100000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd == rn) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// ADCS.W {<Rd>}, <Rn>, <Rm> ; T2
|
|
adcs(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xeb500000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00100000) {
|
|
// ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
adcs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xeb500000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00600000: {
|
|
// 0xeb700000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xeb700030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T2
|
|
sbcs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xeb700030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (OutsideITBlock() &&
|
|
(instr & 0x00100000) == 0x00100000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd == rn) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// SBCS.W {<Rd>}, <Rn>, <Rm> ; T2
|
|
sbcs(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xeb700000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00100000) {
|
|
// SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
sbcs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xeb700000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01800000: {
|
|
// 0xeb800000
|
|
switch (instr & 0x00600000) {
|
|
case 0x00200000: {
|
|
// 0xeba00000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000d0000: {
|
|
// 0xebad0000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xebad0030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SUB{<c>}{<q>} {<Rd>}, SP, <Rm>, RRX ; T1
|
|
sub(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfffff0f0) != 0xebad0030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if ((instr & 0x00100000) == 0x00000000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0)) {
|
|
// SUB{<c>} {<Rd>}, SP, <Rm> ; T1
|
|
sub(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Register(rm));
|
|
if (((instr & 0xffff8000) != 0xebad0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
sub(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xffff8000) != 0xebad0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xeba00030
|
|
if (((instr & 0xf0000) == 0xd0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T2
|
|
sub(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xeba00030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xd0000) ||
|
|
((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (InITBlock() &&
|
|
(instr & 0x00100000) == 0x00000000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// SUB<c>.W {<Rd>}, <Rn>, <Rm> ; T2
|
|
sub(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xeba00000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
sub(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xeba00000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xebc00000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xebc00030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T1
|
|
rsb(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xebc00030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
// RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
rsb(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xebc00000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01900000: {
|
|
// 0xeb900000
|
|
switch (instr & 0x00600000) {
|
|
case 0x00200000: {
|
|
// 0xebb00000
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000f00: {
|
|
// 0xebb00f00
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xebb00f30
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CMP{<c>}{<q>} <Rn>, <Rm>, RRX ; T3
|
|
cmp(CurrentCond(),
|
|
Best,
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0fff0) != 0xebb00f30)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0)) {
|
|
// CMP{<c>}.W <Rn>, <Rm> ; T3
|
|
cmp(CurrentCond(),
|
|
Wide,
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08f00) != 0xebb00f00)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// CMP{<c>}{<q>} <Rn>, <Rm>, <shift> #<amount> ; T3 NOLINT(whitespace/line_length)
|
|
cmp(CurrentCond(),
|
|
Best,
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08f00) != 0xebb00f00)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000d0000: {
|
|
// 0xebbd0000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xebbd0030
|
|
if (((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SUBS{<c>}{<q>} {<Rd>}, SP, <Rm>, RRX ; T1
|
|
subs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfffff0f0) != 0xebbd0030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30) ||
|
|
((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
// SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
subs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xffff8000) != 0xebbd0000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xebb00030
|
|
if (((instr & 0xf0000) == 0xd0000) ||
|
|
((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T2
|
|
subs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xebb00030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xd0000) ||
|
|
((instr & 0x70f0) == 0x30) ||
|
|
((instr & 0xf00) == 0xf00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
if (OutsideITBlock() &&
|
|
(instr & 0x00100000) == 0x00100000 &&
|
|
shift_operand.GetShift().IsLSL() &&
|
|
(shift_operand.GetAmount() == 0) &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// SUBS.W {<Rd>}, <Rn>, <Rm> ; T2
|
|
subs(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff08000) != 0xebb00000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else if ((instr & 0x00100000) ==
|
|
0x00100000) {
|
|
// SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
subs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xebb00000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xebd00000
|
|
switch (instr & 0x000070f0) {
|
|
case 0x00000030: {
|
|
// 0xebd00030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; T1
|
|
rsbs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0f0f0) != 0xebd00030)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x70f0) == 0x30)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand
|
|
shift_operand((instr >> 4) & 0x3,
|
|
((instr >> 6) & 0x3) |
|
|
((instr >> 10) & 0x1c));
|
|
// RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
rsbs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff08000) != 0xebd00000)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xfa000000
|
|
switch (instr & 0x0000f080) {
|
|
case 0x0000f000: {
|
|
// 0xfa00f000
|
|
if ((instr & 0x00000070) == 0x00000000) {
|
|
if (((Uint32((instr >> 21)) & Uint32(0x3)) ==
|
|
Uint32(0x2))) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = (instr >> 16) & 0xf;
|
|
unsigned rs = instr & 0xf;
|
|
if (InITBlock() &&
|
|
((rd == rm) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rs < kNumberOfT32LowRegisters))) {
|
|
// ASR<c>.W {<Rd>}, <Rm>, <Rs> ; T2
|
|
asr(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
} else {
|
|
// ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
|
|
asr(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 21)) & Uint32(0x3)) ==
|
|
Uint32(0x0))) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = (instr >> 16) & 0xf;
|
|
unsigned rs = instr & 0xf;
|
|
if (InITBlock() &&
|
|
((rd == rm) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rs < kNumberOfT32LowRegisters))) {
|
|
// LSL<c>.W {<Rd>}, <Rm>, <Rs> ; T2
|
|
lsl(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
} else {
|
|
// LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
|
|
lsl(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 21)) & Uint32(0x3)) ==
|
|
Uint32(0x1))) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = (instr >> 16) & 0xf;
|
|
unsigned rs = instr & 0xf;
|
|
if (InITBlock() &&
|
|
((rd == rm) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rs < kNumberOfT32LowRegisters))) {
|
|
// LSR<c>.W {<Rd>}, <Rm>, <Rs> ; T2
|
|
lsr(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
} else {
|
|
// LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
|
|
lsr(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 21)) & Uint32(0x3)) ==
|
|
Uint32(0x3))) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = (instr >> 16) & 0xf;
|
|
unsigned rs = instr & 0xf;
|
|
if (InITBlock() &&
|
|
((rd == rm) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rs < kNumberOfT32LowRegisters))) {
|
|
// ROR<c>.W {<Rd>}, <Rm>, <Rs> ; T2
|
|
ror(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
} else {
|
|
// ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
|
|
ror(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
}
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = (instr >> 16) & 0xf;
|
|
Shift shift((instr >> 21) & 0x3);
|
|
unsigned rs = instr & 0xf;
|
|
if (InITBlock() && (instr & 0x00100000) == 0x00000000 &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters) &&
|
|
(rs < kNumberOfT32LowRegisters))) {
|
|
// MOV<c>.W <Rd>, <Rm>, <shift> <Rs> ; T2
|
|
mov(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift.GetType(),
|
|
Register(rs)));
|
|
} else if ((instr & 0x00100000) == 0x00000000) {
|
|
// MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
|
|
mov(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift.GetType(),
|
|
Register(rs)));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x0000f080: {
|
|
// 0xfa00f080
|
|
switch (instr & 0x00600000) {
|
|
case 0x00000000: {
|
|
// 0xfa00f080
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xfa0ff080
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 4) & 0x3) * 8;
|
|
if ((amount == 0) &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// SXTH{<c>}.W {<Rd>}, <Rm> ; T2
|
|
sxth(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm));
|
|
if (((instr & 0xfffff0c0) != 0xfa0ff080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
sxth(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfffff0c0) != 0xfa0ff080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 4) & 0x3) * 8;
|
|
// SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
sxtah(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfff0f0c0) != 0xfa00f080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xfa20f080
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xfa2ff080
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 4) & 0x3) * 8;
|
|
// SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
sxtb16(CurrentCond(),
|
|
Register(rd),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfffff0c0) != 0xfa2ff080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 4) & 0x3) * 8;
|
|
// SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
sxtab16(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfff0f0c0) != 0xfa20f080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xfa40f080
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xfa4ff080
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 4) & 0x3) * 8;
|
|
if ((amount == 0) &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// SXTB{<c>}.W {<Rd>}, <Rm> ; T2
|
|
sxtb(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm));
|
|
if (((instr & 0xfffff0c0) != 0xfa4ff080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
sxtb(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfffff0c0) != 0xfa4ff080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 4) & 0x3) * 8;
|
|
// SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
sxtab(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfff0f0c0) != 0xfa40f080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x10100000: {
|
|
// 0xfa100000
|
|
switch (instr & 0x0000f080) {
|
|
case 0x0000f000: {
|
|
// 0xfa10f000
|
|
if ((instr & 0x00000070) == 0x00000000) {
|
|
if (((Uint32((instr >> 21)) & Uint32(0x3)) ==
|
|
Uint32(0x2))) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = (instr >> 16) & 0xf;
|
|
unsigned rs = instr & 0xf;
|
|
if (OutsideITBlock() &&
|
|
((rd == rm) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rs < kNumberOfT32LowRegisters))) {
|
|
// ASRS.W {<Rd>}, <Rm>, <Rs> ; T2
|
|
asrs(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
} else {
|
|
// ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
|
|
asrs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 21)) & Uint32(0x3)) ==
|
|
Uint32(0x0))) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = (instr >> 16) & 0xf;
|
|
unsigned rs = instr & 0xf;
|
|
if (OutsideITBlock() &&
|
|
((rd == rm) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rs < kNumberOfT32LowRegisters))) {
|
|
// LSLS.W {<Rd>}, <Rm>, <Rs> ; T2
|
|
lsls(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
} else {
|
|
// LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
|
|
lsls(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 21)) & Uint32(0x3)) ==
|
|
Uint32(0x1))) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = (instr >> 16) & 0xf;
|
|
unsigned rs = instr & 0xf;
|
|
if (OutsideITBlock() &&
|
|
((rd == rm) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rs < kNumberOfT32LowRegisters))) {
|
|
// LSRS.W {<Rd>}, <Rm>, <Rs> ; T2
|
|
lsrs(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
} else {
|
|
// LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
|
|
lsrs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 21)) & Uint32(0x3)) ==
|
|
Uint32(0x3))) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = (instr >> 16) & 0xf;
|
|
unsigned rs = instr & 0xf;
|
|
if (OutsideITBlock() &&
|
|
((rd == rm) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rs < kNumberOfT32LowRegisters))) {
|
|
// RORS.W {<Rd>}, <Rm>, <Rs> ; T2
|
|
rors(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
} else {
|
|
// RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; T2
|
|
rors(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
}
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = (instr >> 16) & 0xf;
|
|
Shift shift((instr >> 21) & 0x3);
|
|
unsigned rs = instr & 0xf;
|
|
if (OutsideITBlock() &&
|
|
(instr & 0x00100000) == 0x00100000 &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters) &&
|
|
(rs < kNumberOfT32LowRegisters))) {
|
|
// MOVS.W <Rd>, <Rm>, <shift> <Rs> ; T2
|
|
movs(Condition::None(),
|
|
Wide,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift.GetType(),
|
|
Register(rs)));
|
|
} else if ((instr & 0x00100000) == 0x00100000) {
|
|
// MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; T2
|
|
movs(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift.GetType(),
|
|
Register(rs)));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x0000f080: {
|
|
// 0xfa10f080
|
|
switch (instr & 0x00600000) {
|
|
case 0x00000000: {
|
|
// 0xfa10f080
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xfa1ff080
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 4) & 0x3) * 8;
|
|
if ((amount == 0) &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// UXTH{<c>}.W {<Rd>}, <Rm> ; T2
|
|
uxth(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm));
|
|
if (((instr & 0xfffff0c0) != 0xfa1ff080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
uxth(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfffff0c0) != 0xfa1ff080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 4) & 0x3) * 8;
|
|
// UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
uxtah(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfff0f0c0) != 0xfa10f080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xfa30f080
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xfa3ff080
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 4) & 0x3) * 8;
|
|
// UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
uxtb16(CurrentCond(),
|
|
Register(rd),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfffff0c0) != 0xfa3ff080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 4) & 0x3) * 8;
|
|
// UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
uxtab16(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfff0f0c0) != 0xfa30f080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xfa50f080
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xfa5ff080
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 4) & 0x3) * 8;
|
|
if ((amount == 0) &&
|
|
((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters))) {
|
|
// UXTB{<c>}.W {<Rd>}, <Rm> ; T2
|
|
uxtb(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm));
|
|
if (((instr & 0xfffff0c0) != 0xfa5ff080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
// UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; T2 NOLINT(whitespace/line_length)
|
|
uxtb(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfffff0c0) != 0xfa5ff080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 4) & 0x3) * 8;
|
|
// UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; T1 NOLINT(whitespace/line_length)
|
|
uxtab(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfff0f0c0) != 0xfa50f080)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x10800000: {
|
|
// 0xfa800000
|
|
switch (instr & 0x0060f0f0) {
|
|
case 0x0000f000: {
|
|
// 0xfa80f000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
sadd8(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0000f010: {
|
|
// 0xfa80f010
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
qadd8(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0000f020: {
|
|
// 0xfa80f020
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
shadd8(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0000f040: {
|
|
// 0xfa80f040
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
uadd8(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0000f050: {
|
|
// 0xfa80f050
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
uqadd8(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0000f060: {
|
|
// 0xfa80f060
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
uhadd8(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0000f080: {
|
|
// 0xfa80f080
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
|
|
qadd(CurrentCond(),
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rn));
|
|
break;
|
|
}
|
|
case 0x0000f090: {
|
|
// 0xfa80f090
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
|
|
qdadd(CurrentCond(),
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rn));
|
|
break;
|
|
}
|
|
case 0x0000f0a0: {
|
|
// 0xfa80f0a0
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
|
|
qsub(CurrentCond(),
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rn));
|
|
break;
|
|
}
|
|
case 0x0000f0b0: {
|
|
// 0xfa80f0b0
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; T1
|
|
qdsub(CurrentCond(),
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rn));
|
|
break;
|
|
}
|
|
case 0x0020f000: {
|
|
// 0xfaa0f000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
sasx(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0020f010: {
|
|
// 0xfaa0f010
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
qasx(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0020f020: {
|
|
// 0xfaa0f020
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
shasx(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0020f040: {
|
|
// 0xfaa0f040
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
uasx(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0020f050: {
|
|
// 0xfaa0f050
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
uqasx(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0020f060: {
|
|
// 0xfaa0f060
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
uhasx(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0020f080: {
|
|
// 0xfaa0f080
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
sel(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f000: {
|
|
// 0xfac0f000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
ssub8(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f010: {
|
|
// 0xfac0f010
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
qsub8(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f020: {
|
|
// 0xfac0f020
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
shsub8(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f040: {
|
|
// 0xfac0f040
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
usub8(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f050: {
|
|
// 0xfac0f050
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
uqsub8(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f060: {
|
|
// 0xfac0f060
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
uhsub8(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f080: {
|
|
// 0xfac0f080
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CRC32B{<q>} <Rd>, <Rn>, <Rm> ; T1
|
|
crc32b(Condition::None(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f090: {
|
|
// 0xfac0f090
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CRC32H{<q>} <Rd>, <Rn>, <Rm> ; T1
|
|
crc32h(Condition::None(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f0a0: {
|
|
// 0xfac0f0a0
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CRC32W{<q>} <Rd>, <Rn>, <Rm> ; T1
|
|
crc32w(Condition::None(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0060f000: {
|
|
// 0xfae0f000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
ssax(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0060f010: {
|
|
// 0xfae0f010
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
qsax(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0060f020: {
|
|
// 0xfae0f020
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
shsax(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0060f040: {
|
|
// 0xfae0f040
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
usax(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0060f050: {
|
|
// 0xfae0f050
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
uqsax(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0060f060: {
|
|
// 0xfae0f060
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
uhsax(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x10900000: {
|
|
// 0xfa900000
|
|
switch (instr & 0x0060f0f0) {
|
|
case 0x0000f000: {
|
|
// 0xfa90f000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
sadd16(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0000f010: {
|
|
// 0xfa90f010
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
qadd16(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0000f020: {
|
|
// 0xfa90f020
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
shadd16(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0000f040: {
|
|
// 0xfa90f040
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
uadd16(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0000f050: {
|
|
// 0xfa90f050
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
uqadd16(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0000f060: {
|
|
// 0xfa90f060
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
uhadd16(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0000f080: {
|
|
// 0xfa90f080
|
|
if (((instr >> 16) & 0xf) == (instr & 0xf)) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
if ((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters)) {
|
|
// REV{<c>}.W <Rd>, <Rm> ; T2
|
|
rev(CurrentCond(), Wide, Register(rd), Register(rm));
|
|
} else {
|
|
// REV{<c>}{<q>} <Rd>, <Rm> ; T2
|
|
rev(CurrentCond(), Best, Register(rd), Register(rm));
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x0000f090: {
|
|
// 0xfa90f090
|
|
if (((instr >> 16) & 0xf) == (instr & 0xf)) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
if ((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters)) {
|
|
// REV16{<c>}.W <Rd>, <Rm> ; T2
|
|
rev16(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm));
|
|
} else {
|
|
// REV16{<c>}{<q>} <Rd>, <Rm> ; T2
|
|
rev16(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm));
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x0000f0a0: {
|
|
// 0xfa90f0a0
|
|
if (((instr >> 16) & 0xf) == (instr & 0xf)) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// RBIT{<c>}{<q>} <Rd>, <Rm> ; T1
|
|
rbit(CurrentCond(), Register(rd), Register(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x0000f0b0: {
|
|
// 0xfa90f0b0
|
|
if (((instr >> 16) & 0xf) == (instr & 0xf)) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
if ((rd < kNumberOfT32LowRegisters) &&
|
|
(rm < kNumberOfT32LowRegisters)) {
|
|
// REVSH{<c>}.W <Rd>, <Rm> ; T2
|
|
revsh(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rm));
|
|
} else {
|
|
// REVSH{<c>}{<q>} <Rd>, <Rm> ; T2
|
|
revsh(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rm));
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x0020f080: {
|
|
// 0xfab0f080
|
|
if (((instr >> 16) & 0xf) == (instr & 0xf)) {
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CLZ{<c>}{<q>} <Rd>, <Rm> ; T1
|
|
clz(CurrentCond(), Register(rd), Register(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x0040f000: {
|
|
// 0xfad0f000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
ssub16(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f010: {
|
|
// 0xfad0f010
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
qsub16(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f020: {
|
|
// 0xfad0f020
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
shsub16(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f040: {
|
|
// 0xfad0f040
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
usub16(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f050: {
|
|
// 0xfad0f050
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
uqsub16(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f060: {
|
|
// 0xfad0f060
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
uhsub16(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f080: {
|
|
// 0xfad0f080
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; T1
|
|
crc32cb(Condition::None(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f090: {
|
|
// 0xfad0f090
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; T1
|
|
crc32ch(Condition::None(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x0040f0a0: {
|
|
// 0xfad0f0a0
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; T1
|
|
crc32cw(Condition::None(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x11000000: {
|
|
// 0xfb000000
|
|
switch (instr & 0x006000f0) {
|
|
case 0x00000000: {
|
|
// 0xfb000000
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xfb00f000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
if (InITBlock() &&
|
|
((rd == rm) && (rd < kNumberOfT32LowRegisters) &&
|
|
(rn < kNumberOfT32LowRegisters))) {
|
|
// MUL<c>.W <Rd>, <Rn>, {<Rm>} ; T2
|
|
mul(CurrentCond(),
|
|
Wide,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
} else {
|
|
// MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; T2
|
|
mul(CurrentCond(),
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
mla(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000010: {
|
|
// 0xfb000010
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
mls(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xfb200000
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xfb20f000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
smuad(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
smlad(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200010: {
|
|
// 0xfb200010
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xfb20f010
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
smuadx(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
smladx(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xfb400000
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xfb40f000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
smusd(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
smlsd(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400010: {
|
|
// 0xfb400010
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xfb40f010
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
smusdx(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
smlsdx(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00600000: {
|
|
// 0xfb600000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
smmls(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
case 0x00600010: {
|
|
// 0xfb600010
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
smmlsr(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x11100000: {
|
|
// 0xfb100000
|
|
switch (instr & 0x006000f0) {
|
|
case 0x00000000: {
|
|
// 0xfb100000
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xfb10f000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
smulbb(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
smlabb(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000010: {
|
|
// 0xfb100010
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xfb10f010
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
smulbt(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
smlabt(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xfb100020
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xfb10f020
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
smultb(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
smlatb(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000030: {
|
|
// 0xfb100030
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xfb10f030
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
smultt(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
smlatt(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xfb300000
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xfb30f000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
smulwb(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
smlawb(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200010: {
|
|
// 0xfb300010
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xfb30f010
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
smulwt(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
smlawt(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xfb500000
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xfb50f000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
smmul(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
smmla(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400010: {
|
|
// 0xfb500010
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xfb50f010
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
smmulr(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
smmlar(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00600000: {
|
|
// 0xfb700000
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0xfb70f000
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
usad8(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; T1
|
|
usada8(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x11800000: {
|
|
// 0xfb800000
|
|
switch (instr & 0x006000f0) {
|
|
case 0x00000000: {
|
|
// 0xfb800000
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
|
|
smull(CurrentCond(),
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xfba00000
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
|
|
umull(CurrentCond(),
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xfbc00000
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
|
|
smlal(CurrentCond(),
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x00400080: {
|
|
// 0xfbc00080
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
|
|
smlalbb(CurrentCond(),
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x00400090: {
|
|
// 0xfbc00090
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
|
|
smlalbt(CurrentCond(),
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x004000a0: {
|
|
// 0xfbc000a0
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
|
|
smlaltb(CurrentCond(),
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x004000b0: {
|
|
// 0xfbc000b0
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
|
|
smlaltt(CurrentCond(),
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x004000c0: {
|
|
// 0xfbc000c0
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
|
|
smlald(CurrentCond(),
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x004000d0: {
|
|
// 0xfbc000d0
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
|
|
smlaldx(CurrentCond(),
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x00600000: {
|
|
// 0xfbe00000
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
|
|
umlal(CurrentCond(),
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x00600060: {
|
|
// 0xfbe00060
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
|
|
umaal(CurrentCond(),
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x11900000: {
|
|
// 0xfb900000
|
|
switch (instr & 0x006000f0) {
|
|
case 0x000000f0: {
|
|
// 0xfb9000f0
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
sdiv(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff0f0f0) != 0xfb90f0f0)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x002000f0: {
|
|
// 0xfbb000f0
|
|
unsigned rd = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; T1
|
|
udiv(CurrentCond(),
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xfff0f0f0) != 0xfbb0f0f0)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x004000c0: {
|
|
// 0xfbd000c0
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
|
|
smlsld(CurrentCond(),
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x004000d0: {
|
|
// 0xfbd000d0
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 8) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; T1
|
|
smlsldx(CurrentCond(),
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x04000000: {
|
|
// 0xec000000
|
|
switch (instr & 0x11100e00) {
|
|
case 0x00000a00: {
|
|
// 0xec000a00
|
|
switch (instr & 0x00800100) {
|
|
case 0x00000000: {
|
|
// 0xec000a00
|
|
if ((instr & 0x006000d0) == 0x00400010) {
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 16) & 0xf;
|
|
// VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; T1
|
|
vmov(CurrentCond(),
|
|
SRegister(rm),
|
|
SRegister(rm + 1),
|
|
Register(rt),
|
|
Register(rt2));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xec000b00
|
|
if ((instr & 0x006000d0) == 0x00400010) {
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 16) & 0xf;
|
|
// VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; T1
|
|
vmov(CurrentCond(),
|
|
DRegister(rm),
|
|
Register(rt),
|
|
Register(rt2));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xec800a00
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
unsigned first = ExtractSRegister(instr, 22, 12);
|
|
unsigned len = instr & 0xff;
|
|
// VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
|
|
vstm(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
write_back,
|
|
SRegisterList(SRegister(first), len));
|
|
if ((len == 0) || ((first + len) > kNumberOfSRegisters)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800100: {
|
|
// 0xec800b00
|
|
switch (instr & 0x00000001) {
|
|
case 0x00000000: {
|
|
// 0xec800b00
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
|
|
vstm(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
write_back,
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) ||
|
|
(end > kMaxNumberOfDRegisters)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000001: {
|
|
// 0xec800b01
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
|
|
fstmiax(CurrentCond(),
|
|
Register(rn),
|
|
write_back,
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) || (end > 16)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000e00: {
|
|
// 0xec000e00
|
|
switch (instr & 0x00600000) {
|
|
case 0x00000000: {
|
|
// 0xec000e00
|
|
if ((instr & 0x0080f100) == 0x00805000) {
|
|
UnimplementedT32_32("STC", instr);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xec200e00
|
|
if ((instr & 0x0000f100) == 0x00005000) {
|
|
UnimplementedT32_32("STC", instr);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xec400e00
|
|
if ((instr & 0x00800000) == 0x00000000) {
|
|
UnimplementedT32_32("MCRR", instr);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100a00: {
|
|
// 0xec100a00
|
|
switch (instr & 0x00800100) {
|
|
case 0x00000000: {
|
|
// 0xec100a00
|
|
if ((instr & 0x006000d0) == 0x00400010) {
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 16) & 0xf;
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; T1
|
|
vmov(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
SRegister(rm),
|
|
SRegister(rm + 1));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xec100b00
|
|
if ((instr & 0x006000d0) == 0x00400010) {
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 16) & 0xf;
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; T1
|
|
vmov(CurrentCond(),
|
|
Register(rt),
|
|
Register(rt2),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xec900a00
|
|
if (((Uint32((instr >> 21)) & Uint32(0x1)) ==
|
|
Uint32(0x1)) &&
|
|
((Uint32((instr >> 16)) & Uint32(0xf)) ==
|
|
Uint32(0xd))) {
|
|
unsigned first = ExtractSRegister(instr, 22, 12);
|
|
unsigned len = instr & 0xff;
|
|
// VPOP{<c>}{<q>}{.<size>} <sreglist> ; T2
|
|
vpop(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
SRegisterList(SRegister(first), len));
|
|
if ((len == 0) ||
|
|
((first + len) > kNumberOfSRegisters)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
unsigned first = ExtractSRegister(instr, 22, 12);
|
|
unsigned len = instr & 0xff;
|
|
// VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; T2
|
|
vldm(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
write_back,
|
|
SRegisterList(SRegister(first), len));
|
|
if ((len == 0) || ((first + len) > kNumberOfSRegisters)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800100: {
|
|
// 0xec900b00
|
|
switch (instr & 0x00000001) {
|
|
case 0x00000000: {
|
|
// 0xec900b00
|
|
if (((Uint32((instr >> 21)) & Uint32(0x1)) ==
|
|
Uint32(0x1)) &&
|
|
((Uint32((instr >> 16)) & Uint32(0xf)) ==
|
|
Uint32(0xd))) {
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// VPOP{<c>}{<q>}{.<size>} <dreglist> ; T1
|
|
vpop(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) ||
|
|
(end > kMaxNumberOfDRegisters)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; T1
|
|
vldm(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
write_back,
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) ||
|
|
(end > kMaxNumberOfDRegisters)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000001: {
|
|
// 0xec900b01
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; T1
|
|
fldmiax(CurrentCond(),
|
|
Register(rn),
|
|
write_back,
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) || (end > 16)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100e00: {
|
|
// 0xec100e00
|
|
switch (instr & 0x00600000) {
|
|
case 0x00000000: {
|
|
// 0xec100e00
|
|
if ((instr & 0x0080f100) == 0x00805000) {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
UnimplementedT32_32("LDC", instr);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xec300e00
|
|
if ((instr & 0x0000f100) == 0x00005000) {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
UnimplementedT32_32("LDC", instr);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xec500e00
|
|
if ((instr & 0x00800000) == 0x00000000) {
|
|
UnimplementedT32_32("MRRC", instr);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000a00: {
|
|
// 0xed000a00
|
|
switch (instr & 0x00200100) {
|
|
case 0x00000000: {
|
|
// 0xed000a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2
|
|
vstr(CurrentCond(),
|
|
Untyped32,
|
|
SRegister(rd),
|
|
MemOperand(Register(rn), sign, offset, Offset));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xed000b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1
|
|
vstr(CurrentCond(),
|
|
Untyped64,
|
|
DRegister(rd),
|
|
MemOperand(Register(rn), sign, offset, Offset));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xed200a00
|
|
if ((instr & 0x00800000) == 0x00000000) {
|
|
if (((Uint32((instr >> 16)) & Uint32(0xf)) ==
|
|
Uint32(0xd))) {
|
|
unsigned first = ExtractSRegister(instr, 22, 12);
|
|
unsigned len = instr & 0xff;
|
|
// VPUSH{<c>}{<q>}{.<size>} <sreglist> ; T2
|
|
vpush(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
SRegisterList(SRegister(first), len));
|
|
if ((len == 0) ||
|
|
((first + len) > kNumberOfSRegisters)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned first = ExtractSRegister(instr, 22, 12);
|
|
unsigned len = instr & 0xff;
|
|
// VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
|
|
vstmdb(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
WriteBack(WRITE_BACK),
|
|
SRegisterList(SRegister(first), len));
|
|
if ((len == 0) ||
|
|
((first + len) > kNumberOfSRegisters)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200100: {
|
|
// 0xed200b00
|
|
switch (instr & 0x00800001) {
|
|
case 0x00000000: {
|
|
// 0xed200b00
|
|
if (((Uint32((instr >> 16)) & Uint32(0xf)) ==
|
|
Uint32(0xd))) {
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// VPUSH{<c>}{<q>}{.<size>} <dreglist> ; T1
|
|
vpush(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) ||
|
|
(end > kMaxNumberOfDRegisters)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
|
|
vstmdb(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
WriteBack(WRITE_BACK),
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) ||
|
|
(end > kMaxNumberOfDRegisters)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000001: {
|
|
// 0xed200b01
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
|
|
fstmdbx(CurrentCond(),
|
|
Register(rn),
|
|
WriteBack(WRITE_BACK),
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) || (end > 16)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000e00: {
|
|
// 0xed000e00
|
|
switch (instr & 0x0060f100) {
|
|
case 0x00005000: {
|
|
// 0xed005e00
|
|
UnimplementedT32_32("STC", instr);
|
|
break;
|
|
}
|
|
case 0x00205000: {
|
|
// 0xed205e00
|
|
UnimplementedT32_32("STC", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01100a00: {
|
|
// 0xed100a00
|
|
switch (instr & 0x00200100) {
|
|
case 0x00000000: {
|
|
// 0xed100a00
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xed1f0a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xff;
|
|
imm <<= 2;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kT32PcDelta);
|
|
// VLDR{<c>}{<q>}{.32} <Sd>, <label> ; T2
|
|
if (minus_zero) {
|
|
vldr(CurrentCond(),
|
|
Untyped32,
|
|
SRegister(rd),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
vldr(CurrentCond(),
|
|
Untyped32,
|
|
SRegister(rd),
|
|
&location);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; T2 NOLINT(whitespace/line_length)
|
|
vldr(CurrentCond(),
|
|
Untyped32,
|
|
SRegister(rd),
|
|
MemOperand(Register(rn), sign, offset, Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xed100b00
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xed1f0b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xff;
|
|
imm <<= 2;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kT32PcDelta);
|
|
// VLDR{<c>}{<q>}{.64} <Dd>, <label> ; T1
|
|
if (minus_zero) {
|
|
vldr(CurrentCond(),
|
|
Untyped64,
|
|
DRegister(rd),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
vldr(CurrentCond(),
|
|
Untyped64,
|
|
DRegister(rd),
|
|
&location);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; T1 NOLINT(whitespace/line_length)
|
|
vldr(CurrentCond(),
|
|
Untyped64,
|
|
DRegister(rd),
|
|
MemOperand(Register(rn), sign, offset, Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xed300a00
|
|
if ((instr & 0x00800000) == 0x00000000) {
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned first = ExtractSRegister(instr, 22, 12);
|
|
unsigned len = instr & 0xff;
|
|
// VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; T2
|
|
vldmdb(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
WriteBack(WRITE_BACK),
|
|
SRegisterList(SRegister(first), len));
|
|
if ((len == 0) ||
|
|
((first + len) > kNumberOfSRegisters)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200100: {
|
|
// 0xed300b00
|
|
switch (instr & 0x00800001) {
|
|
case 0x00000000: {
|
|
// 0xed300b00
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; T1
|
|
vldmdb(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
WriteBack(WRITE_BACK),
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) ||
|
|
(end > kMaxNumberOfDRegisters)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000001: {
|
|
// 0xed300b01
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; T1
|
|
fldmdbx(CurrentCond(),
|
|
Register(rn),
|
|
WriteBack(WRITE_BACK),
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) || (end > 16)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01100e00: {
|
|
// 0xed100e00
|
|
switch (instr & 0x0060f100) {
|
|
case 0x00005000: {
|
|
// 0xed105e00
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xed1f5e00
|
|
UnimplementedT32_32("LDC", instr);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
UnimplementedT32_32("LDC", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00205000: {
|
|
// 0xed305e00
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
UnimplementedT32_32("LDC", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x06000000: {
|
|
// 0xee000000
|
|
switch (instr & 0x01000010) {
|
|
case 0x00000000: {
|
|
// 0xee000000
|
|
switch (instr & 0x10b00f40) {
|
|
case 0x00000a00: {
|
|
// 0xee000a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
|
|
vmla(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000a40: {
|
|
// 0xee000a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
|
|
vmls(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000b00: {
|
|
// 0xee000b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
|
|
vmla(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000b40: {
|
|
// 0xee000b40
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
|
|
vmls(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00100a00: {
|
|
// 0xee100a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
|
|
vnmls(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00100a40: {
|
|
// 0xee100a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
|
|
vnmla(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00100b00: {
|
|
// 0xee100b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
|
|
vnmls(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00100b40: {
|
|
// 0xee100b40
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
|
|
vnmla(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200a00: {
|
|
// 0xee200a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
|
|
vmul(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200a40: {
|
|
// 0xee200a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
|
|
vnmul(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200b00: {
|
|
// 0xee200b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
|
|
vmul(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200b40: {
|
|
// 0xee200b40
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
|
|
vnmul(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00300a00: {
|
|
// 0xee300a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
|
|
vadd(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00300a40: {
|
|
// 0xee300a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T2
|
|
vsub(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00300b00: {
|
|
// 0xee300b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
|
|
vadd(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00300b40: {
|
|
// 0xee300b40
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T2
|
|
vsub(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00800a00: {
|
|
// 0xee800a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; T1
|
|
vdiv(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00800b00: {
|
|
// 0xee800b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; T1
|
|
vdiv(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00900a00: {
|
|
// 0xee900a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
|
|
vfnms(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00900a40: {
|
|
// 0xee900a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T1
|
|
vfnma(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00900b00: {
|
|
// 0xee900b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
|
|
vfnms(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00900b40: {
|
|
// 0xee900b40
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T1
|
|
vfnma(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00a00a00: {
|
|
// 0xeea00a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
|
|
vfma(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00a00a40: {
|
|
// 0xeea00a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
|
|
vfms(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00a00b00: {
|
|
// 0xeea00b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
|
|
vfma(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00a00b40: {
|
|
// 0xeea00b40
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
|
|
vfms(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00b00a00: {
|
|
// 0xeeb00a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
uint32_t encoded_imm =
|
|
(instr & 0xf) | ((instr >> 12) & 0xf0);
|
|
NeonImmediate imm =
|
|
ImmediateVFP::Decode<float>(encoded_imm);
|
|
// VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; T2
|
|
vmov(CurrentCond(), F32, SRegister(rd), imm);
|
|
if (((instr & 0xffb00ff0) != 0xeeb00a00)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00b00a40: {
|
|
// 0xeeb00a40
|
|
switch (instr & 0x000e0000) {
|
|
case 0x00000000: {
|
|
// 0xeeb00a40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0xeeb00a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
|
|
vmov(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xeeb00ac0
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
|
|
vabs(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0xeeb10a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; T2
|
|
vneg(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0xeeb10ac0
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
|
|
vsqrt(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00020000: {
|
|
// 0xeeb20a40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0xeeb20a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
|
|
vcvtb(CurrentCond(),
|
|
F32,
|
|
F16,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xeeb20ac0
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; T1
|
|
vcvtt(CurrentCond(),
|
|
F32,
|
|
F16,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0xeeb30a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
|
|
vcvtb(CurrentCond(),
|
|
F16,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0xeeb30ac0
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; T1
|
|
vcvtt(CurrentCond(),
|
|
F16,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00040000: {
|
|
// 0xeeb40a40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0xeeb40a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
|
|
vcmp(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xeeb40ac0
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
|
|
vcmpe(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0xeeb50a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
// VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
|
|
vcmp(CurrentCond(), F32, SRegister(rd), 0.0);
|
|
if (((instr & 0xffbf0fff) != 0xeeb50a40)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0xeeb50ac0
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
// VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; T2
|
|
vcmpe(CurrentCond(), F32, SRegister(rd), 0.0);
|
|
if (((instr & 0xffbf0fff) != 0xeeb50ac0)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00060000: {
|
|
// 0xeeb60a40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0xeeb60a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VRINTR{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
|
|
vrintr(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xeeb60ac0
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VRINTZ{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
|
|
vrintz(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0xeeb70a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VRINTX{<c>}{<q>}.F32 <Sd>, <Sm> ; T1
|
|
vrintx(CurrentCond(),
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0xeeb70ac0
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; T1
|
|
vcvt(CurrentCond(),
|
|
F64,
|
|
F32,
|
|
DRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00080000: {
|
|
// 0xeeb80a40
|
|
if ((instr & 0x00010000) == 0x00000000) {
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; T1
|
|
vcvt(CurrentCond(),
|
|
F32,
|
|
dt,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000a0000: {
|
|
// 0xeeba0a40
|
|
DataType dt = Dt_U_sx_1_Decode(((instr >> 7) & 0x1) |
|
|
((instr >> 15) & 0x2));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned offset = 32;
|
|
if (dt.Is(S16) || dt.Is(U16)) {
|
|
offset = 16;
|
|
}
|
|
uint32_t fbits = offset - (((instr >> 5) & 0x1) |
|
|
((instr << 1) & 0x1e));
|
|
// VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; T1
|
|
vcvt(CurrentCond(),
|
|
F32,
|
|
dt,
|
|
SRegister(rd),
|
|
SRegister(rd),
|
|
fbits);
|
|
break;
|
|
}
|
|
case 0x000c0000: {
|
|
// 0xeebc0a40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0xeebc0a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
|
|
vcvtr(CurrentCond(),
|
|
U32,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xeebc0ac0
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; T1
|
|
vcvt(CurrentCond(),
|
|
U32,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0xeebd0a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
|
|
vcvtr(CurrentCond(),
|
|
S32,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0xeebd0ac0
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; T1
|
|
vcvt(CurrentCond(),
|
|
S32,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x000e0000: {
|
|
// 0xeebe0a40
|
|
DataType dt = Dt_U_sx_1_Decode(((instr >> 7) & 0x1) |
|
|
((instr >> 15) & 0x2));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned offset = 32;
|
|
if (dt.Is(S16) || dt.Is(U16)) {
|
|
offset = 16;
|
|
}
|
|
uint32_t fbits = offset - (((instr >> 5) & 0x1) |
|
|
((instr << 1) & 0x1e));
|
|
// VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; T1
|
|
vcvt(CurrentCond(),
|
|
dt,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rd),
|
|
fbits);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00b00b00: {
|
|
// 0xeeb00b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
uint32_t encoded_imm =
|
|
(instr & 0xf) | ((instr >> 12) & 0xf0);
|
|
NeonImmediate imm =
|
|
ImmediateVFP::Decode<double>(encoded_imm);
|
|
// VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; T2
|
|
vmov(CurrentCond(), F64, DRegister(rd), imm);
|
|
if (((instr & 0xffb00ff0) != 0xeeb00b00)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00b00b40: {
|
|
// 0xeeb00b40
|
|
switch (instr & 0x000e0000) {
|
|
case 0x00000000: {
|
|
// 0xeeb00b40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0xeeb00b40
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
|
|
vmov(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xeeb00bc0
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
|
|
vabs(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0xeeb10b40
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; T2
|
|
vneg(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0xeeb10bc0
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
|
|
vsqrt(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00020000: {
|
|
// 0xeeb20b40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0xeeb20b40
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
|
|
vcvtb(CurrentCond(),
|
|
F64,
|
|
F16,
|
|
DRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xeeb20bc0
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; T1
|
|
vcvtt(CurrentCond(),
|
|
F64,
|
|
F16,
|
|
DRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0xeeb30b40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
|
|
vcvtb(CurrentCond(),
|
|
F16,
|
|
F64,
|
|
SRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0xeeb30bc0
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; T1
|
|
vcvtt(CurrentCond(),
|
|
F16,
|
|
F64,
|
|
SRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00040000: {
|
|
// 0xeeb40b40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0xeeb40b40
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
|
|
vcmp(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xeeb40bc0
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
|
|
vcmpe(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0xeeb50b40
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
// VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
|
|
vcmp(CurrentCond(), F64, DRegister(rd), 0.0);
|
|
if (((instr & 0xffbf0fff) != 0xeeb50b40)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0xeeb50bc0
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
// VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; T2
|
|
vcmpe(CurrentCond(), F64, DRegister(rd), 0.0);
|
|
if (((instr & 0xffbf0fff) != 0xeeb50bc0)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00060000: {
|
|
// 0xeeb60b40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0xeeb60b40
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTR{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
|
|
vrintr(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xeeb60bc0
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTZ{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
|
|
vrintz(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0xeeb70b40
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTX{<c>}{<q>}.F64 <Dd>, <Dm> ; T1
|
|
vrintx(CurrentCond(),
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0xeeb70bc0
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; T1
|
|
vcvt(CurrentCond(),
|
|
F32,
|
|
F64,
|
|
SRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00080000: {
|
|
// 0xeeb80b40
|
|
if ((instr & 0x00010000) == 0x00000000) {
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; T1
|
|
vcvt(CurrentCond(),
|
|
F64,
|
|
dt,
|
|
DRegister(rd),
|
|
SRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000a0000: {
|
|
// 0xeeba0b40
|
|
DataType dt = Dt_U_sx_1_Decode(((instr >> 7) & 0x1) |
|
|
((instr >> 15) & 0x2));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned offset = 32;
|
|
if (dt.Is(S16) || dt.Is(U16)) {
|
|
offset = 16;
|
|
}
|
|
uint32_t fbits = offset - (((instr >> 5) & 0x1) |
|
|
((instr << 1) & 0x1e));
|
|
// VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; T1
|
|
vcvt(CurrentCond(),
|
|
F64,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rd),
|
|
fbits);
|
|
break;
|
|
}
|
|
case 0x000c0000: {
|
|
// 0xeebc0b40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0xeebc0b40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
|
|
vcvtr(CurrentCond(),
|
|
U32,
|
|
F64,
|
|
SRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xeebc0bc0
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; T1
|
|
vcvt(CurrentCond(),
|
|
U32,
|
|
F64,
|
|
SRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0xeebd0b40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
|
|
vcvtr(CurrentCond(),
|
|
S32,
|
|
F64,
|
|
SRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0xeebd0bc0
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; T1
|
|
vcvt(CurrentCond(),
|
|
S32,
|
|
F64,
|
|
SRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x000e0000: {
|
|
// 0xeebe0b40
|
|
DataType dt = Dt_U_sx_1_Decode(((instr >> 7) & 0x1) |
|
|
((instr >> 15) & 0x2));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned offset = 32;
|
|
if (dt.Is(S16) || dt.Is(U16)) {
|
|
offset = 16;
|
|
}
|
|
uint32_t fbits = offset - (((instr >> 5) & 0x1) |
|
|
((instr << 1) & 0x1e));
|
|
// VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; T1
|
|
vcvt(CurrentCond(),
|
|
dt,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rd),
|
|
fbits);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x10000a00: {
|
|
// 0xfe000a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VSELEQ.F32 <Sd>, <Sn>, <Sm> ; T1
|
|
vseleq(F32, SRegister(rd), SRegister(rn), SRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10000b00: {
|
|
// 0xfe000b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSELEQ.F64 <Dd>, <Dn>, <Dm> ; T1
|
|
vseleq(F64, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10100a00: {
|
|
// 0xfe100a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VSELVS.F32 <Sd>, <Sn>, <Sm> ; T1
|
|
vselvs(F32, SRegister(rd), SRegister(rn), SRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10100b00: {
|
|
// 0xfe100b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSELVS.F64 <Dd>, <Dn>, <Dm> ; T1
|
|
vselvs(F64, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10200a00: {
|
|
// 0xfe200a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VSELGE.F32 <Sd>, <Sn>, <Sm> ; T1
|
|
vselge(F32, SRegister(rd), SRegister(rn), SRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10200b00: {
|
|
// 0xfe200b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSELGE.F64 <Dd>, <Dn>, <Dm> ; T1
|
|
vselge(F64, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10300a00: {
|
|
// 0xfe300a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VSELGT.F32 <Sd>, <Sn>, <Sm> ; T1
|
|
vselgt(F32, SRegister(rd), SRegister(rn), SRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10300b00: {
|
|
// 0xfe300b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSELGT.F64 <Dd>, <Dn>, <Dm> ; T1
|
|
vselgt(F64, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10800a00: {
|
|
// 0xfe800a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
|
|
vmaxnm(F32, SRegister(rd), SRegister(rn), SRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10800a40: {
|
|
// 0xfe800a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; T2
|
|
vminnm(F32, SRegister(rd), SRegister(rn), SRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10800b00: {
|
|
// 0xfe800b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
|
|
vmaxnm(F64, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10800b40: {
|
|
// 0xfe800b40
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; T2
|
|
vminnm(F64, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10b00a40: {
|
|
// 0xfeb00a40
|
|
switch (instr & 0x000f0000) {
|
|
case 0x00080000: {
|
|
// 0xfeb80a40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VRINTA{<q>}.F32 <Sd>, <Sm> ; T1
|
|
vrinta(F32, SRegister(rd), SRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00090000: {
|
|
// 0xfeb90a40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VRINTN{<q>}.F32 <Sd>, <Sm> ; T1
|
|
vrintn(F32, SRegister(rd), SRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000a0000: {
|
|
// 0xfeba0a40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VRINTP{<q>}.F32 <Sd>, <Sm> ; T1
|
|
vrintp(F32, SRegister(rd), SRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000b0000: {
|
|
// 0xfebb0a40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VRINTM{<q>}.F32 <Sd>, <Sm> ; T1
|
|
vrintm(F32, SRegister(rd), SRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000c0000: {
|
|
// 0xfebc0a40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
|
|
vcvta(dt, F32, SRegister(rd), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000d0000: {
|
|
// 0xfebd0a40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
|
|
vcvtn(dt, F32, SRegister(rd), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000e0000: {
|
|
// 0xfebe0a40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
|
|
vcvtp(dt, F32, SRegister(rd), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000f0000: {
|
|
// 0xfebf0a40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; T1
|
|
vcvtm(dt, F32, SRegister(rd), SRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x10b00b40: {
|
|
// 0xfeb00b40
|
|
switch (instr & 0x000f0000) {
|
|
case 0x00080000: {
|
|
// 0xfeb80b40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTA{<q>}.F64 <Dd>, <Dm> ; T1
|
|
vrinta(F64, DRegister(rd), DRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00090000: {
|
|
// 0xfeb90b40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTN{<q>}.F64 <Dd>, <Dm> ; T1
|
|
vrintn(F64, DRegister(rd), DRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000a0000: {
|
|
// 0xfeba0b40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTP{<q>}.F64 <Dd>, <Dm> ; T1
|
|
vrintp(F64, DRegister(rd), DRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000b0000: {
|
|
// 0xfebb0b40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTM{<q>}.F64 <Dd>, <Dm> ; T1
|
|
vrintm(F64, DRegister(rd), DRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000c0000: {
|
|
// 0xfebc0b40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
|
|
vcvta(dt, F64, SRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000d0000: {
|
|
// 0xfebd0b40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
|
|
vcvtn(dt, F64, SRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000e0000: {
|
|
// 0xfebe0b40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
|
|
vcvtp(dt, F64, SRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000f0000: {
|
|
// 0xfebf0b40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; T1
|
|
vcvtm(dt, F64, SRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000010: {
|
|
// 0xee000010
|
|
switch (instr & 0x10100e00) {
|
|
case 0x00000a00: {
|
|
// 0xee000a10
|
|
switch (instr & 0x00800100) {
|
|
case 0x00000000: {
|
|
// 0xee000a10
|
|
if ((instr & 0x00600000) == 0x00000000) {
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
// VMOV{<c>}{<q>} <Sn>, <Rt> ; T1
|
|
vmov(CurrentCond(), SRegister(rn), Register(rt));
|
|
if (((instr & 0xfff00f7f) != 0xee000a10)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xee000b10
|
|
unsigned lane;
|
|
DataType dt =
|
|
Dt_opc1_opc2_1_Decode(((instr >> 5) & 0x3) |
|
|
((instr >> 19) & 0xc),
|
|
&lane);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 7, 16);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
// VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; T1
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegisterLane(rd, lane),
|
|
Register(rt));
|
|
if (((instr & 0xff900f1f) != 0xee000b10)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xee800a10
|
|
if ((instr & 0x00600000) == 0x00600000) {
|
|
unsigned spec_reg = (instr >> 16) & 0xf;
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
switch (spec_reg) {
|
|
case 0x0:
|
|
case 0x1:
|
|
case 0x8: {
|
|
// VMSR{<c>}{<q>} <spec_reg>, <Rt> ; T1
|
|
vmsr(CurrentCond(),
|
|
SpecialFPRegister(spec_reg),
|
|
Register(rt));
|
|
if (((instr & 0xfff00fff) != 0xeee00a10)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800100: {
|
|
// 0xee800b10
|
|
switch (instr & 0x00200040) {
|
|
case 0x00000000: {
|
|
// 0xee800b10
|
|
DataType dt = Dt_B_E_1_Decode(
|
|
((instr >> 5) & 0x1) | ((instr >> 21) & 0x2));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 7, 16);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
// VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; T1
|
|
vdup(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
Register(rt));
|
|
if (((instr & 0xffb00f5f) != 0xee800b10)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xeea00b10
|
|
DataType dt = Dt_B_E_1_Decode(
|
|
((instr >> 5) & 0x1) | ((instr >> 21) & 0x2));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 7, 16);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
// VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; T1
|
|
vdup(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
Register(rt));
|
|
if (((instr & 0xffb00f5f) != 0xeea00b10)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000e00: {
|
|
// 0xee000e10
|
|
UnimplementedT32_32("MCR", instr);
|
|
break;
|
|
}
|
|
case 0x00100a00: {
|
|
// 0xee100a10
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xee100a10
|
|
switch (instr & 0x00e00000) {
|
|
case 0x00000000: {
|
|
// 0xee100a10
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
// VMOV{<c>}{<q>} <Rt>, <Sn> ; T1
|
|
vmov(CurrentCond(), Register(rt), SRegister(rn));
|
|
if (((instr & 0xfff00f7f) != 0xee100a10)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00e00000: {
|
|
// 0xeef00a10
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned spec_reg = (instr >> 16) & 0xf;
|
|
switch (spec_reg) {
|
|
case 0x0:
|
|
case 0x1:
|
|
case 0x5:
|
|
case 0x6:
|
|
case 0x7:
|
|
case 0x8: {
|
|
// VMRS{<c>}{<q>} <Rt>, <spec_reg> ; T1
|
|
vmrs(CurrentCond(),
|
|
RegisterOrAPSR_nzcv(rt),
|
|
SpecialFPRegister(spec_reg));
|
|
if (((instr & 0xfff00fff) != 0xeef00a10)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xee100b10
|
|
unsigned lane;
|
|
DataType dt =
|
|
Dt_U_opc1_opc2_1_Decode(((instr >> 5) & 0x3) |
|
|
((instr >> 19) &
|
|
0xc) |
|
|
((instr >> 19) &
|
|
0x10),
|
|
&lane);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
// VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; T1
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
Register(rt),
|
|
DRegisterLane(rn, lane));
|
|
if (((instr & 0xff100f1f) != 0xee100b10)) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100e00: {
|
|
// 0xee100e10
|
|
UnimplementedT32_32("MRC", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xef000000
|
|
switch (instr & 0x00800000) {
|
|
case 0x00000000: {
|
|
// 0xef000000
|
|
switch (instr & 0x00000f40) {
|
|
case 0x00000000: {
|
|
// 0xef000000
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vhadd(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xef000040
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vhadd(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef000100
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vrhadd(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000140: {
|
|
// 0xef000140
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vrhadd(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef000200
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vhsub(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000240: {
|
|
// 0xef000240
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vhsub(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xef000300
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vcgt(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000340: {
|
|
// 0xef000340
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vcgt(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xef000400
|
|
DataType dt = Dt_U_size_3_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
// VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
|
|
vshl(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
DRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000440: {
|
|
// 0xef000440
|
|
DataType dt = Dt_U_size_3_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
// VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
|
|
vshl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
QRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xef000500
|
|
DataType dt = Dt_U_size_3_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
// VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
|
|
vrshl(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
DRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000540: {
|
|
// 0xef000540
|
|
DataType dt = Dt_U_size_3_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
// VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
|
|
vrshl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
QRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xef000600
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vmax(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000640: {
|
|
// 0xef000640
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vmax(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xef000700
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vabd(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000740: {
|
|
// 0xef000740
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vabd(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xef000800
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef000800
|
|
DataType dt =
|
|
Dt_size_2_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vadd(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000800
|
|
DataType dt =
|
|
Dt_size_2_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vsub(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000840: {
|
|
// 0xef000840
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef000840
|
|
DataType dt =
|
|
Dt_size_2_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vadd(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000840
|
|
DataType dt =
|
|
Dt_size_2_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vsub(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xef000900
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef000900
|
|
DataType dt =
|
|
Dt_size_10_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vmla(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000900
|
|
DataType dt =
|
|
Dt_size_10_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vmls(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000940: {
|
|
// 0xef000940
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef000940
|
|
DataType dt =
|
|
Dt_size_10_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vmla(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000940
|
|
DataType dt =
|
|
Dt_size_10_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vmls(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xef000a00
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vpmax(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000b00: {
|
|
// 0xef000b00
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef000b00
|
|
DataType dt =
|
|
Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vqdmulh(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000b00
|
|
DataType dt =
|
|
Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vqrdmulh(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000b40: {
|
|
// 0xef000b40
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef000b40
|
|
DataType dt =
|
|
Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vqdmulh(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000b40
|
|
DataType dt =
|
|
Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vqrdmulh(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000c40: {
|
|
// 0xef000c40
|
|
switch (instr & 0x10300000) {
|
|
case 0x00000000: {
|
|
// 0xef000c40
|
|
UnimplementedT32_32("SHA1C", instr);
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xef100c40
|
|
UnimplementedT32_32("SHA1P", instr);
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xef200c40
|
|
UnimplementedT32_32("SHA1M", instr);
|
|
break;
|
|
}
|
|
case 0x00300000: {
|
|
// 0xef300c40
|
|
UnimplementedT32_32("SHA1SU0", instr);
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000c40
|
|
UnimplementedT32_32("SHA256H", instr);
|
|
break;
|
|
}
|
|
case 0x10100000: {
|
|
// 0xff100c40
|
|
UnimplementedT32_32("SHA256H2", instr);
|
|
break;
|
|
}
|
|
case 0x10200000: {
|
|
// 0xff200c40
|
|
UnimplementedT32_32("SHA256SU1", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xef000d00
|
|
switch (instr & 0x10300000) {
|
|
case 0x00000000: {
|
|
// 0xef000d00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
|
|
vadd(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xef200d00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
|
|
vsub(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000d00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
|
|
vpadd(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10200000: {
|
|
// 0xff200d00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
|
|
vabd(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000d40: {
|
|
// 0xef000d40
|
|
switch (instr & 0x10300000) {
|
|
case 0x00000000: {
|
|
// 0xef000d40
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
|
|
vadd(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xef200d40
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
|
|
vsub(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10200000: {
|
|
// 0xff200d40
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
|
|
vabd(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000e00: {
|
|
// 0xef000e00
|
|
switch (instr & 0x10200000) {
|
|
case 0x00000000: {
|
|
// 0xef000e00
|
|
DataType dt = Dt_sz_1_Decode((instr >> 20) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T2
|
|
vceq(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000e00
|
|
if ((instr & 0x00100000) == 0x00000000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
|
|
vcge(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10200000: {
|
|
// 0xff200e00
|
|
if ((instr & 0x00100000) == 0x00000000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T2
|
|
vcgt(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000e40: {
|
|
// 0xef000e40
|
|
switch (instr & 0x10200000) {
|
|
case 0x00000000: {
|
|
// 0xef000e40
|
|
DataType dt = Dt_sz_1_Decode((instr >> 20) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T2
|
|
vceq(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000e40
|
|
if ((instr & 0x00100000) == 0x00000000) {
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
|
|
vcge(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10200000: {
|
|
// 0xff200e40
|
|
if ((instr & 0x00100000) == 0x00000000) {
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T2
|
|
vcgt(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000f00: {
|
|
// 0xef000f00
|
|
switch (instr & 0x10300000) {
|
|
case 0x00000000: {
|
|
// 0xef000f00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
|
|
vmax(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xef200f00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
|
|
vmin(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000f00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
|
|
vpmax(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10200000: {
|
|
// 0xff200f00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
|
|
vpmin(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000f40: {
|
|
// 0xef000f40
|
|
switch (instr & 0x10300000) {
|
|
case 0x00000000: {
|
|
// 0xef000f40
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
|
|
vmax(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xef200f40
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
|
|
vmin(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xef800000
|
|
switch (instr & 0x00300000) {
|
|
case 0x00300000: {
|
|
// 0xefb00000
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xefb00000
|
|
switch (instr & 0x00000040) {
|
|
case 0x00000000: {
|
|
// 0xefb00000
|
|
if (((instr & 0x800) == 0x800)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm = (instr >> 8) & 0xf;
|
|
// VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vext(CurrentCond(),
|
|
Untyped8,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xefb00040
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm = (instr >> 8) & 0xf;
|
|
// VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vext(CurrentCond(),
|
|
Untyped8,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xffb00000
|
|
switch (instr & 0x00000800) {
|
|
case 0x00000000: {
|
|
// 0xffb00000
|
|
switch (instr & 0x00030200) {
|
|
case 0x00000000: {
|
|
// 0xffb00000
|
|
switch (instr & 0x000005c0) {
|
|
case 0x00000000: {
|
|
// 0xffb00000
|
|
DataType dt = Dt_size_7_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vrev64(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xffb00040
|
|
DataType dt = Dt_size_7_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vrev64(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xffb00080
|
|
DataType dt = Dt_size_15_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vrev32(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000000c0: {
|
|
// 0xffb000c0
|
|
DataType dt = Dt_size_15_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vrev32(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xffb00100
|
|
DataType dt = Dt_size_1_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vrev16(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000140: {
|
|
// 0xffb00140
|
|
DataType dt = Dt_size_1_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vrev16(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xffb00400
|
|
DataType dt = Dt_size_5_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
|
|
vcls(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000440: {
|
|
// 0xffb00440
|
|
DataType dt = Dt_size_5_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
|
|
vcls(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000480: {
|
|
// 0xffb00480
|
|
DataType dt = Dt_size_4_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
|
|
vclz(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000004c0: {
|
|
// 0xffb004c0
|
|
DataType dt = Dt_size_4_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
|
|
vclz(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xffb00500
|
|
if ((instr & 0x000c0000) ==
|
|
0x00000000) {
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; T1
|
|
vcnt(CurrentCond(),
|
|
Untyped8,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000540: {
|
|
// 0xffb00540
|
|
if ((instr & 0x000c0000) ==
|
|
0x00000000) {
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; T1
|
|
vcnt(CurrentCond(),
|
|
Untyped8,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000580: {
|
|
// 0xffb00580
|
|
if ((instr & 0x000c0000) ==
|
|
0x00000000) {
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000005c0: {
|
|
// 0xffb005c0
|
|
if ((instr & 0x000c0000) ==
|
|
0x00000000) {
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xffb00200
|
|
switch (instr & 0x00000540) {
|
|
case 0x00000000: {
|
|
// 0xffb00200
|
|
DataType dt = Dt_op_size_2_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 5) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vpaddl(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xffb00240
|
|
DataType dt = Dt_op_size_2_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 5) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vpaddl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xffb00300
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xffb00300
|
|
UnimplementedT32_32("AESE",
|
|
instr);
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xffb00380
|
|
UnimplementedT32_32("AESMC",
|
|
instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000140: {
|
|
// 0xffb00340
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xffb00340
|
|
UnimplementedT32_32("AESD",
|
|
instr);
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xffb003c0
|
|
UnimplementedT32_32("AESIMC",
|
|
instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xffb00600
|
|
DataType dt = Dt_op_size_2_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 5) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vpadal(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000440: {
|
|
// 0xffb00640
|
|
DataType dt = Dt_op_size_2_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 5) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vpadal(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xffb00700
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xffb00700
|
|
DataType dt = Dt_size_5_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vqabs(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xffb00780
|
|
DataType dt = Dt_size_5_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vqneg(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000540: {
|
|
// 0xffb00740
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xffb00740
|
|
DataType dt = Dt_size_5_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vqabs(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xffb007c0
|
|
DataType dt = Dt_size_5_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vqneg(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0xffb10000
|
|
switch (instr & 0x000001c0) {
|
|
case 0x00000000: {
|
|
// 0xffb10000
|
|
DataType dt = Dt_F_size_1_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 NOLINT(whitespace/line_length)
|
|
vcgt(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xffb10040
|
|
DataType dt = Dt_F_size_1_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 NOLINT(whitespace/line_length)
|
|
vcgt(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xffb10080
|
|
DataType dt = Dt_F_size_1_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 NOLINT(whitespace/line_length)
|
|
vcge(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x000000c0: {
|
|
// 0xffb100c0
|
|
DataType dt = Dt_F_size_1_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 NOLINT(whitespace/line_length)
|
|
vcge(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xffb10100
|
|
DataType dt = Dt_F_size_2_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 NOLINT(whitespace/line_length)
|
|
vceq(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x00000140: {
|
|
// 0xffb10140
|
|
DataType dt = Dt_F_size_2_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 NOLINT(whitespace/line_length)
|
|
vceq(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x00000180: {
|
|
// 0xffb10180
|
|
DataType dt = Dt_F_size_1_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 NOLINT(whitespace/line_length)
|
|
vcle(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x000001c0: {
|
|
// 0xffb101c0
|
|
DataType dt = Dt_F_size_1_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 NOLINT(whitespace/line_length)
|
|
vcle(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00010200: {
|
|
// 0xffb10200
|
|
switch (instr & 0x000001c0) {
|
|
case 0x00000000: {
|
|
// 0xffb10200
|
|
DataType dt = Dt_F_size_1_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; T1 NOLINT(whitespace/line_length)
|
|
vclt(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xffb10240
|
|
DataType dt = Dt_F_size_1_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; T1 NOLINT(whitespace/line_length)
|
|
vclt(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x000000c0: {
|
|
// 0xffb102c0
|
|
if ((instr & 0x000c0400) ==
|
|
0x00080000) {
|
|
UnimplementedT32_32("SHA1H", instr);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xffb10300
|
|
DataType dt = Dt_F_size_1_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
|
|
vabs(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000140: {
|
|
// 0xffb10340
|
|
DataType dt = Dt_F_size_1_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
|
|
vabs(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000180: {
|
|
// 0xffb10380
|
|
DataType dt = Dt_F_size_1_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
|
|
vneg(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000001c0: {
|
|
// 0xffb103c0
|
|
DataType dt = Dt_F_size_1_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
|
|
vneg(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00020000: {
|
|
// 0xffb20000
|
|
switch (instr & 0x000005c0) {
|
|
case 0x00000000: {
|
|
// 0xffb20000
|
|
if ((instr & 0x000c0000) ==
|
|
0x00000000) {
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vswp(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xffb20040
|
|
if ((instr & 0x000c0000) ==
|
|
0x00000000) {
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vswp(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xffb20080
|
|
DataType dt = Dt_size_7_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
|
|
vtrn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000000c0: {
|
|
// 0xffb200c0
|
|
DataType dt = Dt_size_7_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
|
|
vtrn(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xffb20100
|
|
DataType dt = Dt_size_15_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
|
|
vuzp(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000140: {
|
|
// 0xffb20140
|
|
DataType dt = Dt_size_7_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
|
|
vuzp(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000180: {
|
|
// 0xffb20180
|
|
DataType dt = Dt_size_15_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1
|
|
vzip(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000001c0: {
|
|
// 0xffb201c0
|
|
DataType dt = Dt_size_7_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1
|
|
vzip(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xffb20400
|
|
DataType dt = Dt_size_16_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VRINTN{<q>}.<dt> <Dd>, <Dm> ; T1
|
|
vrintn(dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000440: {
|
|
// 0xffb20440
|
|
DataType dt = Dt_size_16_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VRINTN{<q>}.<dt> <Qd>, <Qm> ; T1
|
|
vrintn(dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000480: {
|
|
// 0xffb20480
|
|
DataType dt = Dt_size_16_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VRINTX{<q>}.<dt> <Dd>, <Dm> ; T1
|
|
vrintx(Condition::None(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000004c0: {
|
|
// 0xffb204c0
|
|
DataType dt = Dt_size_16_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VRINTX{<q>}.<dt> <Qd>, <Qm> ; T1
|
|
vrintx(dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xffb20500
|
|
DataType dt = Dt_size_16_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VRINTA{<q>}.<dt> <Dd>, <Dm> ; T1
|
|
vrinta(dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000540: {
|
|
// 0xffb20540
|
|
DataType dt = Dt_size_16_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VRINTA{<q>}.<dt> <Qd>, <Qm> ; T1
|
|
vrinta(dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000580: {
|
|
// 0xffb20580
|
|
DataType dt = Dt_size_16_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VRINTZ{<q>}.<dt> <Dd>, <Dm> ; T1
|
|
vrintz(Condition::None(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000005c0: {
|
|
// 0xffb205c0
|
|
DataType dt = Dt_size_16_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VRINTZ{<q>}.<dt> <Qd>, <Qm> ; T1
|
|
vrintz(dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00020200: {
|
|
// 0xffb20200
|
|
switch (instr & 0x00000580) {
|
|
case 0x00000000: {
|
|
// 0xffb20200
|
|
switch (instr & 0x00000040) {
|
|
case 0x00000000: {
|
|
// 0xffb20200
|
|
DataType dt = Dt_size_3_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vmovn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xffb20240
|
|
DataType dt = Dt_size_14_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vqmovun(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xffb20280
|
|
DataType dt = Dt_op_size_3_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 4) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vqmovn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xffb20300
|
|
if ((instr & 0x00000040) ==
|
|
0x00000000) {
|
|
DataType dt = Dt_size_17_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm = dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T2 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000180: {
|
|
// 0xffb20380
|
|
switch (instr & 0x000c0040) {
|
|
case 0x00080000: {
|
|
// 0xffba0380
|
|
UnimplementedT32_32("SHA1SU1",
|
|
instr);
|
|
break;
|
|
}
|
|
case 0x00080040: {
|
|
// 0xffba03c0
|
|
UnimplementedT32_32("SHA256SU0",
|
|
instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xffb20600
|
|
if ((instr & 0x000c0040) ==
|
|
0x00040000) {
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vcvt(CurrentCond(),
|
|
F16,
|
|
F32,
|
|
DRegister(rd),
|
|
QRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000480: {
|
|
// 0xffb20680
|
|
switch (instr & 0x00000040) {
|
|
case 0x00000000: {
|
|
// 0xffb20680
|
|
DataType dt = Dt_size_16_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VRINTM{<q>}.<dt> <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vrintm(dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xffb206c0
|
|
DataType dt = Dt_size_16_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VRINTM{<q>}.<dt> <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vrintm(dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xffb20700
|
|
if ((instr & 0x000c0040) ==
|
|
0x00040000) {
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vcvt(CurrentCond(),
|
|
F32,
|
|
F16,
|
|
QRegister(rd),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000580: {
|
|
// 0xffb20780
|
|
switch (instr & 0x00000040) {
|
|
case 0x00000000: {
|
|
// 0xffb20780
|
|
DataType dt = Dt_size_16_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VRINTP{<q>}.<dt> <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vrintp(dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xffb207c0
|
|
DataType dt = Dt_size_16_Decode(
|
|
(instr >> 18) & 0x3);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VRINTP{<q>}.<dt> <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vrintp(dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00030000: {
|
|
// 0xffb30000
|
|
switch (instr & 0x00000440) {
|
|
case 0x00000000: {
|
|
// 0xffb30000
|
|
switch (instr & 0x000c0100) {
|
|
case 0x00080000: {
|
|
// 0xffbb0000
|
|
DataType dt = Dt_op_3_Decode(
|
|
(instr >> 7) & 0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vcvta(dt,
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00080100: {
|
|
// 0xffbb0100
|
|
DataType dt = Dt_op_3_Decode(
|
|
(instr >> 7) & 0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vcvtn(dt,
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xffb30040
|
|
switch (instr & 0x000c0100) {
|
|
case 0x00080000: {
|
|
// 0xffbb0040
|
|
DataType dt = Dt_op_3_Decode(
|
|
(instr >> 7) & 0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vcvta(dt,
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00080100: {
|
|
// 0xffbb0140
|
|
DataType dt = Dt_op_3_Decode(
|
|
(instr >> 7) & 0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vcvtn(dt,
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xffb30400
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xffb30400
|
|
DataType dt = Dt_F_size_4_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 6) & 0x4));
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vrecpe(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xffb30480
|
|
DataType dt = Dt_F_size_4_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 6) & 0x4));
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vrsqrte(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000440: {
|
|
// 0xffb30440
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xffb30440
|
|
DataType dt = Dt_F_size_4_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 6) & 0x4));
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vrecpe(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xffb304c0
|
|
DataType dt = Dt_F_size_4_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 6) & 0x4));
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vrsqrte(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00030200: {
|
|
// 0xffb30200
|
|
switch (instr & 0x000c0440) {
|
|
case 0x00080000: {
|
|
// 0xffbb0200
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xffbb0200
|
|
DataType dt = Dt_op_3_Decode(
|
|
(instr >> 7) & 0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vcvtp(dt,
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xffbb0300
|
|
DataType dt = Dt_op_3_Decode(
|
|
(instr >> 7) & 0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vcvtm(dt,
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00080040: {
|
|
// 0xffbb0240
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xffbb0240
|
|
DataType dt = Dt_op_3_Decode(
|
|
(instr >> 7) & 0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vcvtp(dt,
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xffbb0340
|
|
DataType dt = Dt_op_3_Decode(
|
|
(instr >> 7) & 0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vcvtm(dt,
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00080400: {
|
|
// 0xffbb0600
|
|
DataType dt1 = Dt_op_1_Decode1(
|
|
(instr >> 7) & 0x3);
|
|
if (dt1.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt2 = Dt_op_1_Decode2(
|
|
(instr >> 7) & 0x3);
|
|
if (dt2.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vcvt(CurrentCond(),
|
|
dt1,
|
|
dt2,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00080440: {
|
|
// 0xffbb0640
|
|
DataType dt1 = Dt_op_1_Decode1(
|
|
(instr >> 7) & 0x3);
|
|
if (dt1.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt2 = Dt_op_1_Decode2(
|
|
(instr >> 7) & 0x3);
|
|
if (dt2.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vcvt(CurrentCond(),
|
|
dt1,
|
|
dt2,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xffb00800
|
|
switch (instr & 0x00000440) {
|
|
case 0x00000000: {
|
|
// 0xffb00800
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned first =
|
|
ExtractDRegister(instr, 7, 16);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0x3) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 1;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
break;
|
|
case 0x2:
|
|
length = 3;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vtbl(CurrentCond(),
|
|
Untyped8,
|
|
DRegister(rd),
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xffb00840
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned first =
|
|
ExtractDRegister(instr, 7, 16);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0x3) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 1;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
break;
|
|
case 0x2:
|
|
length = 3;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vtbx(CurrentCond(),
|
|
Untyped8,
|
|
DRegister(rd),
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xffb00c00
|
|
if ((instr & 0x00000380) == 0x00000000) {
|
|
unsigned lane;
|
|
DataType dt =
|
|
Dt_imm4_1_Decode((instr >> 16) &
|
|
0xf,
|
|
&lane);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; T1 NOLINT(whitespace/line_length)
|
|
vdup(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegisterLane(rm, lane));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000440: {
|
|
// 0xffb00c40
|
|
if ((instr & 0x00000380) == 0x00000000) {
|
|
unsigned lane;
|
|
DataType dt =
|
|
Dt_imm4_1_Decode((instr >> 16) &
|
|
0xf,
|
|
&lane);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; T1 NOLINT(whitespace/line_length)
|
|
vdup(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegisterLane(rm, lane));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000c40) {
|
|
case 0x00000000: {
|
|
// 0xef800000
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xef800000
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
|
|
vaddl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800100
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vaddw(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef800200
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
|
|
vsubl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xef800300
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vsubw(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xef800040
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0xef800040
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef800040
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_9_Decode((instr >> 20) & 0x3,
|
|
(instr >> 8) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rn =
|
|
ExtractDRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr,
|
|
dt,
|
|
5,
|
|
0,
|
|
&lane);
|
|
// VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1 NOLINT(whitespace/line_length)
|
|
vmla(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff800040
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_9_Decode((instr >> 20) & 0x3,
|
|
(instr >> 8) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn =
|
|
ExtractQRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr,
|
|
dt,
|
|
5,
|
|
0,
|
|
&lane);
|
|
// VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1 NOLINT(whitespace/line_length)
|
|
vmla(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef800240
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xef800240
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_11_Decode((instr >> 20) & 0x3,
|
|
(instr >> 28) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rn =
|
|
ExtractDRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr,
|
|
dt,
|
|
5,
|
|
0,
|
|
&lane);
|
|
// VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1 NOLINT(whitespace/line_length)
|
|
vmlal(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800340
|
|
if ((instr & 0x10000000) == 0x00000000) {
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_13_Decode(
|
|
(instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rn =
|
|
ExtractDRegister(instr, 7, 16);
|
|
uint32_t mvm = (instr & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
uint32_t shift = 4;
|
|
if (dt.Is(S16)) {
|
|
shift = 3;
|
|
}
|
|
uint32_t vm = mvm & ((1 << shift) - 1);
|
|
uint32_t index = mvm >> shift;
|
|
// VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2 NOLINT(whitespace/line_length)
|
|
vqdmlal(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(vm),
|
|
index);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xef800400
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xef800400
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef800400
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_3_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn =
|
|
ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vaddhn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff800400
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_3_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn =
|
|
ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vraddhn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800500
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
|
|
vabal(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef800600
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef800600
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_3_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn =
|
|
ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vsubhn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff800600
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_3_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn =
|
|
ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
// VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; T1 NOLINT(whitespace/line_length)
|
|
vrsubhn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xef800700
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
|
|
vabdl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000440: {
|
|
// 0xef800440
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0xef800440
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef800440
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_9_Decode((instr >> 20) & 0x3,
|
|
(instr >> 8) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rn =
|
|
ExtractDRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr,
|
|
dt,
|
|
5,
|
|
0,
|
|
&lane);
|
|
// VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; T1 NOLINT(whitespace/line_length)
|
|
vmls(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff800440
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_9_Decode((instr >> 20) & 0x3,
|
|
(instr >> 8) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn =
|
|
ExtractQRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr,
|
|
dt,
|
|
5,
|
|
0,
|
|
&lane);
|
|
// VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; T1 NOLINT(whitespace/line_length)
|
|
vmls(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef800640
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xef800640
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_11_Decode((instr >> 20) & 0x3,
|
|
(instr >> 28) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rn =
|
|
ExtractDRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr,
|
|
dt,
|
|
5,
|
|
0,
|
|
&lane);
|
|
// VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; T1 NOLINT(whitespace/line_length)
|
|
vmlsl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800740
|
|
if ((instr & 0x10000000) == 0x00000000) {
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_13_Decode(
|
|
(instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rn =
|
|
ExtractDRegister(instr, 7, 16);
|
|
uint32_t mvm = (instr & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
uint32_t shift = 4;
|
|
if (dt.Is(S16)) {
|
|
shift = 3;
|
|
}
|
|
uint32_t vm = mvm & ((1 << shift) - 1);
|
|
uint32_t index = mvm >> shift;
|
|
// VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T2 NOLINT(whitespace/line_length)
|
|
vqdmlsl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(vm),
|
|
index);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xef800800
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xef800800
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_12_Decode((instr >> 20) & 0x3,
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vmlal(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800900
|
|
if ((instr & 0x10000000) == 0x00000000) {
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rn =
|
|
ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vqdmlal(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef800a00
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_12_Decode((instr >> 20) & 0x3,
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vmlsl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xef800b00
|
|
if ((instr & 0x10000000) == 0x00000000) {
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rn =
|
|
ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vqdmlsl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000840: {
|
|
// 0xef800840
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0xef800840
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef800840
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_F_size_3_Decode(
|
|
((instr >> 20) & 0x3) |
|
|
((instr >> 6) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rn =
|
|
ExtractDRegister(instr, 7, 16);
|
|
uint32_t mvm =
|
|
(instr & 0xf) | ((instr >> 1) & 0x10);
|
|
uint32_t shift = 4;
|
|
if (dt.Is(I16)) {
|
|
shift = 3;
|
|
}
|
|
uint32_t vm = mvm & ((1 << shift) - 1);
|
|
uint32_t index = mvm >> shift;
|
|
// VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; T1 NOLINT(whitespace/line_length)
|
|
vmul(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(vm),
|
|
index);
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff800840
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_F_size_3_Decode(
|
|
((instr >> 20) & 0x3) |
|
|
((instr >> 6) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn =
|
|
ExtractQRegister(instr, 7, 16);
|
|
uint32_t mvm =
|
|
(instr & 0xf) | ((instr >> 1) & 0x10);
|
|
uint32_t shift = 4;
|
|
if (dt.Is(I16)) {
|
|
shift = 3;
|
|
}
|
|
uint32_t vm = mvm & ((1 << shift) - 1);
|
|
uint32_t index = mvm >> shift;
|
|
// VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; T1 NOLINT(whitespace/line_length)
|
|
vmul(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
DRegister(vm),
|
|
index);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef800a40
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xef800a40
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_U_size_2_Decode(
|
|
((instr >> 20) & 0x3) |
|
|
((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rn =
|
|
ExtractDRegister(instr, 7, 16);
|
|
uint32_t mvm =
|
|
(instr & 0xf) | ((instr >> 1) & 0x10);
|
|
uint32_t shift = 4;
|
|
if (dt.Is(S16) || dt.Is(U16)) {
|
|
shift = 3;
|
|
}
|
|
uint32_t vm = mvm & ((1 << shift) - 1);
|
|
uint32_t index = mvm >> shift;
|
|
// VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; T1 NOLINT(whitespace/line_length)
|
|
vmull(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(vm),
|
|
index);
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800b40
|
|
if ((instr & 0x10000000) == 0x00000000) {
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_13_Decode(
|
|
(instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rn =
|
|
ExtractDRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr,
|
|
dt,
|
|
5,
|
|
0,
|
|
&lane);
|
|
// VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; T2 NOLINT(whitespace/line_length)
|
|
vqdmull(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xef800c00
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xef800c00
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_op_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) |
|
|
((instr >> 26) & 0x4) |
|
|
((instr >> 6) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1
|
|
vmull(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800d00
|
|
if ((instr & 0x10000200) == 0x00000000) {
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rn =
|
|
ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vqdmull(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000c40: {
|
|
// 0xef800c40
|
|
switch (instr & 0x10000300) {
|
|
case 0x00000000: {
|
|
// 0xef800c40
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm = ExtractDRegisterAndLane(instr,
|
|
dt,
|
|
5,
|
|
0,
|
|
&lane);
|
|
// VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2 NOLINT(whitespace/line_length)
|
|
vqdmulh(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800d40
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm = ExtractDRegisterAndLane(instr,
|
|
dt,
|
|
5,
|
|
0,
|
|
&lane);
|
|
// VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; T2 NOLINT(whitespace/line_length)
|
|
vqrdmulh(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff800c40
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm = ExtractDRegisterAndLane(instr,
|
|
dt,
|
|
5,
|
|
0,
|
|
&lane);
|
|
// VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2 NOLINT(whitespace/line_length)
|
|
vqdmulh(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
case 0x10000100: {
|
|
// 0xff800d40
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm = ExtractDRegisterAndLane(instr,
|
|
dt,
|
|
5,
|
|
0,
|
|
&lane);
|
|
// VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; T2 NOLINT(whitespace/line_length)
|
|
vqrdmulh(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000010: {
|
|
// 0xef000010
|
|
switch (instr & 0x00800040) {
|
|
case 0x00000000: {
|
|
// 0xef000010
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000000: {
|
|
// 0xef000010
|
|
DataType dt = Dt_U_size_3_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vqadd(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef000110
|
|
switch (instr & 0x10300000) {
|
|
case 0x00000000: {
|
|
// 0xef000110
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
|
|
vand(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xef100110
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
|
|
vbic(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xef200110
|
|
if (((instr & 0x00000040) == 0x00000000) &&
|
|
((((Uint32((instr >> 7)) & Uint32(0x1))
|
|
<< 4) |
|
|
(Uint32((instr >> 16)) & Uint32(0xf))) ==
|
|
(((Uint32((instr >> 5)) & Uint32(0x1))
|
|
<< 4) |
|
|
(Uint32(instr) & Uint32(0xf))))) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 7, 16);
|
|
// VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; T1
|
|
vmov(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
|
|
vorr(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00300000: {
|
|
// 0xef300110
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
|
|
vorn(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000110
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
|
|
veor(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10100000: {
|
|
// 0xff100110
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
|
|
vbsl(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10200000: {
|
|
// 0xff200110
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
|
|
vbit(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10300000: {
|
|
// 0xff300110
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; T1
|
|
vbif(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef000210
|
|
DataType dt = Dt_U_size_3_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vqsub(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xef000310
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vcge(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xef000410
|
|
DataType dt = Dt_U_size_3_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
// VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
|
|
vqshl(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
DRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xef000510
|
|
DataType dt = Dt_U_size_3_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
// VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; T1
|
|
vqrshl(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
DRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xef000610
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vmin(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xef000710
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; T1
|
|
vaba(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xef000810
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef000810
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vtst(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000810
|
|
DataType dt =
|
|
Dt_size_4_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vceq(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xef000910
|
|
DataType dt = Dt_op_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vmul(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xef000a10
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vpmin(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000b00: {
|
|
// 0xef000b10
|
|
if ((instr & 0x10000000) == 0x00000000) {
|
|
DataType dt = Dt_size_4_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; T1
|
|
vpadd(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xef000c10
|
|
switch (instr & 0x10300000) {
|
|
case 0x00000000: {
|
|
// 0xef000c10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
|
|
vfma(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xef200c10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
|
|
vfms(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xef000d10
|
|
switch (instr & 0x10300000) {
|
|
case 0x00000000: {
|
|
// 0xef000d10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
|
|
vmla(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xef200d10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
|
|
vmls(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000d10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
|
|
vmul(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000e00: {
|
|
// 0xef000e10
|
|
switch (instr & 0x10300000) {
|
|
case 0x10000000: {
|
|
// 0xff000e10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
|
|
vacge(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10200000: {
|
|
// 0xff200e10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
|
|
vacgt(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000f00: {
|
|
// 0xef000f10
|
|
switch (instr & 0x10300000) {
|
|
case 0x00000000: {
|
|
// 0xef000f10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
|
|
vrecps(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xef200f10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; T1
|
|
vrsqrts(CurrentCond(),
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000f10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
|
|
vmaxnm(F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10200000: {
|
|
// 0xff200f10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; T1
|
|
vminnm(F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xef000050
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000000: {
|
|
// 0xef000050
|
|
DataType dt = Dt_U_size_3_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vqadd(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef000150
|
|
switch (instr & 0x10300000) {
|
|
case 0x00000000: {
|
|
// 0xef000150
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
|
|
vand(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xef100150
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
|
|
vbic(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xef200150
|
|
if (((instr & 0x00000040) == 0x00000040) &&
|
|
((((Uint32((instr >> 7)) & Uint32(0x1))
|
|
<< 4) |
|
|
(Uint32((instr >> 16)) & Uint32(0xf))) ==
|
|
(((Uint32((instr >> 5)) & Uint32(0x1))
|
|
<< 4) |
|
|
(Uint32(instr) & Uint32(0xf))))) {
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 7, 16);
|
|
// VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; T1
|
|
vmov(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
|
|
vorr(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00300000: {
|
|
// 0xef300150
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
|
|
vorn(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000150
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
|
|
veor(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10100000: {
|
|
// 0xff100150
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
|
|
vbsl(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10200000: {
|
|
// 0xff200150
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
|
|
vbit(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10300000: {
|
|
// 0xff300150
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; T1
|
|
vbif(CurrentCond(),
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef000250
|
|
DataType dt = Dt_U_size_3_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vqsub(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xef000350
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vcge(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xef000450
|
|
DataType dt = Dt_U_size_3_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
// VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
|
|
vqshl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
QRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xef000550
|
|
DataType dt = Dt_U_size_3_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
// VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; T1
|
|
vqrshl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
QRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xef000650
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vmin(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xef000750
|
|
DataType dt = Dt_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; T1
|
|
vaba(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xef000850
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef000850
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vtst(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000850
|
|
DataType dt =
|
|
Dt_size_4_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vceq(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xef000950
|
|
DataType dt = Dt_op_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 26) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; T1
|
|
vmul(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xef000c50
|
|
switch (instr & 0x10300000) {
|
|
case 0x00000000: {
|
|
// 0xef000c50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
|
|
vfma(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xef200c50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
|
|
vfms(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xef000d50
|
|
switch (instr & 0x10300000) {
|
|
case 0x00000000: {
|
|
// 0xef000d50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
|
|
vmla(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xef200d50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
|
|
vmls(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000d50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
|
|
vmul(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000e00: {
|
|
// 0xef000e50
|
|
switch (instr & 0x10300000) {
|
|
case 0x10000000: {
|
|
// 0xff000e50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
|
|
vacge(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10200000: {
|
|
// 0xff200e50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
|
|
vacgt(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000f00: {
|
|
// 0xef000f50
|
|
switch (instr & 0x10300000) {
|
|
case 0x00000000: {
|
|
// 0xef000f50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
|
|
vrecps(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xef200f50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; T1
|
|
vrsqrts(CurrentCond(),
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff000f50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
|
|
vmaxnm(F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x10200000: {
|
|
// 0xff200f50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; T1
|
|
vminnm(F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
if (InITBlock()) {
|
|
UnpredictableT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xef800010
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000000: {
|
|
// 0xef800010
|
|
switch (instr & 0x00380080) {
|
|
case 0x00000000: {
|
|
// 0xef800010
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xef800010
|
|
switch (instr & 0x00000200) {
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xef800030
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800110
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000000: {
|
|
// 0xef800110
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVorr::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVorr::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vorr(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xef800130
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVbic::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVbic::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vbic(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xef800010
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) &
|
|
0x8),
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64
|
|
: (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshr(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800110
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) &
|
|
0x8),
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64
|
|
: (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vsra(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef800210
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) &
|
|
0x8),
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64
|
|
: (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vrshr(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xef800310
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) &
|
|
0x8),
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64
|
|
: (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vrsra(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xef800410
|
|
switch (instr & 0x00380080) {
|
|
case 0x00000000: {
|
|
// 0xef800410
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xef800410
|
|
switch (instr & 0x00000200) {
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xef800430
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800510
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000000: {
|
|
// 0xef800510
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVorr::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVorr::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vorr(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xef800530
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVbic::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVbic::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vbic(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xef800410
|
|
if ((instr & 0x10000000) == 0x10000000) {
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_L_imm6_4_Decode(
|
|
((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64
|
|
: (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vsri(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800510
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef800510
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_L_imm6_3_Decode(
|
|
((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 -
|
|
(dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshl(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff800510
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_L_imm6_4_Decode(
|
|
((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 -
|
|
(dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vsli(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef800610
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_2_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) &
|
|
0x8),
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - (dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqshlu(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xef800710
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) &
|
|
0x8),
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - (dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqshl(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xef800810
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xef800810
|
|
switch (instr & 0x00380000) {
|
|
case 0x00000000: {
|
|
// 0xef800810
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xef800810
|
|
switch (instr & 0x00000200) {
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xef800830
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(cmode,
|
|
(instr &
|
|
0xf) |
|
|
((instr >>
|
|
12) &
|
|
0x70) |
|
|
((instr >>
|
|
21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmov::
|
|
DecodeImmediate(cmode,
|
|
(instr &
|
|
0xf) |
|
|
((instr >>
|
|
12) &
|
|
0x70) |
|
|
((instr >>
|
|
21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800910
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000000: {
|
|
// 0xef800910
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVorr::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVorr::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vorr(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xef800930
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVbic::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVbic::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vbic(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00180000: {
|
|
// 0xef980810
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xef980810
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef980810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_imm6_3_Decode(
|
|
(instr >> 19) & 0x7);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshrn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff980810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_2_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 28) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqshrun(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef980910
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_1_Decode((instr >> 19) & 0x7,
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqshrn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef980a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) & 0x7,
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00280000: {
|
|
// 0xefa80810
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xefa80810
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xefa80810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_imm6_3_Decode(
|
|
(instr >> 19) & 0x7);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshrn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xffa80810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_2_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 28) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqshrun(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xefa80910
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_1_Decode((instr >> 19) & 0x7,
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqshrn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xefa80a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) & 0x7,
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00300000: {
|
|
// 0xefb00810
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xefb00810
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xefb00810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_imm6_3_Decode(
|
|
(instr >> 19) & 0x7);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshrn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xffb00810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_2_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 28) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqshrun(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xefb00910
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_1_Decode((instr >> 19) & 0x7,
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqshrn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xefb00a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) & 0x7,
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00380000: {
|
|
// 0xefb80810
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xefb80810
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xefb80810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_imm6_3_Decode(
|
|
(instr >> 19) & 0x7);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshrn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xffb80810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_2_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 28) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqshrun(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xefb80910
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_1_Decode((instr >> 19) & 0x7,
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqshrn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xefb80a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) & 0x7,
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xef800810
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef800810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_imm6_3_Decode(
|
|
(instr >> 19) & 0x7);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshrn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff800810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_2_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 28) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqshrun(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800910
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_1_Decode((instr >> 19) & 0x7,
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqshrn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef800a10
|
|
switch (instr & 0x00070000) {
|
|
case 0x00000000: {
|
|
// 0xef800a10
|
|
switch (instr & 0x003f0000) {
|
|
case 0x00080000: {
|
|
// 0xef880a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x380000) ==
|
|
0x180000) ||
|
|
((instr & 0x380000) ==
|
|
0x280000) ||
|
|
((instr & 0x380000) ==
|
|
0x300000) ||
|
|
((instr & 0x380000) ==
|
|
0x380000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_U_imm3H_1_Decode(
|
|
((instr >> 19) & 0x7) |
|
|
((instr >> 25) & 0x8));
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vmovl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00090000: {
|
|
// 0xef890a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x000a0000: {
|
|
// 0xef8a0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x000b0000: {
|
|
// 0xef8b0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x000c0000: {
|
|
// 0xef8c0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x000d0000: {
|
|
// 0xef8d0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x000e0000: {
|
|
// 0xef8e0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x000f0000: {
|
|
// 0xef8f0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xef900a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x380000) ==
|
|
0x180000) ||
|
|
((instr & 0x380000) ==
|
|
0x280000) ||
|
|
((instr & 0x380000) ==
|
|
0x300000) ||
|
|
((instr & 0x380000) ==
|
|
0x380000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_U_imm3H_1_Decode(
|
|
((instr >> 19) & 0x7) |
|
|
((instr >> 25) & 0x8));
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vmovl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00110000: {
|
|
// 0xef910a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00120000: {
|
|
// 0xef920a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00130000: {
|
|
// 0xef930a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00140000: {
|
|
// 0xef940a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00150000: {
|
|
// 0xef950a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00160000: {
|
|
// 0xef960a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00170000: {
|
|
// 0xef970a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00180000: {
|
|
// 0xef980a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00190000: {
|
|
// 0xef990a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x001a0000: {
|
|
// 0xef9a0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x001b0000: {
|
|
// 0xef9b0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x001c0000: {
|
|
// 0xef9c0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x001d0000: {
|
|
// 0xef9d0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x001e0000: {
|
|
// 0xef9e0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x001f0000: {
|
|
// 0xef9f0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xefa00a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x380000) ==
|
|
0x180000) ||
|
|
((instr & 0x380000) ==
|
|
0x280000) ||
|
|
((instr & 0x380000) ==
|
|
0x300000) ||
|
|
((instr & 0x380000) ==
|
|
0x380000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_U_imm3H_1_Decode(
|
|
((instr >> 19) & 0x7) |
|
|
((instr >> 25) & 0x8));
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; T1 NOLINT(whitespace/line_length)
|
|
vmovl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00210000: {
|
|
// 0xefa10a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00220000: {
|
|
// 0xefa20a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00230000: {
|
|
// 0xefa30a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00240000: {
|
|
// 0xefa40a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00250000: {
|
|
// 0xefa50a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00260000: {
|
|
// 0xefa60a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00270000: {
|
|
// 0xefa70a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00280000: {
|
|
// 0xefa80a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00290000: {
|
|
// 0xefa90a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x002a0000: {
|
|
// 0xefaa0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x002b0000: {
|
|
// 0xefab0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x002c0000: {
|
|
// 0xefac0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x002d0000: {
|
|
// 0xefad0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x002e0000: {
|
|
// 0xefae0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x002f0000: {
|
|
// 0xefaf0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00300000: {
|
|
// 0xefb00a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00310000: {
|
|
// 0xefb10a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00320000: {
|
|
// 0xefb20a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00330000: {
|
|
// 0xefb30a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00340000: {
|
|
// 0xefb40a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00350000: {
|
|
// 0xefb50a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00360000: {
|
|
// 0xefb60a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00370000: {
|
|
// 0xefb70a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00380000: {
|
|
// 0xefb80a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00390000: {
|
|
// 0xefb90a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x003a0000: {
|
|
// 0xefba0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x003b0000: {
|
|
// 0xefbb0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x003c0000: {
|
|
// 0xefbc0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x003d0000: {
|
|
// 0xefbd0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x003e0000: {
|
|
// 0xefbe0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x003f0000: {
|
|
// 0xefbf0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) ==
|
|
0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >>
|
|
19) &
|
|
0x7,
|
|
(instr >>
|
|
28) &
|
|
0x1);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 =
|
|
(instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x100000) ||
|
|
((instr & 0x3f0000) ==
|
|
0x200000)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 28) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshll(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xef800c10
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xef800c10
|
|
switch (instr & 0x00200000) {
|
|
case 0x00000000: {
|
|
// 0xef800c10
|
|
switch (instr & 0x00180000) {
|
|
case 0x00000000: {
|
|
// 0xef800c10
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000200: {
|
|
// 0xef800e10
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xef800f10
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xef800c30
|
|
switch (instr & 0x00000f20) {
|
|
case 0x00000000: {
|
|
// 0xef800c10
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xef800c30
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef800e10
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000220: {
|
|
// 0xef800e30
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xef800c10
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000420: {
|
|
// 0xef800c30
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xef800e10
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000620: {
|
|
// 0xef800e30
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xef800c10
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000820: {
|
|
// 0xef800c30
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xef800e10
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000a20: {
|
|
// 0xef800e30
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xef800c10
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000c20: {
|
|
// 0xef800c30
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xef800d10
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000d20: {
|
|
// 0xef800d30
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000e00: {
|
|
// 0xef800e10
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000e20: {
|
|
// 0xef800e30
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000f00: {
|
|
// 0xef800f10
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr,
|
|
22,
|
|
12);
|
|
DOperand imm = ImmediateVmov::
|
|
DecodeImmediate(cmode,
|
|
(instr &
|
|
0xf) |
|
|
((instr >>
|
|
12) &
|
|
0x70) |
|
|
((instr >>
|
|
21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if ((instr & 0x00000200) == 0x00000200) {
|
|
if (((instr & 0x200000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt1 = Dt_op_U_1_Decode1(
|
|
((instr >> 28) & 0x1) |
|
|
((instr >> 7) & 0x2));
|
|
if (dt1.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt2 = Dt_op_U_1_Decode2(
|
|
((instr >> 28) & 0x1) |
|
|
((instr >> 7) & 0x2));
|
|
if (dt2.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t fbits =
|
|
64 - ((instr >> 16) & 0x3f);
|
|
// VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; T1 NOLINT(whitespace/line_length)
|
|
vcvt(CurrentCond(),
|
|
dt1,
|
|
dt2,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
fbits);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800040: {
|
|
// 0xef800050
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000000: {
|
|
// 0xef800050
|
|
switch (instr & 0x00380080) {
|
|
case 0x00000000: {
|
|
// 0xef800050
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xef800050
|
|
switch (instr & 0x00000200) {
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xef800070
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800150
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000000: {
|
|
// 0xef800150
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVorr::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVorr::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vorr(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xef800170
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVbic::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVbic::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vbic(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xef800050
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) &
|
|
0x8),
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64
|
|
: (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshr(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800150
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) &
|
|
0x8),
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64
|
|
: (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vsra(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef800250
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) &
|
|
0x8),
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64
|
|
: (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vrshr(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xef800350
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) &
|
|
0x8),
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64
|
|
: (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vrsra(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xef800450
|
|
switch (instr & 0x00380080) {
|
|
case 0x00000000: {
|
|
// 0xef800450
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xef800450
|
|
switch (instr & 0x00000200) {
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xef800470
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800550
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000000: {
|
|
// 0xef800550
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVorr::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVorr::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vorr(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xef800570
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVbic::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVbic::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vbic(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xef800450
|
|
if ((instr & 0x10000000) == 0x10000000) {
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_L_imm6_4_Decode(
|
|
((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64
|
|
: (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vsri(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800550
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef800550
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_L_imm6_3_Decode(
|
|
((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 -
|
|
(dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vshl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff800550
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_L_imm6_4_Decode(
|
|
((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 -
|
|
(dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vsli(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef800650
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_2_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) &
|
|
0x8),
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - (dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqshlu(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xef800750
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) &
|
|
0x8),
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - (dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqshl(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xef800850
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xef800850
|
|
switch (instr & 0x00380000) {
|
|
case 0x00000000: {
|
|
// 0xef800850
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xef800850
|
|
switch (instr & 0x00000200) {
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xef800870
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(cmode,
|
|
(instr &
|
|
0xf) |
|
|
((instr >>
|
|
12) &
|
|
0x70) |
|
|
((instr >>
|
|
21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmov::
|
|
DecodeImmediate(cmode,
|
|
(instr &
|
|
0xf) |
|
|
((instr >>
|
|
12) &
|
|
0x70) |
|
|
((instr >>
|
|
21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800950
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000000: {
|
|
// 0xef800950
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVorr::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVorr::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vorr(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xef800970
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVbic::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVbic::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vbic(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xef800850
|
|
switch (instr & 0x10000000) {
|
|
case 0x00000000: {
|
|
// 0xef800850
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_imm6_3_Decode(
|
|
(instr >> 19) & 0x7);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vrshrn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x10000000: {
|
|
// 0xff800850
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_2_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 28) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqrshrun(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xef800950
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_1_Decode((instr >> 19) & 0x7,
|
|
(instr >> 28) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm =
|
|
ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vqrshrn(CurrentCond(),
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xef800c50
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xef800c50
|
|
switch (instr & 0x00200000) {
|
|
case 0x00000000: {
|
|
// 0xef800c50
|
|
switch (instr & 0x00180000) {
|
|
case 0x00000000: {
|
|
// 0xef800c50
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000200: {
|
|
// 0xef800e50
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xef800f50
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 21) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xef800c70
|
|
switch (instr & 0x00000f20) {
|
|
case 0x00000000: {
|
|
// 0xef800c50
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xef800c70
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xef800e50
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000220: {
|
|
// 0xef800e70
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xef800c50
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000420: {
|
|
// 0xef800c70
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xef800e50
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000620: {
|
|
// 0xef800e70
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xef800c50
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000820: {
|
|
// 0xef800c70
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xef800e50
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000a20: {
|
|
// 0xef800e70
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xef800c50
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000c20: {
|
|
// 0xef800c70
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xef800d50
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000d20: {
|
|
// 0xef800d70
|
|
if (((instr & 0xd00) ==
|
|
0x100) ||
|
|
((instr & 0xd00) ==
|
|
0x500) ||
|
|
((instr & 0xd00) ==
|
|
0x900) ||
|
|
((instr & 0xe00) ==
|
|
0xe00)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
(instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmvn::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmvn(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000e00: {
|
|
// 0xef800e50
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000e20: {
|
|
// 0xef800e70
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000f00: {
|
|
// 0xef800f50
|
|
if (((instr & 0x920) ==
|
|
0x100) ||
|
|
((instr & 0x520) ==
|
|
0x100) ||
|
|
((instr & 0x820) ==
|
|
0x20) ||
|
|
((instr & 0x420) ==
|
|
0x20) ||
|
|
((instr & 0x220) ==
|
|
0x20) ||
|
|
((instr & 0x120) ==
|
|
0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) !=
|
|
0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmov::
|
|
DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) &
|
|
0x70) |
|
|
((instr >> 21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(
|
|
cmode);
|
|
if (dt.Is(
|
|
kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr,
|
|
22,
|
|
12);
|
|
QOperand imm = ImmediateVmov::
|
|
DecodeImmediate(cmode,
|
|
(instr &
|
|
0xf) |
|
|
((instr >>
|
|
12) &
|
|
0x70) |
|
|
((instr >>
|
|
21) &
|
|
0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; T1 NOLINT(whitespace/line_length)
|
|
vmov(CurrentCond(),
|
|
dt,
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if ((instr & 0x00000200) == 0x00000200) {
|
|
if (((instr & 0x200000) == 0x0)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt1 = Dt_op_U_1_Decode1(
|
|
((instr >> 28) & 0x1) |
|
|
((instr >> 7) & 0x2));
|
|
if (dt1.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
DataType dt2 = Dt_op_U_1_Decode2(
|
|
((instr >> 28) & 0x1) |
|
|
((instr >> 7) & 0x2));
|
|
if (dt2.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedT32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t fbits =
|
|
64 - ((instr >> 16) & 0x3f);
|
|
// VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; T1 NOLINT(whitespace/line_length)
|
|
vcvt(CurrentCond(),
|
|
dt1,
|
|
dt2,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
fbits);
|
|
} else {
|
|
UnallocatedT32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedT32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
} // NOLINT(readability/fn_size)
|
|
|
|
void Disassembler::DecodeA32(uint32_t instr) {
|
|
A32CodeAddressIncrementer incrementer(&code_address_);
|
|
if ((instr & 0xf0000000) == 0xf0000000) {
|
|
switch (instr & 0x0e000000) {
|
|
case 0x00000000: {
|
|
// 0xf0000000
|
|
switch (instr & 0x01f10020) {
|
|
case 0x01000000: {
|
|
// 0xf1000000
|
|
switch (instr & 0x000e0000) {
|
|
case 0x00020000: {
|
|
// 0xf1020000
|
|
if ((instr & 0x000001c0) == 0x00000000) {
|
|
UnimplementedA32("CPS", instr);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00080000: {
|
|
// 0xf1080000
|
|
if ((instr & 0x0000001f) == 0x00000000) {
|
|
UnimplementedA32("CPSIE", instr);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000a0000: {
|
|
// 0xf10a0000
|
|
UnimplementedA32("CPSIE", instr);
|
|
break;
|
|
}
|
|
case 0x000c0000: {
|
|
// 0xf10c0000
|
|
if ((instr & 0x0000001f) == 0x00000000) {
|
|
UnimplementedA32("CPSID", instr);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000e0000: {
|
|
// 0xf10e0000
|
|
UnimplementedA32("CPSID", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01010000: {
|
|
// 0xf1010000
|
|
if ((instr & 0x000000d0) == 0x00000000) {
|
|
UnimplementedA32("SETEND", instr);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x02000000: {
|
|
// 0xf2000000
|
|
switch (instr & 0x00800010) {
|
|
case 0x00000000: {
|
|
// 0xf2000000
|
|
switch (instr & 0x00000f40) {
|
|
case 0x00000000: {
|
|
// 0xf2000000
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vhadd(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf2000040
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vhadd(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2000100
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRHADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vrhadd(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000140: {
|
|
// 0xf2000140
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRHADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vrhadd(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2000200
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VHSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vhsub(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000240: {
|
|
// 0xf2000240
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VHSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vhsub(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf2000300
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vcgt(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000340: {
|
|
// 0xf2000340
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vcgt(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf2000400
|
|
DataType dt = Dt_U_size_3_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
// VSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
|
|
vshl(al, dt, DRegister(rd), DRegister(rm), DRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000440: {
|
|
// 0xf2000440
|
|
DataType dt = Dt_U_size_3_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
// VSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
|
|
vshl(al, dt, QRegister(rd), QRegister(rm), QRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf2000500
|
|
DataType dt = Dt_U_size_3_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
// VRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
|
|
vrshl(al, dt, DRegister(rd), DRegister(rm), DRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000540: {
|
|
// 0xf2000540
|
|
DataType dt = Dt_U_size_3_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
// VRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
|
|
vrshl(al, dt, QRegister(rd), QRegister(rm), QRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf2000600
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vmax(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000640: {
|
|
// 0xf2000640
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMAX{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vmax(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xf2000700
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VABD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vabd(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000740: {
|
|
// 0xf2000740
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VABD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vabd(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf2000800
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2000800
|
|
DataType dt = Dt_size_2_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vadd(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000800
|
|
DataType dt = Dt_size_2_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vsub(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000840: {
|
|
// 0xf2000840
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2000840
|
|
DataType dt = Dt_size_2_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vadd(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000840
|
|
DataType dt = Dt_size_2_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vsub(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf2000900
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2000900
|
|
DataType dt = Dt_size_10_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
|
|
vmla(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000900
|
|
DataType dt = Dt_size_10_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm> ; A1
|
|
vmls(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000940: {
|
|
// 0xf2000940
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2000940
|
|
DataType dt = Dt_size_10_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
|
|
vmla(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000940
|
|
DataType dt = Dt_size_10_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Qm> ; A1
|
|
vmls(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf2000a00
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VPMAX{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vpmax(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000b00: {
|
|
// 0xf2000b00
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2000b00
|
|
DataType dt = Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vqdmulh(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000b00
|
|
DataType dt = Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vqrdmulh(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000b40: {
|
|
// 0xf2000b40
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2000b40
|
|
DataType dt = Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vqdmulh(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000b40
|
|
DataType dt = Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vqrdmulh(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000c40: {
|
|
// 0xf2000c40
|
|
switch (instr & 0x01300000) {
|
|
case 0x00000000: {
|
|
// 0xf2000c40
|
|
UnimplementedA32("SHA1C", instr);
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xf2100c40
|
|
UnimplementedA32("SHA1P", instr);
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf2200c40
|
|
UnimplementedA32("SHA1M", instr);
|
|
break;
|
|
}
|
|
case 0x00300000: {
|
|
// 0xf2300c40
|
|
UnimplementedA32("SHA1SU0", instr);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000c40
|
|
UnimplementedA32("SHA256H", instr);
|
|
break;
|
|
}
|
|
case 0x01100000: {
|
|
// 0xf3100c40
|
|
UnimplementedA32("SHA256H2", instr);
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0xf3200c40
|
|
UnimplementedA32("SHA256SU1", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xf2000d00
|
|
switch (instr & 0x01300000) {
|
|
case 0x00000000: {
|
|
// 0xf2000d00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
|
|
vadd(al, F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf2200d00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSUB{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
|
|
vsub(al, F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000d00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VPADD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
|
|
vpadd(al, F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0xf3200d00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VABD{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
|
|
vabd(al, F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000d40: {
|
|
// 0xf2000d40
|
|
switch (instr & 0x01300000) {
|
|
case 0x00000000: {
|
|
// 0xf2000d40
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VADD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
|
|
vadd(al, F32, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf2200d40
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VSUB{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
|
|
vsub(al, F32, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0xf3200d40
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VABD{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
|
|
vabd(al, F32, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000e00: {
|
|
// 0xf2000e00
|
|
switch (instr & 0x01200000) {
|
|
case 0x00000000: {
|
|
// 0xf2000e00
|
|
DataType dt = Dt_sz_1_Decode((instr >> 20) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A2
|
|
vceq(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000e00
|
|
if ((instr & 0x00100000) == 0x00000000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
|
|
vcge(al,
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0xf3200e00
|
|
if ((instr & 0x00100000) == 0x00000000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A2
|
|
vcgt(al,
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000e40: {
|
|
// 0xf2000e40
|
|
switch (instr & 0x01200000) {
|
|
case 0x00000000: {
|
|
// 0xf2000e40
|
|
DataType dt = Dt_sz_1_Decode((instr >> 20) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A2
|
|
vceq(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000e40
|
|
if ((instr & 0x00100000) == 0x00000000) {
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
|
|
vcge(al,
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0xf3200e40
|
|
if ((instr & 0x00100000) == 0x00000000) {
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A2
|
|
vcgt(al,
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000f00: {
|
|
// 0xf2000f00
|
|
switch (instr & 0x01300000) {
|
|
case 0x00000000: {
|
|
// 0xf2000f00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
|
|
vmax(al, F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf2200f00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
|
|
vmin(al, F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000f00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VPMAX{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
|
|
vpmax(al, F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0xf3200f00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VPMIN{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
|
|
vpmin(al, F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000f40: {
|
|
// 0xf2000f40
|
|
switch (instr & 0x01300000) {
|
|
case 0x00000000: {
|
|
// 0xf2000f40
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMAX{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
|
|
vmax(al, F32, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf2200f40
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMIN{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
|
|
vmin(al, F32, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000010: {
|
|
// 0xf2000010
|
|
switch (instr & 0x00000f40) {
|
|
case 0x00000000: {
|
|
// 0xf2000010
|
|
DataType dt = Dt_U_size_3_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vqadd(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf2000050
|
|
DataType dt = Dt_U_size_3_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VQADD{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vqadd(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2000110
|
|
switch (instr & 0x01300000) {
|
|
case 0x00000000: {
|
|
// 0xf2000110
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VAND{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
|
|
vand(al,
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xf2100110
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VBIC{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
|
|
vbic(al,
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf2200110
|
|
if (((instr & 0x00000040) == 0x00000000) &&
|
|
((((Uint32((instr >> 7)) & Uint32(0x1)) << 4) |
|
|
(Uint32((instr >> 16)) & Uint32(0xf))) ==
|
|
(((Uint32((instr >> 5)) & Uint32(0x1)) << 4) |
|
|
(Uint32(instr) & Uint32(0xf))))) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 7, 16);
|
|
// VMOV{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
|
|
vmov(al,
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VORR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
|
|
vorr(al,
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00300000: {
|
|
// 0xf2300110
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VORN{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
|
|
vorn(al,
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000110
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VEOR{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
|
|
veor(al,
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01100000: {
|
|
// 0xf3100110
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VBSL{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
|
|
vbsl(al,
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0xf3200110
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VBIT{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
|
|
vbit(al,
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01300000: {
|
|
// 0xf3300110
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VBIF{<c>}{<q>}{.<dt>} {<Dd>}, <Dn>, <Dm> ; A1
|
|
vbif(al,
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000140: {
|
|
// 0xf2000150
|
|
switch (instr & 0x01300000) {
|
|
case 0x00000000: {
|
|
// 0xf2000150
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VAND{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
|
|
vand(al,
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xf2100150
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VBIC{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
|
|
vbic(al,
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf2200150
|
|
if (((instr & 0x00000040) == 0x00000040) &&
|
|
((((Uint32((instr >> 7)) & Uint32(0x1)) << 4) |
|
|
(Uint32((instr >> 16)) & Uint32(0xf))) ==
|
|
(((Uint32((instr >> 5)) & Uint32(0x1)) << 4) |
|
|
(Uint32(instr) & Uint32(0xf))))) {
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 7, 16);
|
|
// VMOV{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
|
|
vmov(al,
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VORR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
|
|
vorr(al,
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00300000: {
|
|
// 0xf2300150
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VORN{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
|
|
vorn(al,
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000150
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VEOR{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
|
|
veor(al,
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01100000: {
|
|
// 0xf3100150
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VBSL{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
|
|
vbsl(al,
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0xf3200150
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VBIT{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
|
|
vbit(al,
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01300000: {
|
|
// 0xf3300150
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VBIF{<c>}{<q>}{.<dt>} {<Qd>}, <Qn>, <Qm> ; A1
|
|
vbif(al,
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2000210
|
|
DataType dt = Dt_U_size_3_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQSUB{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vqsub(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000240: {
|
|
// 0xf2000250
|
|
DataType dt = Dt_U_size_3_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VQSUB{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vqsub(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf2000310
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vcge(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000340: {
|
|
// 0xf2000350
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vcge(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf2000410
|
|
DataType dt = Dt_U_size_3_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
// VQSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
|
|
vqshl(al, dt, DRegister(rd), DRegister(rm), DRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000440: {
|
|
// 0xf2000450
|
|
DataType dt = Dt_U_size_3_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
// VQSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
|
|
vqshl(al, dt, QRegister(rd), QRegister(rm), QRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf2000510
|
|
DataType dt = Dt_U_size_3_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
// VQRSHL{<c>}{<q>}.<dt> {<Dd>}, <Dm>, <Dn> ; A1
|
|
vqrshl(al, dt, DRegister(rd), DRegister(rm), DRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000540: {
|
|
// 0xf2000550
|
|
DataType dt = Dt_U_size_3_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
// VQRSHL{<c>}{<q>}.<dt> {<Qd>}, <Qm>, <Qn> ; A1
|
|
vqrshl(al, dt, QRegister(rd), QRegister(rm), QRegister(rn));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf2000610
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vmin(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000640: {
|
|
// 0xf2000650
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMIN{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vmin(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xf2000710
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VABA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> ; A1
|
|
vaba(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000740: {
|
|
// 0xf2000750
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VABA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> ; A1
|
|
vaba(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf2000810
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2000810
|
|
DataType dt = Dt_size_7_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VTST{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vtst(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000810
|
|
DataType dt = Dt_size_4_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vceq(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000840: {
|
|
// 0xf2000850
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2000850
|
|
DataType dt = Dt_size_7_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VTST{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vtst(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000850
|
|
DataType dt = Dt_size_4_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vceq(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf2000910
|
|
DataType dt = Dt_op_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vmul(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000940: {
|
|
// 0xf2000950
|
|
DataType dt = Dt_op_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Qm> ; A1
|
|
vmul(al, dt, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf2000a10
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VPMIN{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vpmin(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000b00: {
|
|
// 0xf2000b10
|
|
if ((instr & 0x01000000) == 0x00000000) {
|
|
DataType dt = Dt_size_4_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VPADD{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm> ; A1
|
|
vpadd(al, dt, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xf2000c10
|
|
switch (instr & 0x01300000) {
|
|
case 0x00000000: {
|
|
// 0xf2000c10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VFMA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
|
|
vfma(al, F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf2200c10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VFMS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
|
|
vfms(al, F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000c40: {
|
|
// 0xf2000c50
|
|
switch (instr & 0x01300000) {
|
|
case 0x00000000: {
|
|
// 0xf2000c50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VFMA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
|
|
vfma(al, F32, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf2200c50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VFMS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
|
|
vfms(al, F32, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xf2000d10
|
|
switch (instr & 0x01300000) {
|
|
case 0x00000000: {
|
|
// 0xf2000d10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLA{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
|
|
vmla(al, F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf2200d10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLS{<c>}{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
|
|
vmls(al, F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000d10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMUL{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
|
|
vmul(al, F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000d40: {
|
|
// 0xf2000d50
|
|
switch (instr & 0x01300000) {
|
|
case 0x00000000: {
|
|
// 0xf2000d50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMLA{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
|
|
vmla(al, F32, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf2200d50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMLS{<c>}{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
|
|
vmls(al, F32, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000d50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMUL{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
|
|
vmul(al, F32, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000e00: {
|
|
// 0xf2000e10
|
|
switch (instr & 0x01300000) {
|
|
case 0x01000000: {
|
|
// 0xf3000e10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VACGE{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
|
|
vacge(al, F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0xf3200e10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VACGT{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
|
|
vacgt(al, F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000e40: {
|
|
// 0xf2000e50
|
|
switch (instr & 0x01300000) {
|
|
case 0x01000000: {
|
|
// 0xf3000e50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VACGE{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
|
|
vacge(al, F32, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0xf3200e50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VACGT{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
|
|
vacgt(al, F32, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000f00: {
|
|
// 0xf2000f10
|
|
switch (instr & 0x01300000) {
|
|
case 0x00000000: {
|
|
// 0xf2000f10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRECPS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
|
|
vrecps(al,
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf2200f10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRSQRTS{<c>}{<q>}.F32 {<Dd>}, <Dn>, <Dm> ; A1
|
|
vrsqrts(al,
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000f10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMAXNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
|
|
vmaxnm(F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0xf3200f10
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMINNM{<q>}.F32 <Dd>, <Dn>, <Dm> ; A1
|
|
vminnm(F32, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000f40: {
|
|
// 0xf2000f50
|
|
switch (instr & 0x01300000) {
|
|
case 0x00000000: {
|
|
// 0xf2000f50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRECPS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
|
|
vrecps(al,
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf2200f50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRSQRTS{<c>}{<q>}.F32 {<Qd>}, <Qn>, <Qm> ; A1
|
|
vrsqrts(al,
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3000f50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMAXNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
|
|
vmaxnm(F32, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0xf3200f50
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMINNM{<q>}.F32 <Qd>, <Qn>, <Qm> ; A1
|
|
vminnm(F32, QRegister(rd), QRegister(rn), QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xf2800000
|
|
switch (instr & 0x00300000) {
|
|
case 0x00300000: {
|
|
// 0xf2b00000
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2b00000
|
|
switch (instr & 0x00000040) {
|
|
case 0x00000000: {
|
|
// 0xf2b00000
|
|
if (((instr & 0x800) == 0x800)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm = (instr >> 8) & 0xf;
|
|
// VEXT{<c>}{<q>}.8 {<Dd>}, <Dn>, <Dm>, #<imm> ; A1
|
|
vext(al,
|
|
Untyped8,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf2b00040
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm = (instr >> 8) & 0xf;
|
|
// VEXT{<c>}{<q>}.8 {<Qd>}, <Qn>, <Qm>, #<imm> ; A1
|
|
vext(al,
|
|
Untyped8,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3b00000
|
|
switch (instr & 0x00000800) {
|
|
case 0x00000000: {
|
|
// 0xf3b00000
|
|
switch (instr & 0x00030200) {
|
|
case 0x00000000: {
|
|
// 0xf3b00000
|
|
switch (instr & 0x000005c0) {
|
|
case 0x00000000: {
|
|
// 0xf3b00000
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VREV64{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vrev64(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf3b00040
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VREV64{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vrev64(al, dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xf3b00080
|
|
DataType dt =
|
|
Dt_size_15_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VREV32{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vrev32(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000000c0: {
|
|
// 0xf3b000c0
|
|
DataType dt =
|
|
Dt_size_15_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VREV32{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vrev32(al, dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf3b00100
|
|
DataType dt =
|
|
Dt_size_1_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VREV16{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vrev16(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000140: {
|
|
// 0xf3b00140
|
|
DataType dt =
|
|
Dt_size_1_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VREV16{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vrev16(al, dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf3b00400
|
|
DataType dt =
|
|
Dt_size_5_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCLS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vcls(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000440: {
|
|
// 0xf3b00440
|
|
DataType dt =
|
|
Dt_size_5_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCLS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vcls(al, dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000480: {
|
|
// 0xf3b00480
|
|
DataType dt =
|
|
Dt_size_4_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCLZ{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vclz(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000004c0: {
|
|
// 0xf3b004c0
|
|
DataType dt =
|
|
Dt_size_4_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCLZ{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vclz(al, dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf3b00500
|
|
if ((instr & 0x000c0000) == 0x00000000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCNT{<c>}{<q>}.8 <Dd>, <Dm> ; A1
|
|
vcnt(al,
|
|
Untyped8,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000540: {
|
|
// 0xf3b00540
|
|
if ((instr & 0x000c0000) == 0x00000000) {
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCNT{<c>}{<q>}.8 <Qd>, <Qm> ; A1
|
|
vcnt(al,
|
|
Untyped8,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000580: {
|
|
// 0xf3b00580
|
|
if ((instr & 0x000c0000) == 0x00000000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMVN{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
|
|
vmvn(al,
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000005c0: {
|
|
// 0xf3b005c0
|
|
if ((instr & 0x000c0000) == 0x00000000) {
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMVN{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
|
|
vmvn(al,
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf3b00200
|
|
switch (instr & 0x00000540) {
|
|
case 0x00000000: {
|
|
// 0xf3b00200
|
|
DataType dt =
|
|
Dt_op_size_2_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 5) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VPADDL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vpaddl(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf3b00240
|
|
DataType dt =
|
|
Dt_op_size_2_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 5) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VPADDL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vpaddl(al, dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf3b00300
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xf3b00300
|
|
UnimplementedA32("AESE", instr);
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xf3b00380
|
|
UnimplementedA32("AESMC", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000140: {
|
|
// 0xf3b00340
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xf3b00340
|
|
UnimplementedA32("AESD", instr);
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xf3b003c0
|
|
UnimplementedA32("AESIMC", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf3b00600
|
|
DataType dt =
|
|
Dt_op_size_2_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 5) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VPADAL{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vpadal(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000440: {
|
|
// 0xf3b00640
|
|
DataType dt =
|
|
Dt_op_size_2_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 5) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VPADAL{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vpadal(al, dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf3b00700
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xf3b00700
|
|
DataType dt =
|
|
Dt_size_5_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vqabs(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xf3b00780
|
|
DataType dt =
|
|
Dt_size_5_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vqneg(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000540: {
|
|
// 0xf3b00740
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xf3b00740
|
|
DataType dt =
|
|
Dt_size_5_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VQABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vqabs(al, dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xf3b007c0
|
|
DataType dt =
|
|
Dt_size_5_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VQNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vqneg(al, dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0xf3b10000
|
|
switch (instr & 0x000001c0) {
|
|
case 0x00000000: {
|
|
// 0xf3b10000
|
|
DataType dt =
|
|
Dt_F_size_1_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCGT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
|
|
vcgt(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf3b10040
|
|
DataType dt =
|
|
Dt_F_size_1_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCGT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
|
|
vcgt(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xf3b10080
|
|
DataType dt =
|
|
Dt_F_size_1_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCGE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
|
|
vcge(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x000000c0: {
|
|
// 0xf3b100c0
|
|
DataType dt =
|
|
Dt_F_size_1_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCGE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
|
|
vcge(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf3b10100
|
|
DataType dt =
|
|
Dt_F_size_2_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCEQ{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
|
|
vceq(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x00000140: {
|
|
// 0xf3b10140
|
|
DataType dt =
|
|
Dt_F_size_2_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCEQ{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
|
|
vceq(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x00000180: {
|
|
// 0xf3b10180
|
|
DataType dt =
|
|
Dt_F_size_1_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCLE{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
|
|
vcle(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x000001c0: {
|
|
// 0xf3b101c0
|
|
DataType dt =
|
|
Dt_F_size_1_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCLE{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
|
|
vcle(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00010200: {
|
|
// 0xf3b10200
|
|
switch (instr & 0x000001c0) {
|
|
case 0x00000000: {
|
|
// 0xf3b10200
|
|
DataType dt =
|
|
Dt_F_size_1_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCLT{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #0 ; A1
|
|
vclt(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf3b10240
|
|
DataType dt =
|
|
Dt_F_size_1_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCLT{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #0 ; A1
|
|
vclt(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
UINT32_C(0));
|
|
break;
|
|
}
|
|
case 0x000000c0: {
|
|
// 0xf3b102c0
|
|
if ((instr & 0x000c0400) == 0x00080000) {
|
|
UnimplementedA32("SHA1H", instr);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf3b10300
|
|
DataType dt =
|
|
Dt_F_size_1_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VABS{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vabs(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000140: {
|
|
// 0xf3b10340
|
|
DataType dt =
|
|
Dt_F_size_1_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VABS{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vabs(al, dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000180: {
|
|
// 0xf3b10380
|
|
DataType dt =
|
|
Dt_F_size_1_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VNEG{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vneg(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000001c0: {
|
|
// 0xf3b103c0
|
|
DataType dt =
|
|
Dt_F_size_1_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 8) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VNEG{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vneg(al, dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00020000: {
|
|
// 0xf3b20000
|
|
switch (instr & 0x000005c0) {
|
|
case 0x00000000: {
|
|
// 0xf3b20000
|
|
if ((instr & 0x000c0000) == 0x00000000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSWP{<c>}{<q>}{.<dt>} <Dd>, <Dm> ; A1
|
|
vswp(al,
|
|
kDataTypeValueNone,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf3b20040
|
|
if ((instr & 0x000c0000) == 0x00000000) {
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VSWP{<c>}{<q>}{.<dt>} <Qd>, <Qm> ; A1
|
|
vswp(al,
|
|
kDataTypeValueNone,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xf3b20080
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VTRN{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vtrn(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000000c0: {
|
|
// 0xf3b200c0
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VTRN{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vtrn(al, dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf3b20100
|
|
DataType dt =
|
|
Dt_size_15_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VUZP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vuzp(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000140: {
|
|
// 0xf3b20140
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VUZP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vuzp(al, dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000180: {
|
|
// 0xf3b20180
|
|
DataType dt =
|
|
Dt_size_15_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VZIP{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vzip(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000001c0: {
|
|
// 0xf3b201c0
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VZIP{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vzip(al, dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf3b20400
|
|
DataType dt =
|
|
Dt_size_16_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTN{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vrintn(dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000440: {
|
|
// 0xf3b20440
|
|
DataType dt =
|
|
Dt_size_16_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRINTN{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vrintn(dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000480: {
|
|
// 0xf3b20480
|
|
DataType dt =
|
|
Dt_size_16_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTX{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vrintx(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000004c0: {
|
|
// 0xf3b204c0
|
|
DataType dt =
|
|
Dt_size_16_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRINTX{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vrintx(dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf3b20500
|
|
DataType dt =
|
|
Dt_size_16_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTA{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vrinta(dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000540: {
|
|
// 0xf3b20540
|
|
DataType dt =
|
|
Dt_size_16_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRINTA{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vrinta(dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000580: {
|
|
// 0xf3b20580
|
|
DataType dt =
|
|
Dt_size_16_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTZ{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vrintz(al, dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000005c0: {
|
|
// 0xf3b205c0
|
|
DataType dt =
|
|
Dt_size_16_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRINTZ{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vrintz(dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00020200: {
|
|
// 0xf3b20200
|
|
switch (instr & 0x00000580) {
|
|
case 0x00000000: {
|
|
// 0xf3b20200
|
|
switch (instr & 0x00000040) {
|
|
case 0x00000000: {
|
|
// 0xf3b20200
|
|
DataType dt =
|
|
Dt_size_3_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
|
|
vmovn(al, dt, DRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf3b20240
|
|
DataType dt =
|
|
Dt_size_14_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VQMOVUN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
|
|
vqmovun(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xf3b20280
|
|
DataType dt =
|
|
Dt_op_size_3_Decode(((instr >> 18) & 0x3) |
|
|
((instr >> 4) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VQMOVN{<c>}{<q>}.<dt> <Dd>, <Qm> ; A1
|
|
vqmovn(al, dt, DRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf3b20300
|
|
if ((instr & 0x00000040) == 0x00000000) {
|
|
DataType dt =
|
|
Dt_size_17_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm = dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A2 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000180: {
|
|
// 0xf3b20380
|
|
switch (instr & 0x000c0040) {
|
|
case 0x00080000: {
|
|
// 0xf3ba0380
|
|
UnimplementedA32("SHA1SU1", instr);
|
|
break;
|
|
}
|
|
case 0x00080040: {
|
|
// 0xf3ba03c0
|
|
UnimplementedA32("SHA256SU0", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf3b20600
|
|
if ((instr & 0x000c0040) == 0x00040000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.F16.F32 <Dd>, <Qm> ; A1
|
|
vcvt(al,
|
|
F16,
|
|
F32,
|
|
DRegister(rd),
|
|
QRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000480: {
|
|
// 0xf3b20680
|
|
switch (instr & 0x00000040) {
|
|
case 0x00000000: {
|
|
// 0xf3b20680
|
|
DataType dt =
|
|
Dt_size_16_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTM{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vrintm(dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf3b206c0
|
|
DataType dt =
|
|
Dt_size_16_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRINTM{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vrintm(dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf3b20700
|
|
if ((instr & 0x000c0040) == 0x00040000) {
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.F32.F16 <Qd>, <Dm> ; A1
|
|
vcvt(al,
|
|
F32,
|
|
F16,
|
|
QRegister(rd),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000580: {
|
|
// 0xf3b20780
|
|
switch (instr & 0x00000040) {
|
|
case 0x00000000: {
|
|
// 0xf3b20780
|
|
DataType dt =
|
|
Dt_size_16_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTP{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vrintp(dt, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf3b207c0
|
|
DataType dt =
|
|
Dt_size_16_Decode((instr >> 18) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRINTP{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vrintp(dt, QRegister(rd), QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00030000: {
|
|
// 0xf3b30000
|
|
switch (instr & 0x00000440) {
|
|
case 0x00000000: {
|
|
// 0xf3b30000
|
|
switch (instr & 0x000c0100) {
|
|
case 0x00080000: {
|
|
// 0xf3bb0000
|
|
DataType dt =
|
|
Dt_op_3_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTA{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
|
|
vcvta(dt,
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00080100: {
|
|
// 0xf3bb0100
|
|
DataType dt =
|
|
Dt_op_3_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTN{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
|
|
vcvtn(dt,
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf3b30040
|
|
switch (instr & 0x000c0100) {
|
|
case 0x00080000: {
|
|
// 0xf3bb0040
|
|
DataType dt =
|
|
Dt_op_3_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCVTA{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
|
|
vcvta(dt,
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00080100: {
|
|
// 0xf3bb0140
|
|
DataType dt =
|
|
Dt_op_3_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCVTN{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
|
|
vcvtn(dt,
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf3b30400
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xf3b30400
|
|
DataType dt = Dt_F_size_4_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 6) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRECPE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vrecpe(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xf3b30480
|
|
DataType dt = Dt_F_size_4_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 6) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRSQRTE{<c>}{<q>}.<dt> <Dd>, <Dm> ; A1
|
|
vrsqrte(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000440: {
|
|
// 0xf3b30440
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xf3b30440
|
|
DataType dt = Dt_F_size_4_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 6) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRECPE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vrecpe(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0xf3b304c0
|
|
DataType dt = Dt_F_size_4_Decode(
|
|
((instr >> 18) & 0x3) |
|
|
((instr >> 6) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRSQRTE{<c>}{<q>}.<dt> <Qd>, <Qm> ; A1
|
|
vrsqrte(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00030200: {
|
|
// 0xf3b30200
|
|
switch (instr & 0x000c0440) {
|
|
case 0x00080000: {
|
|
// 0xf3bb0200
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xf3bb0200
|
|
DataType dt =
|
|
Dt_op_3_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTP{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
|
|
vcvtp(dt,
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf3bb0300
|
|
DataType dt =
|
|
Dt_op_3_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTM{<q>}.<dt>.F32 <Dd>, <Dm> ; A1
|
|
vcvtm(dt,
|
|
F32,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00080040: {
|
|
// 0xf3bb0240
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xf3bb0240
|
|
DataType dt =
|
|
Dt_op_3_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCVTP{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
|
|
vcvtp(dt,
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf3bb0340
|
|
DataType dt =
|
|
Dt_op_3_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCVTM{<q>}.<dt>.F32 <Qd>, <Qm> ; A1
|
|
vcvtm(dt,
|
|
F32,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00080400: {
|
|
// 0xf3bb0600
|
|
DataType dt1 =
|
|
Dt_op_1_Decode1((instr >> 7) & 0x3);
|
|
if (dt1.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt2 =
|
|
Dt_op_1_Decode2((instr >> 7) & 0x3);
|
|
if (dt2.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm> ; A1
|
|
vcvt(al,
|
|
dt1,
|
|
dt2,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00080440: {
|
|
// 0xf3bb0640
|
|
DataType dt1 =
|
|
Dt_op_1_Decode1((instr >> 7) & 0x3);
|
|
if (dt1.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt2 =
|
|
Dt_op_1_Decode2((instr >> 7) & 0x3);
|
|
if (dt2.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm> ; A1
|
|
vcvt(al,
|
|
dt1,
|
|
dt2,
|
|
QRegister(rd),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf3b00800
|
|
switch (instr & 0x00000440) {
|
|
case 0x00000000: {
|
|
// 0xf3b00800
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned first = ExtractDRegister(instr, 7, 16);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0x3) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 1;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
break;
|
|
case 0x2:
|
|
length = 3;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VTBL{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
|
|
vtbl(al,
|
|
Untyped8,
|
|
DRegister(rd),
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf3b00840
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned first = ExtractDRegister(instr, 7, 16);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0x3) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 1;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
break;
|
|
case 0x2:
|
|
length = 3;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VTBX{<c>}{<q>}.8 <Dd>, <list>, <Dm> ; A1
|
|
vtbx(al,
|
|
Untyped8,
|
|
DRegister(rd),
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf3b00c00
|
|
if ((instr & 0x00000380) == 0x00000000) {
|
|
unsigned lane;
|
|
DataType dt =
|
|
Dt_imm4_1_Decode((instr >> 16) & 0xf, &lane);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VDUP{<c>}{<q>}.<dt> <Dd>, <Dm[x]> ; A1
|
|
vdup(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegisterLane(rm, lane));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000440: {
|
|
// 0xf3b00c40
|
|
if ((instr & 0x00000380) == 0x00000000) {
|
|
unsigned lane;
|
|
DataType dt =
|
|
Dt_imm4_1_Decode((instr >> 16) & 0xf, &lane);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VDUP{<c>}{<q>}.<dt> <Qd>, <Dm[x]> ; A1
|
|
vdup(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegisterLane(rm, lane));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000c40) {
|
|
case 0x00000000: {
|
|
// 0xf2800000
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf2800000
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VADDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
|
|
vaddl(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800100
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VADDW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
|
|
vaddw(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2800200
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSUBL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
|
|
vsubl(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf2800300
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSUBW{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm> ; A1
|
|
vsubw(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf2800040
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0xf2800040
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2800040
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_9_Decode((instr >> 20) & 0x3,
|
|
(instr >> 8) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr, dt, 5, 0, &lane);
|
|
// VMLA{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1 NOLINT(whitespace/line_length)
|
|
vmla(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3800040
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_9_Decode((instr >> 20) & 0x3,
|
|
(instr >> 8) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr, dt, 5, 0, &lane);
|
|
// VMLA{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1 NOLINT(whitespace/line_length)
|
|
vmla(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2800240
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xf2800240
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_11_Decode((instr >> 20) & 0x3,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr, dt, 5, 0, &lane);
|
|
// VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1 NOLINT(whitespace/line_length)
|
|
vmlal(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800340
|
|
if ((instr & 0x01000000) == 0x00000000) {
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
uint32_t mvm =
|
|
(instr & 0xf) | ((instr >> 1) & 0x10);
|
|
uint32_t shift = 4;
|
|
if (dt.Is(S16)) {
|
|
shift = 3;
|
|
}
|
|
uint32_t vm = mvm & ((1 << shift) - 1);
|
|
uint32_t index = mvm >> shift;
|
|
// VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2 NOLINT(whitespace/line_length)
|
|
vqdmlal(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(vm),
|
|
index);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf2800400
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf2800400
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2800400
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_3_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
|
|
vaddhn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3800400
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_3_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRADDHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
|
|
vraddhn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800500
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VABAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
|
|
vabal(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2800600
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2800600
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_3_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
|
|
vsubhn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3800600
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_3_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
// VRSUBHN{<c>}{<q>}.<dt> <Dd>, <Qn>, <Qm> ; A1
|
|
vrsubhn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rn),
|
|
QRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf2800700
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_U_size_1_Decode(((instr >> 20) & 0x3) |
|
|
((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VABDL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
|
|
vabdl(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000440: {
|
|
// 0xf2800440
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0xf2800440
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2800440
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_9_Decode((instr >> 20) & 0x3,
|
|
(instr >> 8) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr, dt, 5, 0, &lane);
|
|
// VMLS{<c>}{<q>}.<type><size> <Dd>, <Dn>, <Dm[x]> ; A1 NOLINT(whitespace/line_length)
|
|
vmls(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3800440
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_9_Decode((instr >> 20) & 0x3,
|
|
(instr >> 8) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr, dt, 5, 0, &lane);
|
|
// VMLS{<c>}{<q>}.<type><size> <Qd>, <Qn>, <Dm[x]> ; A1 NOLINT(whitespace/line_length)
|
|
vmls(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2800640
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xf2800640
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_11_Decode((instr >> 20) & 0x3,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr, dt, 5, 0, &lane);
|
|
// VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm[x]> ; A1 NOLINT(whitespace/line_length)
|
|
vmlsl(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800740
|
|
if ((instr & 0x01000000) == 0x00000000) {
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
uint32_t mvm =
|
|
(instr & 0xf) | ((instr >> 1) & 0x10);
|
|
uint32_t shift = 4;
|
|
if (dt.Is(S16)) {
|
|
shift = 3;
|
|
}
|
|
uint32_t vm = mvm & ((1 << shift) - 1);
|
|
uint32_t index = mvm >> shift;
|
|
// VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A2 NOLINT(whitespace/line_length)
|
|
vqdmlsl(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(vm),
|
|
index);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf2800800
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf2800800
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_12_Decode((instr >> 20) & 0x3,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLAL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
|
|
vmlal(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800900
|
|
if ((instr & 0x01000000) == 0x00000000) {
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQDMLAL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
|
|
vqdmlal(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2800a00
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_12_Decode((instr >> 20) & 0x3,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLSL{<c>}{<q>}.<type><size> <Qd>, <Dn>, <Dm> ; A1
|
|
vmlsl(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf2800b00
|
|
if ((instr & 0x01000000) == 0x00000000) {
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQDMLSL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
|
|
vqdmlsl(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000840: {
|
|
// 0xf2800840
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0xf2800840
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2800840
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_F_size_3_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 6) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
uint32_t mvm =
|
|
(instr & 0xf) | ((instr >> 1) & 0x10);
|
|
uint32_t shift = 4;
|
|
if (dt.Is(I16)) {
|
|
shift = 3;
|
|
}
|
|
uint32_t vm = mvm & ((1 << shift) - 1);
|
|
uint32_t index = mvm >> shift;
|
|
// VMUL{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm>[<index>] ; A1 NOLINT(whitespace/line_length)
|
|
vmul(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(vm),
|
|
index);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3800840
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_F_size_3_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 6) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
uint32_t mvm =
|
|
(instr & 0xf) | ((instr >> 1) & 0x10);
|
|
uint32_t shift = 4;
|
|
if (dt.Is(I16)) {
|
|
shift = 3;
|
|
}
|
|
uint32_t vm = mvm & ((1 << shift) - 1);
|
|
uint32_t index = mvm >> shift;
|
|
// VMUL{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm>[<index>] ; A1 NOLINT(whitespace/line_length)
|
|
vmul(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
DRegister(vm),
|
|
index);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2800a40
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xf2800a40
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_U_size_2_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 22) & 0x4));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
uint32_t mvm =
|
|
(instr & 0xf) | ((instr >> 1) & 0x10);
|
|
uint32_t shift = 4;
|
|
if (dt.Is(S16) || dt.Is(U16)) {
|
|
shift = 3;
|
|
}
|
|
uint32_t vm = mvm & ((1 << shift) - 1);
|
|
uint32_t index = mvm >> shift;
|
|
// VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm>[<index>] ; A1 NOLINT(whitespace/line_length)
|
|
vmull(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(vm),
|
|
index);
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800b40
|
|
if ((instr & 0x01000000) == 0x00000000) {
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm = ExtractDRegisterAndLane(instr,
|
|
dt,
|
|
5,
|
|
0,
|
|
&lane);
|
|
// VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm[x]> ; A2
|
|
vqdmull(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xf2800c00
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xf2800c00
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_op_U_size_1_Decode(
|
|
((instr >> 20) & 0x3) | ((instr >> 22) & 0x4) |
|
|
((instr >> 6) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
|
|
vmull(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800d00
|
|
if ((instr & 0x01000200) == 0x00000000) {
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VQDMULL{<c>}{<q>}.<dt> <Qd>, <Dn>, <Dm> ; A1
|
|
vqdmull(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000c40: {
|
|
// 0xf2800c40
|
|
switch (instr & 0x01000300) {
|
|
case 0x00000000: {
|
|
// 0xf2800c40
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr, dt, 5, 0, &lane);
|
|
// VQDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
|
|
vqdmulh(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800d40
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr, dt, 5, 0, &lane);
|
|
// VQRDMULH{<c>}{<q>}.<dt> {<Dd>}, <Dn>, <Dm[x]> ; A2
|
|
vqrdmulh(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3800c40
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr, dt, 5, 0, &lane);
|
|
// VQDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
|
|
vqdmulh(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
case 0x01000100: {
|
|
// 0xf3800d40
|
|
if (((instr & 0x300000) == 0x300000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_13_Decode((instr >> 20) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = ExtractQRegister(instr, 7, 16);
|
|
int lane;
|
|
unsigned rm =
|
|
ExtractDRegisterAndLane(instr, dt, 5, 0, &lane);
|
|
// VQRDMULH{<c>}{<q>}.<dt> {<Qd>}, <Qn>, <Dm[x]> ; A2
|
|
vqrdmulh(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rn),
|
|
DRegisterLane(rm, lane));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800010: {
|
|
// 0xf2800010
|
|
switch (instr & 0x00000040) {
|
|
case 0x00000000: {
|
|
// 0xf2800010
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000000: {
|
|
// 0xf2800010
|
|
switch (instr & 0x00380080) {
|
|
case 0x00000000: {
|
|
// 0xf2800010
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xf2800010
|
|
switch (instr & 0x00000200) {
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xf2800030
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
|
|
vmvn(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = ((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800110
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000000: {
|
|
// 0xf2800110
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt = ImmediateVorr::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
DOperand imm = ImmediateVorr::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) | ((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vorr(al, dt, DRegister(rd), DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xf2800130
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt = ImmediateVbic::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
DOperand imm = ImmediateVbic::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) | ((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vbic(al, dt, DRegister(rd), DRegister(rd), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf2800010
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8),
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64 : (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshr(al, dt, DRegister(rd), DRegister(rm), imm);
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800110
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8),
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64 : (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vsra(al, dt, DRegister(rd), DRegister(rm), imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2800210
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8),
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64 : (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VRSHR{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vrshr(al, dt, DRegister(rd), DRegister(rm), imm);
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf2800310
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8),
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64 : (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VRSRA{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vrsra(al, dt, DRegister(rd), DRegister(rm), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf2800410
|
|
switch (instr & 0x00380080) {
|
|
case 0x00000000: {
|
|
// 0xf2800410
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xf2800410
|
|
switch (instr & 0x00000200) {
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xf2800430
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
|
|
vmvn(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = ((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800510
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000000: {
|
|
// 0xf2800510
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt = ImmediateVorr::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
DOperand imm = ImmediateVorr::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) | ((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vorr(al, dt, DRegister(rd), DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xf2800530
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt = ImmediateVbic::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
DOperand imm = ImmediateVbic::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) | ((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vbic(al, dt, DRegister(rd), DRegister(rd), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf2800410
|
|
if ((instr & 0x01000000) == 0x01000000) {
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_L_imm6_4_Decode(
|
|
((instr >> 19) & 0x7) | ((instr >> 4) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64 : (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VSRI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
|
|
vsri(al, dt, DRegister(rd), DRegister(rm), imm);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800510
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2800510
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_3_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - (dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VSHL{<c>}{<q>}.I<size> {<Dd>}, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshl(al, dt, DRegister(rd), DRegister(rm), imm);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3800510
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_4_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - (dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VSLI{<c>}{<q>}.<dt> {<Dd>}, <Dm>, #<imm> ; A1
|
|
vsli(al, dt, DRegister(rd), DRegister(rm), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2800610
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_2_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8),
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - (dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VQSHLU{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqshlu(al, dt, DRegister(rd), DRegister(rm), imm);
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf2800710
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8),
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - (dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VQSHL{<c>}{<q>}.<type><size> {<Dd>}, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqshl(al, dt, DRegister(rd), DRegister(rm), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf2800810
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xf2800810
|
|
switch (instr & 0x00380000) {
|
|
case 0x00000000: {
|
|
// 0xf2800810
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xf2800810
|
|
switch (instr & 0x00000200) {
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xf2800830
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
|
|
vmvn(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = ((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800910
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000000: {
|
|
// 0xf2800910
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVorr::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVorr::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VORR{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vorr(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xf2800930
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVbic::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVbic::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VBIC{<c>}{<q>}.<dt> {<Ddn>}, <Ddn>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vbic(al,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00180000: {
|
|
// 0xf2980810
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf2980810
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2980810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_3_Decode((instr >> 19) & 0x7);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshrn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3980810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_2_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqshrun(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2980910
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_1_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqshrn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2980a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00280000: {
|
|
// 0xf2a80810
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf2a80810
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2a80810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_3_Decode((instr >> 19) & 0x7);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshrn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3a80810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_2_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqshrun(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2a80910
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_1_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqshrn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2a80a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00300000: {
|
|
// 0xf2b00810
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf2b00810
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2b00810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_3_Decode((instr >> 19) & 0x7);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshrn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3b00810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_2_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqshrun(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2b00910
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_1_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqshrn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2b00a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00380000: {
|
|
// 0xf2b80810
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf2b80810
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2b80810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_3_Decode((instr >> 19) & 0x7);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshrn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3b80810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_2_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqshrun(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2b80910
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_1_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqshrn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2b80a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf2800810
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2800810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_3_Decode((instr >> 19) & 0x7);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshrn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3800810
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_2_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqshrun(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800910
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_1_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqshrn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2800a10
|
|
switch (instr & 0x00070000) {
|
|
case 0x00000000: {
|
|
// 0xf2800a10
|
|
switch (instr & 0x003f0000) {
|
|
case 0x00080000: {
|
|
// 0xf2880a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x380000) == 0x180000) ||
|
|
((instr & 0x380000) == 0x280000) ||
|
|
((instr & 0x380000) == 0x300000) ||
|
|
((instr & 0x380000) == 0x380000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_U_imm3H_1_Decode(
|
|
((instr >> 19) & 0x7) |
|
|
((instr >> 21) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; A1
|
|
vmovl(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00090000: {
|
|
// 0xf2890a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x000a0000: {
|
|
// 0xf28a0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x000b0000: {
|
|
// 0xf28b0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x000c0000: {
|
|
// 0xf28c0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x000d0000: {
|
|
// 0xf28d0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x000e0000: {
|
|
// 0xf28e0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x000f0000: {
|
|
// 0xf28f0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xf2900a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x380000) == 0x180000) ||
|
|
((instr & 0x380000) == 0x280000) ||
|
|
((instr & 0x380000) == 0x300000) ||
|
|
((instr & 0x380000) == 0x380000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_U_imm3H_1_Decode(
|
|
((instr >> 19) & 0x7) |
|
|
((instr >> 21) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; A1
|
|
vmovl(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00110000: {
|
|
// 0xf2910a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00120000: {
|
|
// 0xf2920a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00130000: {
|
|
// 0xf2930a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00140000: {
|
|
// 0xf2940a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00150000: {
|
|
// 0xf2950a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00160000: {
|
|
// 0xf2960a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00170000: {
|
|
// 0xf2970a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00180000: {
|
|
// 0xf2980a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00190000: {
|
|
// 0xf2990a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x001a0000: {
|
|
// 0xf29a0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x001b0000: {
|
|
// 0xf29b0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x001c0000: {
|
|
// 0xf29c0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x001d0000: {
|
|
// 0xf29d0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x001e0000: {
|
|
// 0xf29e0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x001f0000: {
|
|
// 0xf29f0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf2a00a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x380000) == 0x180000) ||
|
|
((instr & 0x380000) == 0x280000) ||
|
|
((instr & 0x380000) == 0x300000) ||
|
|
((instr & 0x380000) == 0x380000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_U_imm3H_1_Decode(
|
|
((instr >> 19) & 0x7) |
|
|
((instr >> 21) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
// VMOVL{<c>}{<q>}.<dt> <Qd>, <Dm> ; A1
|
|
vmovl(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00210000: {
|
|
// 0xf2a10a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00220000: {
|
|
// 0xf2a20a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00230000: {
|
|
// 0xf2a30a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00240000: {
|
|
// 0xf2a40a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00250000: {
|
|
// 0xf2a50a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00260000: {
|
|
// 0xf2a60a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00270000: {
|
|
// 0xf2a70a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00280000: {
|
|
// 0xf2a80a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00290000: {
|
|
// 0xf2a90a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x002a0000: {
|
|
// 0xf2aa0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x002b0000: {
|
|
// 0xf2ab0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x002c0000: {
|
|
// 0xf2ac0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x002d0000: {
|
|
// 0xf2ad0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x002e0000: {
|
|
// 0xf2ae0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x002f0000: {
|
|
// 0xf2af0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00300000: {
|
|
// 0xf2b00a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00310000: {
|
|
// 0xf2b10a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00320000: {
|
|
// 0xf2b20a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00330000: {
|
|
// 0xf2b30a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00340000: {
|
|
// 0xf2b40a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00350000: {
|
|
// 0xf2b50a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00360000: {
|
|
// 0xf2b60a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00370000: {
|
|
// 0xf2b70a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00380000: {
|
|
// 0xf2b80a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00390000: {
|
|
// 0xf2b90a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x003a0000: {
|
|
// 0xf2ba0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x003b0000: {
|
|
// 0xf2bb0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x003c0000: {
|
|
// 0xf2bc0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x003d0000: {
|
|
// 0xf2bd0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x003e0000: {
|
|
// 0xf2be0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x003f0000: {
|
|
// 0xf2bf0a10
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) &
|
|
0x7,
|
|
(instr >> 24) &
|
|
0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm =
|
|
ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x380000) == 0x0) ||
|
|
((instr & 0x3f0000) == 0x80000) ||
|
|
((instr & 0x3f0000) == 0x100000) ||
|
|
((instr & 0x3f0000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_4_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = imm6 - dt.GetSize();
|
|
// VSHLL{<c>}{<q>}.<type><size> <Qd>, <Dm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshll(al,
|
|
dt,
|
|
QRegister(rd),
|
|
DRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xf2800c10
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xf2800c10
|
|
switch (instr & 0x00200000) {
|
|
case 0x00000000: {
|
|
// 0xf2800c10
|
|
switch (instr & 0x00180000) {
|
|
case 0x00000000: {
|
|
// 0xf2800c10
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000200: {
|
|
// 0xf2800e10
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = ((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf2800f10
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = ((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xf2800c30
|
|
switch (instr & 0x00000f20) {
|
|
case 0x00000000: {
|
|
// 0xf2800c10
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xf2800c30
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2800e10
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000220: {
|
|
// 0xf2800e30
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf2800c10
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000420: {
|
|
// 0xf2800c30
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf2800e10
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000620: {
|
|
// 0xf2800e30
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf2800c10
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000820: {
|
|
// 0xf2800c30
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf2800e10
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000a20: {
|
|
// 0xf2800e30
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xf2800c10
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000c20: {
|
|
// 0xf2800c30
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xf2800d10
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000d20: {
|
|
// 0xf2800d30
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000e00: {
|
|
// 0xf2800e10
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000e20: {
|
|
// 0xf2800e30
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000f00: {
|
|
// 0xf2800f10
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = ((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
DOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Dd>, #<imm> ; A1
|
|
vmov(al, dt, DRegister(rd), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if ((instr & 0x00000200) == 0x00000200) {
|
|
if (((instr & 0x200000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt1 = Dt_op_U_1_Decode1(
|
|
((instr >> 24) & 0x1) | ((instr >> 7) & 0x2));
|
|
if (dt1.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt2 = Dt_op_U_1_Decode2(
|
|
((instr >> 24) & 0x1) | ((instr >> 7) & 0x2));
|
|
if (dt2.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
uint32_t fbits = 64 - ((instr >> 16) & 0x3f);
|
|
// VCVT{<c>}{<q>}.<dt>.<dt> <Dd>, <Dm>, #<fbits> ; A1 NOLINT(whitespace/line_length)
|
|
vcvt(al,
|
|
dt1,
|
|
dt2,
|
|
DRegister(rd),
|
|
DRegister(rm),
|
|
fbits);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0xf2800050
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000000: {
|
|
// 0xf2800050
|
|
switch (instr & 0x00380080) {
|
|
case 0x00000000: {
|
|
// 0xf2800050
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xf2800050
|
|
switch (instr & 0x00000200) {
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xf2800070
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
|
|
vmvn(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = ((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800150
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000000: {
|
|
// 0xf2800150
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt = ImmediateVorr::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
QOperand imm = ImmediateVorr::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) | ((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vorr(al, dt, QRegister(rd), QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xf2800170
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt = ImmediateVbic::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
QOperand imm = ImmediateVbic::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) | ((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vbic(al, dt, QRegister(rd), QRegister(rd), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf2800050
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8),
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64 : (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshr(al, dt, QRegister(rd), QRegister(rm), imm);
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800150
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8),
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64 : (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vsra(al, dt, QRegister(rd), QRegister(rm), imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2800250
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8),
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64 : (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VRSHR{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vrshr(al, dt, QRegister(rd), QRegister(rm), imm);
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf2800350
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8),
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64 : (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VRSRA{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vrsra(al, dt, QRegister(rd), QRegister(rm), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf2800450
|
|
switch (instr & 0x00380080) {
|
|
case 0x00000000: {
|
|
// 0xf2800450
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xf2800450
|
|
switch (instr & 0x00000200) {
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xf2800470
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
|
|
vmvn(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = ((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800550
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000000: {
|
|
// 0xf2800550
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt = ImmediateVorr::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
QOperand imm = ImmediateVorr::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) | ((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vorr(al, dt, QRegister(rd), QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xf2800570
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt = ImmediateVbic::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
QOperand imm = ImmediateVbic::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) | ((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vbic(al, dt, QRegister(rd), QRegister(rd), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf2800450
|
|
if ((instr & 0x01000000) == 0x01000000) {
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_L_imm6_4_Decode(
|
|
((instr >> 19) & 0x7) | ((instr >> 4) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
(dt.IsSize(64) ? 64 : (dt.GetSize() * 2)) -
|
|
imm6;
|
|
// VSRI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
|
|
vsri(al, dt, QRegister(rd), QRegister(rm), imm);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800550
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2800550
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_3_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - (dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VSHL{<c>}{<q>}.I<size> {<Qd>}, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vshl(al, dt, QRegister(rd), QRegister(rm), imm);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3800550
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_4_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - (dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VSLI{<c>}{<q>}.<dt> {<Qd>}, <Qm>, #<imm> ; A1
|
|
vsli(al, dt, QRegister(rd), QRegister(rm), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2800650
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_2_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8),
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - (dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VQSHLU{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqshlu(al, dt, QRegister(rd), QRegister(rm), imm);
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf2800750
|
|
if (((instr & 0x380080) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_L_imm6_1_Decode(((instr >> 19) & 0x7) |
|
|
((instr >> 4) & 0x8),
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm =
|
|
imm6 - (dt.IsSize(64) ? 0 : dt.GetSize());
|
|
// VQSHL{<c>}{<q>}.<type><size> {<Qd>}, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqshl(al, dt, QRegister(rd), QRegister(rm), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf2800850
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xf2800850
|
|
switch (instr & 0x00380000) {
|
|
case 0x00000000: {
|
|
// 0xf2800850
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0xf2800850
|
|
switch (instr & 0x00000200) {
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xf2800870
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
|
|
vmvn(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = ((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800950
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000000: {
|
|
// 0xf2800950
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVorr::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVorr::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VORR{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vorr(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xf2800970
|
|
if (((instr & 0x100) == 0x0) ||
|
|
((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVbic::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVbic::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VBIC{<c>}{<q>}.<dt> {<Qdn>}, <Qdn>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vbic(al,
|
|
dt,
|
|
QRegister(rd),
|
|
QRegister(rd),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf2800850
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0xf2800850
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_3_Decode((instr >> 19) & 0x7);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VRSHRN{<c>}{<q>}.I<size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vrshrn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0xf3800850
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_2_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQRSHRUN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqrshrun(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf2800950
|
|
if (((instr & 0x380000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_imm6_1_Decode((instr >> 19) & 0x7,
|
|
(instr >> 24) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t imm6 = (instr >> 16) & 0x3f;
|
|
uint32_t imm = dt.GetSize() - imm6;
|
|
// VQRSHRN{<c>}{<q>}.<type><size> <Dd>, <Qm>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vqrshrn(al,
|
|
dt,
|
|
DRegister(rd),
|
|
QRegister(rm),
|
|
imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xf2800c50
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0xf2800c50
|
|
switch (instr & 0x00200000) {
|
|
case 0x00000000: {
|
|
// 0xf2800c50
|
|
switch (instr & 0x00180000) {
|
|
case 0x00000000: {
|
|
// 0xf2800c50
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000200: {
|
|
// 0xf2800e50
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = ((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf2800f50
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = ((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000020) {
|
|
case 0x00000020: {
|
|
// 0xf2800c70
|
|
switch (instr & 0x00000f20) {
|
|
case 0x00000000: {
|
|
// 0xf2800c50
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0xf2800c70
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf2800e50
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000220: {
|
|
// 0xf2800e70
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf2800c50
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000420: {
|
|
// 0xf2800c70
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf2800e50
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000620: {
|
|
// 0xf2800e70
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf2800c50
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000820: {
|
|
// 0xf2800c70
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf2800e50
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000a20: {
|
|
// 0xf2800e70
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xf2800c50
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000c20: {
|
|
// 0xf2800c70
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000d00: {
|
|
// 0xf2800d50
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000d20: {
|
|
// 0xf2800d70
|
|
if (((instr & 0xd00) == 0x100) ||
|
|
((instr & 0xd00) == 0x500) ||
|
|
((instr & 0xd00) == 0x900) ||
|
|
((instr & 0xe00) == 0xe00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = (instr >> 8) & 0xf;
|
|
DataType dt =
|
|
ImmediateVmvn::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmvn::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMVN{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmvn(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000e00: {
|
|
// 0xf2800e50
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000e20: {
|
|
// 0xf2800e70
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
case 0x00000f00: {
|
|
// 0xf2800f50
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode =
|
|
((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1 NOLINT(whitespace/line_length)
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0x920) == 0x100) ||
|
|
((instr & 0x520) == 0x100) ||
|
|
((instr & 0x820) == 0x20) ||
|
|
((instr & 0x420) == 0x20) ||
|
|
((instr & 0x220) == 0x20) ||
|
|
((instr & 0x120) == 0x120)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned cmode = ((instr >> 8) & 0xf) |
|
|
((instr >> 1) & 0x10);
|
|
DataType dt =
|
|
ImmediateVmov::DecodeDt(cmode);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd =
|
|
ExtractQRegister(instr, 22, 12);
|
|
QOperand imm =
|
|
ImmediateVmov::DecodeImmediate(
|
|
cmode,
|
|
(instr & 0xf) |
|
|
((instr >> 12) & 0x70) |
|
|
((instr >> 17) & 0x80));
|
|
// VMOV{<c>}{<q>}.<dt> <Qd>, #<imm> ; A1
|
|
vmov(al, dt, QRegister(rd), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if ((instr & 0x00000200) == 0x00000200) {
|
|
if (((instr & 0x200000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt1 = Dt_op_U_1_Decode1(
|
|
((instr >> 24) & 0x1) | ((instr >> 7) & 0x2));
|
|
if (dt1.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt2 = Dt_op_U_1_Decode2(
|
|
((instr >> 24) & 0x1) | ((instr >> 7) & 0x2));
|
|
if (dt2.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 12) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 22, 12);
|
|
if ((instr & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rm = ExtractQRegister(instr, 5, 0);
|
|
uint32_t fbits = 64 - ((instr >> 16) & 0x3f);
|
|
// VCVT{<c>}{<q>}.<dt>.<dt> <Qd>, <Qm>, #<fbits> ; A1 NOLINT(whitespace/line_length)
|
|
vcvt(al,
|
|
dt1,
|
|
dt2,
|
|
QRegister(rd),
|
|
QRegister(rm),
|
|
fbits);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x04000000: {
|
|
// 0xf4000000
|
|
switch (instr & 0x01300000) {
|
|
case 0x00000000: {
|
|
// 0xf4000000
|
|
switch (instr & 0x00800000) {
|
|
case 0x00000000: {
|
|
// 0xf4000000
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf400000d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf400000d
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000000: {
|
|
// 0xf400000d
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vst4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf400010d
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vst4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf400020d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vst1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf400030d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vst2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf400040d
|
|
if (((instr & 0x20) == 0x20)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vst3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf400050d
|
|
if (((instr & 0x20) == 0x20)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vst3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf400060d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vst1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xf400070d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vst1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf400080d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vst2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf400090d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vst2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf4000a0d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vst1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf400000f
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000000: {
|
|
// 0xf400000d
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vst4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf400010d
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vst4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf400020d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vst1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf400030d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vst2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf400040d
|
|
if (((instr & 0x20) == 0x20)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vst3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf400050d
|
|
if (((instr & 0x20) == 0x20)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vst3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf400060d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vst1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xf400070d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vst1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf400080d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vst2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf400090d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vst2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf4000a0d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vst1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000000: {
|
|
// 0xf4000000
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first + (length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vst4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf4000100
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first + (length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vst4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf4000200
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vst1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf4000300
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first + (length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vst2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf4000400
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0x20) == 0x20)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first + (length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vst3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf4000500
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0x20) == 0x20)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first + (length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vst3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf4000600
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vst1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xf4000700
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vst1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf4000800
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first + (length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vst2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf4000900
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first + (length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vst2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf4000a00
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_5_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vst1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xf4800000
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf4800000
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000c00: {
|
|
// 0xf4800c00
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf480000d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf480000d
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_1_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 1;
|
|
unsigned last = first + length - 1;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vst1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf480000f
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_1_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 1;
|
|
unsigned last = first + length - 1;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 NOLINT(whitespace/line_length)
|
|
vst1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_1_Decode((instr >> 4) & 0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 1;
|
|
unsigned last = first + length - 1;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vst1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf4800100
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000c00: {
|
|
// 0xf4800d00
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf480010d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf480010d
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_2_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 2;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vst2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf480010f
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_2_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 2;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 NOLINT(whitespace/line_length)
|
|
vst2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_2_Decode((instr >> 4) & 0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 2;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vst2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf4800200
|
|
switch (instr & 0x00000c30) {
|
|
case 0x00000010: {
|
|
// 0xf4800210
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
case 0x00000030: {
|
|
// 0xf4800230
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
case 0x00000410: {
|
|
// 0xf4800610
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
case 0x00000430: {
|
|
// 0xf4800630
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
case 0x00000810: {
|
|
// 0xf4800a10
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
case 0x00000820: {
|
|
// 0xf4800a20
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
case 0x00000830: {
|
|
// 0xf4800a30
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
case 0x00000c00: {
|
|
// 0xf4800e00
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
case 0x00000c10: {
|
|
// 0xf4800e10
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
case 0x00000c20: {
|
|
// 0xf4800e20
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
case 0x00000c30: {
|
|
// 0xf4800e30
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf480020d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf480020d
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0x810) == 0x10) ||
|
|
((instr & 0xc30) == 0x810) ||
|
|
((instr & 0xc30) == 0x820) ||
|
|
((instr & 0xc30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeon decode_neon =
|
|
Index_1_Decode((instr >> 4) & 0xf, dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 3;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
|
|
vst3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
MemOperand(Register(rn), PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf480020f
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0x810) == 0x10) ||
|
|
((instr & 0xc30) == 0x810) ||
|
|
((instr & 0xc30) == 0x820) ||
|
|
((instr & 0xc30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeon decode_neon =
|
|
Index_1_Decode((instr >> 4) & 0xf, dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 3;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
|
|
vst3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
MemOperand(Register(rn), Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd) ||
|
|
((instr & 0x810) == 0x10) ||
|
|
((instr & 0xc30) == 0x810) ||
|
|
((instr & 0xc30) == 0x820) ||
|
|
((instr & 0xc30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeon decode_neon =
|
|
Index_1_Decode((instr >> 4) & 0xf, dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 3;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
// VST3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
|
|
vst3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf4800300
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000c00: {
|
|
// 0xf4800f00
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf480030d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf480030d
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_3_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 4;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vst4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf480030f
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_3_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 4;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 NOLINT(whitespace/line_length)
|
|
vst4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_3_Decode((instr >> 4) & 0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 4;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VST4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vst4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0xf4100000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00400000: {
|
|
// 0xf4500000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xf45f0000
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xfff;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// PLI{<c>}{<q>} <label> ; A1
|
|
if (minus_zero) {
|
|
pli(al, MemOperand(pc, minus, 0));
|
|
} else {
|
|
pli(al, &location);
|
|
}
|
|
if (((instr & 0xff7ff000) != 0xf45ff000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xfff;
|
|
// PLI{<c>}{<q>} [<Rn>{, #{+/-}<imm_3>}] ; A1
|
|
pli(al, MemOperand(Register(rn), sign, offset, Offset));
|
|
if (((instr & 0xff70f000) != 0xf450f000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0xf4200000
|
|
switch (instr & 0x00800000) {
|
|
case 0x00000000: {
|
|
// 0xf4200000
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf420000d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf420000d
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000000: {
|
|
// 0xf420000d
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf420010d
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf420020d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf420030d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf420040d
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf420050d
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf420060d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xf420070d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf420080d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf420090d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf4200a0d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf420000f
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000000: {
|
|
// 0xf420000d
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vld4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf420010d
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vld4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf420020d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf420030d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vld2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf420040d
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vld3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf420050d
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vld3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf420060d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xf420070d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf420080d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vld2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf420090d
|
|
if (((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vld2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf4200a0d
|
|
if (((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000f00) {
|
|
case 0x00000000: {
|
|
// 0xf4200000
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first + (length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf4200100
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_4_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first + (length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf4200200
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf4200300
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first + (length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000400: {
|
|
// 0xf4200400
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first + (length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000500: {
|
|
// 0xf4200500
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_3_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x4:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x5:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first + (length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000600: {
|
|
// 0xf4200600
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000700: {
|
|
// 0xf4200700
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000800: {
|
|
// 0xf4200800
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first + (length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000900: {
|
|
// 0xf4200900
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe30) == 0x830)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_2_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x8:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x9:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
case 0x3:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first + (length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000a00: {
|
|
// 0xf4200a00
|
|
if (((instr & 0xd) == 0xd) ||
|
|
((instr & 0xe20) == 0x620) ||
|
|
((instr & 0xf30) == 0xa30)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_6_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_align_1_Decode((instr >> 4) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 8) & 0xf) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x7:
|
|
length = 1;
|
|
break;
|
|
case 0xa:
|
|
length = 2;
|
|
break;
|
|
case 0x6:
|
|
length = 3;
|
|
break;
|
|
case 0x2:
|
|
length = 4;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kMultipleLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0xf4a00000
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0xf4a00000
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000c00: {
|
|
// 0xf4a00c00
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf4a00c0d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf4a00c0d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_1_Decode((instr >> 4) & 0x1, dt);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 1;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf4a00c0f
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_1_Decode((instr >> 4) & 0x1, dt);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 1;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 NOLINT(whitespace/line_length)
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_1_Decode((instr >> 4) & 0x1, dt);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing = kSingle;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 1;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
break;
|
|
}
|
|
unsigned last = first + length - 1;
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf4a0000d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf4a0000d
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_1_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 1;
|
|
unsigned last = first + length - 1;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf4a0000f
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_1_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 1;
|
|
unsigned last = first + length - 1;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 NOLINT(whitespace/line_length)
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_1_Decode((instr >> 4) & 0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 1;
|
|
unsigned last = first + length - 1;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD1{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld1(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0xf4a00100
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000c00: {
|
|
// 0xf4a00d00
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf4a00d0d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf4a00d0d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_2_Decode((instr >> 4) & 0x1, dt);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf4a00d0f
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_2_Decode((instr >> 4) & 0x1, dt);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 NOLINT(whitespace/line_length)
|
|
vld2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_2_Decode((instr >> 4) & 0x1, dt);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 2;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 2;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf4a0010d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf4a0010d
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_2_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 2;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf4a0010f
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_2_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 2;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 NOLINT(whitespace/line_length)
|
|
vld2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_2_Decode((instr >> 4) & 0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 2;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD2{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld2(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0xf4a00200
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000c00: {
|
|
// 0xf4a00e00
|
|
switch (instr & 0x00000010) {
|
|
case 0x00000000: {
|
|
// 0xf4a00e00
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf4a00e0d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf4a00e0d
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
|
|
vld3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
MemOperand(Register(rn), PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf4a00e0f
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) *
|
|
(spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
|
|
vld3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
MemOperand(Register(rn), Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 3;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 3;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf4a0020d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf4a0020d
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeon decode_neon =
|
|
Index_1_Decode((instr >> 4) & 0xf, dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 3;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>]! ; A1
|
|
vld3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
MemOperand(Register(rn), PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf4a0020f
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeon decode_neon =
|
|
Index_1_Decode((instr >> 4) & 0xf, dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 3;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>] ; A1
|
|
vld3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
MemOperand(Register(rn), Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeon decode_neon =
|
|
Index_1_Decode((instr >> 4) & 0xf, dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 3;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(plus);
|
|
unsigned rm = instr & 0xf;
|
|
// VLD3{<c>}{<q>}.<dt> <list>, [<Rn>], #<Rm> ; A1
|
|
vld3(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0xf4a00300
|
|
switch (instr & 0x00000c00) {
|
|
case 0x00000c00: {
|
|
// 0xf4a00f00
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf4a00f0d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf4a00f0d
|
|
DataType dt =
|
|
Dt_size_8_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_3_Decode((instr >> 4) & 0x1,
|
|
dt,
|
|
(instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf4a00f0f
|
|
DataType dt =
|
|
Dt_size_8_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_3_Decode((instr >> 4) & 0x1,
|
|
dt,
|
|
(instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 NOLINT(whitespace/line_length)
|
|
vld4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_8_Decode((instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align =
|
|
Align_a_3_Decode((instr >> 4) & 0x1,
|
|
dt,
|
|
(instr >> 6) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid) ||
|
|
align.Is(kBadAlignment)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length;
|
|
SpacingType spacing;
|
|
switch ((instr >> 5) & 0x1) {
|
|
default:
|
|
VIXL_UNREACHABLE_OR_FALLTHROUGH();
|
|
case 0x0:
|
|
length = 4;
|
|
spacing = kSingle;
|
|
break;
|
|
case 0x1:
|
|
length = 4;
|
|
spacing = kDouble;
|
|
break;
|
|
}
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
TransferType transfer = kAllLanes;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
transfer),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x0000000d) {
|
|
case 0x0000000d: {
|
|
// 0xf4a0030d
|
|
switch (instr & 0x00000002) {
|
|
case 0x00000000: {
|
|
// 0xf4a0030d
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_3_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 4;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}]! ; A1 NOLINT(whitespace/line_length)
|
|
vld4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0xf4a0030f
|
|
if (((instr & 0xc00) == 0xc00)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt =
|
|
Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_3_Decode((instr >> 4) &
|
|
0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first =
|
|
ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 4;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}] ; A1 NOLINT(whitespace/line_length)
|
|
vld4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xc00) == 0xc00) ||
|
|
((instr & 0xd) == 0xd)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DataType dt = Dt_size_7_Decode((instr >> 10) & 0x3);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
DecodeNeonAndAlign decode_neon =
|
|
Align_index_align_3_Decode((instr >> 4) & 0xf,
|
|
dt);
|
|
if (!decode_neon.IsValid()) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Alignment align = decode_neon.GetAlign();
|
|
int lane = decode_neon.GetLane();
|
|
SpacingType spacing = decode_neon.GetSpacing();
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned length = 4;
|
|
unsigned last =
|
|
first +
|
|
(length - 1) * (spacing == kSingle ? 1 : 2);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// VLD4{<c>}{<q>}.<dt> <list>, [<Rn>{:<align>}], <Rm> ; A1 NOLINT(whitespace/line_length)
|
|
vld4(al,
|
|
dt,
|
|
NeonRegisterList(DRegister(first),
|
|
DRegister(last),
|
|
spacing,
|
|
lane),
|
|
AlignedMemOperand(Register(rn),
|
|
align,
|
|
Register(rm),
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01100000: {
|
|
// 0xf5100000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0xf51f0000
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xfff;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// PLD{<c>}{<q>} <label> ; A1
|
|
if (minus_zero) {
|
|
pld(al, MemOperand(pc, minus, 0));
|
|
} else {
|
|
pld(al, &location);
|
|
}
|
|
if (((instr & 0xff7ff000) != 0xf55ff000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0xf5100000
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xfff;
|
|
// PLDW{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
|
|
pldw(al, MemOperand(Register(rn), sign, offset, Offset));
|
|
if (((instr & 0xff70f000) != 0xf510f000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xf5500000
|
|
if (((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xfff;
|
|
// PLD{<c>}{<q>} [<Rn>{, #{+/-}<imm_2>}] ; A1
|
|
pld(al, MemOperand(Register(rn), sign, offset, Offset));
|
|
if (((instr & 0xff70f000) != 0xf550f000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01300000: {
|
|
// 0xf5300000
|
|
switch (instr & 0x00c000f0) {
|
|
case 0x00400010: {
|
|
// 0xf5700010
|
|
// CLREX{<c>}{<q>} ; A1
|
|
clrex(al);
|
|
if (((instr & 0xffffffff) != 0xf57ff01f)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400040: {
|
|
// 0xf5700040
|
|
MemoryBarrier option(instr & 0xf);
|
|
// DSB{<c>}{<q>} {<option>} ; A1
|
|
dsb(al, option);
|
|
if (((instr & 0xfffffff0) != 0xf57ff040)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400050: {
|
|
// 0xf5700050
|
|
MemoryBarrier option(instr & 0xf);
|
|
// DMB{<c>}{<q>} {<option>} ; A1
|
|
dmb(al, option);
|
|
if (((instr & 0xfffffff0) != 0xf57ff050)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400060: {
|
|
// 0xf5700060
|
|
MemoryBarrier option(instr & 0xf);
|
|
// ISB{<c>}{<q>} {<option>} ; A1
|
|
isb(al, option);
|
|
if (((instr & 0xfffffff0) != 0xf57ff060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x06000000: {
|
|
// 0xf6000000
|
|
switch (instr & 0x01700010) {
|
|
case 0x00500000: {
|
|
// 0xf6500000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0xf6500060
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift = RRX;
|
|
uint32_t amount = 0;
|
|
AddrMode addrmode = Offset;
|
|
// PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
|
|
pli(al,
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
if (((instr & 0xff70fff0) != 0xf650f060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
Shift shift = shift_operand.GetShift();
|
|
uint32_t amount = shift_operand.GetAmount();
|
|
AddrMode addrmode = Offset;
|
|
// PLI{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
|
|
pli(al,
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
if (((instr & 0xff70f010) != 0xf650f000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01100000: {
|
|
// 0xf7100000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0xf7100060
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift = RRX;
|
|
uint32_t amount = 0;
|
|
AddrMode addrmode = Offset;
|
|
// PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
|
|
pldw(al,
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
if (((instr & 0xff70fff0) != 0xf710f060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
Shift shift = shift_operand.GetShift();
|
|
uint32_t amount = shift_operand.GetAmount();
|
|
AddrMode addrmode = Offset;
|
|
// PLDW{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
|
|
pldw(al,
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
if (((instr & 0xff70f010) != 0xf710f000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01500000: {
|
|
// 0xf7500000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0xf7500060
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift = RRX;
|
|
uint32_t amount = 0;
|
|
AddrMode addrmode = Offset;
|
|
// PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>, RRX] ; A1
|
|
pld(al,
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
if (((instr & 0xff70fff0) != 0xf750f060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
Shift shift = shift_operand.GetShift();
|
|
uint32_t amount = shift_operand.GetAmount();
|
|
AddrMode addrmode = Offset;
|
|
// PLD{<c>}{<q>} [<Rn>, {+/-}<Rm>{, <shift> #<amount_1>}] ; A1
|
|
pld(al,
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
if (((instr & 0xff70f010) != 0xf750f000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x08000000: {
|
|
// 0xf8000000
|
|
switch (instr & 0x01d00000) {
|
|
case 0x00100000: {
|
|
// 0xf8100000
|
|
UnimplementedA32("RFEDA", instr);
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0xf8400000
|
|
UnimplementedA32("SRSDA", instr);
|
|
break;
|
|
}
|
|
case 0x00900000: {
|
|
// 0xf8900000
|
|
UnimplementedA32("RFE{IA}", instr);
|
|
break;
|
|
}
|
|
case 0x00c00000: {
|
|
// 0xf8c00000
|
|
UnimplementedA32("SRS{IA}", instr);
|
|
break;
|
|
}
|
|
case 0x01100000: {
|
|
// 0xf9100000
|
|
UnimplementedA32("RFEDB", instr);
|
|
break;
|
|
}
|
|
case 0x01400000: {
|
|
// 0xf9400000
|
|
UnimplementedA32("SRSDB", instr);
|
|
break;
|
|
}
|
|
case 0x01900000: {
|
|
// 0xf9900000
|
|
UnimplementedA32("RFEIB", instr);
|
|
break;
|
|
}
|
|
case 0x01c00000: {
|
|
// 0xf9c00000
|
|
UnimplementedA32("SRSIB", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x0a000000: {
|
|
// 0xfa000000
|
|
int32_t imm = SignExtend<int32_t>((((instr >> 24) & 0x1) |
|
|
((instr << 1) & 0x1fffffe))
|
|
<< 1,
|
|
26);
|
|
Location location(imm, kA32PcDelta);
|
|
// BLX{<c>}{<q>} <label> ; A2
|
|
blx(al, &location);
|
|
break;
|
|
}
|
|
case 0x0e000000: {
|
|
// 0xfe000000
|
|
switch (instr & 0x01b00f50) {
|
|
case 0x00000a00: {
|
|
// 0xfe000a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VSELEQ.F32 <Sd>, <Sn>, <Sm> ; A1
|
|
vseleq(F32, SRegister(rd), SRegister(rn), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000b00: {
|
|
// 0xfe000b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSELEQ.F64 <Dd>, <Dn>, <Dm> ; A1
|
|
vseleq(F64, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00100a00: {
|
|
// 0xfe100a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VSELVS.F32 <Sd>, <Sn>, <Sm> ; A1
|
|
vselvs(F32, SRegister(rd), SRegister(rn), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00100b00: {
|
|
// 0xfe100b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSELVS.F64 <Dd>, <Dn>, <Dm> ; A1
|
|
vselvs(F64, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200a00: {
|
|
// 0xfe200a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VSELGE.F32 <Sd>, <Sn>, <Sm> ; A1
|
|
vselge(F32, SRegister(rd), SRegister(rn), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200b00: {
|
|
// 0xfe200b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSELGE.F64 <Dd>, <Dn>, <Dm> ; A1
|
|
vselge(F64, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00300a00: {
|
|
// 0xfe300a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VSELGT.F32 <Sd>, <Sn>, <Sm> ; A1
|
|
vselgt(F32, SRegister(rd), SRegister(rn), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00300b00: {
|
|
// 0xfe300b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSELGT.F64 <Dd>, <Dn>, <Dm> ; A1
|
|
vselgt(F64, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00800a00: {
|
|
// 0xfe800a00
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VMAXNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
|
|
vmaxnm(F32, SRegister(rd), SRegister(rn), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00800a40: {
|
|
// 0xfe800a40
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VMINNM{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
|
|
vminnm(F32, SRegister(rd), SRegister(rn), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00800b00: {
|
|
// 0xfe800b00
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMAXNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
|
|
vmaxnm(F64, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00800b40: {
|
|
// 0xfe800b40
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMINNM{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
|
|
vminnm(F64, DRegister(rd), DRegister(rn), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00b00a40: {
|
|
// 0xfeb00a40
|
|
switch (instr & 0x000f0000) {
|
|
case 0x00080000: {
|
|
// 0xfeb80a40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VRINTA{<q>}.F32 <Sd>, <Sm> ; A1
|
|
vrinta(F32, SRegister(rd), SRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00090000: {
|
|
// 0xfeb90a40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VRINTN{<q>}.F32 <Sd>, <Sm> ; A1
|
|
vrintn(F32, SRegister(rd), SRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000a0000: {
|
|
// 0xfeba0a40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VRINTP{<q>}.F32 <Sd>, <Sm> ; A1
|
|
vrintp(F32, SRegister(rd), SRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000b0000: {
|
|
// 0xfebb0a40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VRINTM{<q>}.F32 <Sd>, <Sm> ; A1
|
|
vrintm(F32, SRegister(rd), SRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000c0000: {
|
|
// 0xfebc0a40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTA{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
|
|
vcvta(dt, F32, SRegister(rd), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000d0000: {
|
|
// 0xfebd0a40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTN{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
|
|
vcvtn(dt, F32, SRegister(rd), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000e0000: {
|
|
// 0xfebe0a40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTP{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
|
|
vcvtp(dt, F32, SRegister(rd), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000f0000: {
|
|
// 0xfebf0a40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTM{<q>}.<dt>.F32 <Sd>, <Sm> ; A1
|
|
vcvtm(dt, F32, SRegister(rd), SRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00b00b40: {
|
|
// 0xfeb00b40
|
|
switch (instr & 0x000f0000) {
|
|
case 0x00080000: {
|
|
// 0xfeb80b40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTA{<q>}.F64 <Dd>, <Dm> ; A1
|
|
vrinta(F64, DRegister(rd), DRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00090000: {
|
|
// 0xfeb90b40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTN{<q>}.F64 <Dd>, <Dm> ; A1
|
|
vrintn(F64, DRegister(rd), DRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000a0000: {
|
|
// 0xfeba0b40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTP{<q>}.F64 <Dd>, <Dm> ; A1
|
|
vrintp(F64, DRegister(rd), DRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000b0000: {
|
|
// 0xfebb0b40
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTM{<q>}.F64 <Dd>, <Dm> ; A1
|
|
vrintm(F64, DRegister(rd), DRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000c0000: {
|
|
// 0xfebc0b40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTA{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
|
|
vcvta(dt, F64, SRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000d0000: {
|
|
// 0xfebd0b40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTN{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
|
|
vcvtn(dt, F64, SRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000e0000: {
|
|
// 0xfebe0b40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTP{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
|
|
vcvtp(dt, F64, SRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x000f0000: {
|
|
// 0xfebf0b40
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTM{<q>}.<dt>.F64 <Sd>, <Dm> ; A1
|
|
vcvtm(dt, F64, SRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
} else {
|
|
switch (instr & 0x0e000000) {
|
|
case 0x00000000: {
|
|
// 0x00000000
|
|
switch (instr & 0x00100010) {
|
|
case 0x00000000: {
|
|
// 0x00000000
|
|
switch (instr & 0x01a00000) {
|
|
case 0x00000000: {
|
|
// 0x00000000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x00000000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00000060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
and_(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
and_(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x00400000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000d0000: {
|
|
// 0x004d0000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x004d0060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SUB{<c>}{<q>} {<Rd>}, SP, <Rm>, RRX ; A1
|
|
sub(condition,
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) &
|
|
0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// SUB{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
sub(condition,
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00400060
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xd0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
sub(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xd0000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) &
|
|
0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
sub(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x00200000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x00200000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00200060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
eor(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
eor(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x00600000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00600060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
rsb(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
rsb(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x00800000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x00800000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000d0000: {
|
|
// 0x008d0000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x008d0060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ADD{<c>}{<q>} {<Rd>}, SP, <Rm>, RRX ; A1
|
|
add(condition,
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) &
|
|
0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// ADD{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
add(condition,
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00800060
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xd0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
add(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xd0000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) &
|
|
0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
add(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x00c00000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00c00060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
sbc(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
sbc(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00a00000: {
|
|
// 0x00a00000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x00a00000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00a00060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
adc(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
adc(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x00e00000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00e00060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
rsc(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
rsc(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x01000000
|
|
switch (instr & 0x000000e0) {
|
|
case 0x00000000: {
|
|
// 0x01000000
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0x01000000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned spec_reg = (instr >> 22) & 0x1;
|
|
// MRS{<c>}{<q>} <Rd>, <spec_reg> ; A1
|
|
mrs(condition, Register(rd), SpecialRegister(spec_reg));
|
|
if (((instr & 0xfbf0fff) != 0x10f0000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0x01000200
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("MRS", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0x01000040
|
|
switch (instr & 0x00400200) {
|
|
case 0x00000000: {
|
|
// 0x01000040
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CRC32B{<q>} <Rd>, <Rn>, <Rm> ; A1
|
|
crc32b(al, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x1000040)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0x01000240
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CRC32CB{<q>} <Rd>, <Rn>, <Rm> ; A1
|
|
crc32cb(al, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x1000240)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x01400040
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CRC32W{<q>} <Rd>, <Rn>, <Rm> ; A1
|
|
crc32w(al, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x1400040)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400200: {
|
|
// 0x01400240
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CRC32CW{<q>} <Rd>, <Rn>, <Rm> ; A1
|
|
crc32cw(al, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x1400240)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x01000080
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x01000080
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLABB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
smlabb(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x01400080
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMLALBB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
smlalbb(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000a0: {
|
|
// 0x010000a0
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x010000a0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLATB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
smlatb(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x014000a0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMLALTB{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
smlaltb(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000c0: {
|
|
// 0x010000c0
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x010000c0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLABT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
smlabt(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x014000c0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMLALBT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
smlalbt(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000e0: {
|
|
// 0x010000e0
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x010000e0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLATT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
smlatt(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x014000e0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMLALTT{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
smlaltt(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x01200000
|
|
switch (instr & 0x000000e0) {
|
|
case 0x00000000: {
|
|
// 0x01200000
|
|
switch (instr & 0x00000200) {
|
|
case 0x00000000: {
|
|
// 0x01200000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned spec_reg =
|
|
((instr >> 16) & 0xf) | ((instr >> 18) & 0x10);
|
|
unsigned rn = instr & 0xf;
|
|
// MSR{<c>}{<q>} <spec_reg>, <Rn> ; A1
|
|
msr(condition,
|
|
MaskedSpecialRegister(spec_reg),
|
|
Register(rn));
|
|
if (((instr & 0xfb0fff0) != 0x120f000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0x01200200
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("MSR", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0x01200020
|
|
if ((instr & 0x00400000) == 0x00000000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rm = instr & 0xf;
|
|
// BXJ{<c>}{<q>} <Rm> ; A1
|
|
bxj(condition, Register(rm));
|
|
if (((instr & 0xffffff0) != 0x12fff20)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0x01200040
|
|
switch (instr & 0x00400200) {
|
|
case 0x00000000: {
|
|
// 0x01200040
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CRC32H{<q>} <Rd>, <Rn>, <Rm> ; A1
|
|
crc32h(al, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x1200040)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0x01200240
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CRC32CH{<q>} <Rd>, <Rn>, <Rm> ; A1
|
|
crc32ch(al, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x1200240)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000060: {
|
|
// 0x01200060
|
|
if ((instr & 0x00400000) == 0x00400000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("ERET", instr);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x01200080
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x01200080
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLAWB{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
smlawb(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x01600080
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMULBB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
smulbb(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xff0f0f0) != 0x1600080)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000a0: {
|
|
// 0x012000a0
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x012000a0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMULWB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
smulwb(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xff0f0f0) != 0x12000a0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x016000a0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMULTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
smultb(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xff0f0f0) != 0x16000a0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000c0: {
|
|
// 0x012000c0
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x012000c0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLAWT{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
smlawt(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x016000c0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMULBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
smulbt(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xff0f0f0) != 0x16000c0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000e0: {
|
|
// 0x012000e0
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x012000e0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMULWT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
smulwt(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xff0f0f0) != 0x12000e0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x016000e0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMULTT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
smultt(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xff0f0f0) != 0x16000e0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01800000: {
|
|
// 0x01800000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x01800000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x01800060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
orr(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
orr(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x01c00000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x01c00060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
bic(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
bic(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01a00000: {
|
|
// 0x01a00000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x01a00000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x01a00060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// RRX{<c>}{<q>} {<Rd>}, <Rm> ; A1
|
|
rrx(condition, Register(rd), Register(rm));
|
|
if (((instr & 0xfff0ff0) != 0x1a00060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// MOV{<c>}{<q>} <Rd>, <Rm>, RRX ; A1
|
|
mov(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0ff0) != 0x1a00060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) ==
|
|
Uint32(0x2)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = (instr >> 7) & 0x1f;
|
|
if (amount == 0) amount = 32;
|
|
// ASR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
|
|
asr(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xfff0070) != 0x1a00040)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) ==
|
|
Uint32(0x0)) &&
|
|
((instr & 0xf0000000) != 0xf0000000) &&
|
|
((instr & 0x00000f80) != 0x00000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = (instr >> 7) & 0x1f;
|
|
// LSL{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
|
|
lsl(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xfff0070) != 0x1a00000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) ==
|
|
Uint32(0x1)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = (instr >> 7) & 0x1f;
|
|
if (amount == 0) amount = 32;
|
|
// LSR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
|
|
lsr(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xfff0070) != 0x1a00020)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) ==
|
|
Uint32(0x3)) &&
|
|
((instr & 0xf0000000) != 0xf0000000) &&
|
|
((instr & 0x00000f80) != 0x00000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = (instr >> 7) & 0x1f;
|
|
// ROR{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
|
|
ror(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
amount);
|
|
if (((instr & 0xfff0070) != 0x1a00060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// MOV{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
|
|
mov(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff0010) != 0x1a00000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x01e00000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x01e00060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// MVN{<c>}{<q>} <Rd>, <Rm>, RRX ; A1
|
|
mvn(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0ff0) != 0x1e00060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// MVN{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
|
|
mvn(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff0010) != 0x1e00000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000010: {
|
|
// 0x00000010
|
|
switch (instr & 0x00400080) {
|
|
case 0x00000000: {
|
|
// 0x00000010
|
|
switch (instr & 0x01a00000) {
|
|
case 0x00000000: {
|
|
// 0x00000010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// AND{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
and_(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x00200010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// EOR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
eor(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x00800010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// ADD{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
add(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x00a00000: {
|
|
// 0x00a00010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// ADC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
adc(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x01000010
|
|
switch (instr & 0x00000060) {
|
|
case 0x00000040: {
|
|
// 0x01000050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// QADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
|
|
qadd(condition,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rn));
|
|
if (((instr & 0xff00ff0) != 0x1000050)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000060: {
|
|
// 0x01000070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
uint32_t imm = (instr & 0xf) | ((instr >> 4) & 0xfff0);
|
|
// HLT{<q>} {#}<imm> ; A1
|
|
hlt(al, imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x01200010
|
|
switch (instr & 0x00000060) {
|
|
case 0x00000000: {
|
|
// 0x01200010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rm = instr & 0xf;
|
|
// BX{<c>}{<q>} <Rm> ; A1
|
|
bx(condition, Register(rm));
|
|
if (((instr & 0xffffff0) != 0x12fff10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0x01200030
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rm = instr & 0xf;
|
|
// BLX{<c>}{<q>} <Rm> ; A1
|
|
blx(condition, Register(rm));
|
|
if (((instr & 0xffffff0) != 0x12fff30)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0x01200050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// QSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
|
|
qsub(condition,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rn));
|
|
if (((instr & 0xff00ff0) != 0x1200050)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000060: {
|
|
// 0x01200070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
uint32_t imm = (instr & 0xf) | ((instr >> 4) & 0xfff0);
|
|
// BKPT{<q>} {#}<imm> ; A1
|
|
bkpt(al, imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01800000: {
|
|
// 0x01800010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// ORR{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
orr(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x01a00000: {
|
|
// 0x01a00010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) == Uint32(0x2)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// ASR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
|
|
asr(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
if (((instr & 0xfff00f0) != 0x1a00050)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) == Uint32(0x0)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// LSL{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
|
|
lsl(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
if (((instr & 0xfff00f0) != 0x1a00010)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) == Uint32(0x1)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// LSR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
|
|
lsr(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
if (((instr & 0xfff00f0) != 0x1a00030)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) == Uint32(0x3)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// ROR{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
|
|
ror(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
if (((instr & 0xfff00f0) != 0x1a00070)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// MOV{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
|
|
mov(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
if (((instr & 0xfff0090) != 0x1a00010)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x00000090
|
|
switch (instr & 0x01200060) {
|
|
case 0x00000000: {
|
|
// 0x00000090
|
|
switch (instr & 0x00800000) {
|
|
case 0x00000000: {
|
|
// 0x00000090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// MUL{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
|
|
mul(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xff0f0f0) != 0x90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x00800090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// UMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
umull(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0x000000b0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
// STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
|
|
strh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
PostIndex));
|
|
if (((instr & 0xf700ff0) != 0xb0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0x000000d0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
// LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
|
|
ldrd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
PostIndex));
|
|
if (((instr & 0xf700ff0) != 0xd0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000060: {
|
|
// 0x000000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
// STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<Rm> ; A1
|
|
strd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
PostIndex));
|
|
if (((instr & 0xf700ff0) != 0xf0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x00200090
|
|
switch (instr & 0x00800000) {
|
|
case 0x00000000: {
|
|
// 0x00200090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// MLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
mla(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x00a00090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// UMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
umlal(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200020: {
|
|
// 0x002000b0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("STRHT", instr);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x01000090
|
|
switch (instr & 0x00800300) {
|
|
case 0x00800000: {
|
|
// 0x01800090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STL{<c>}{<q>} <Rt>, [<Rn>] ; A1
|
|
stl(condition,
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff0fff0) != 0x180fc90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800200: {
|
|
// 0x01800290
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rt = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STLEX{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
|
|
stlex(condition,
|
|
Register(rd),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00ff0) != 0x1800e90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800300: {
|
|
// 0x01800390
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rt = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn>{, #<imm_1>}] ; A1
|
|
strex(condition,
|
|
Register(rd),
|
|
Register(rt),
|
|
MemOperand(Register(rn), plus, 0, Offset));
|
|
if (((instr & 0xff00ff0) != 0x1800f90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000020: {
|
|
// 0x010000b0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
AddrMode addrmode = Offset;
|
|
// STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
|
|
strh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
if (((instr & 0xf700ff0) != 0x10000b0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000040: {
|
|
// 0x010000d0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
AddrMode addrmode = Offset;
|
|
// LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
|
|
ldrd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
if (((instr & 0xf700ff0) != 0x10000d0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000060: {
|
|
// 0x010000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
AddrMode addrmode = Offset;
|
|
// STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>] ; A1
|
|
strd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
if (((instr & 0xf700ff0) != 0x10000f0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x01200090
|
|
switch (instr & 0x00800300) {
|
|
case 0x00800200: {
|
|
// 0x01a00290
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rt = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STLEXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
|
|
stlexd(condition,
|
|
Register(rd),
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00ff0) != 0x1a00e90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800300: {
|
|
// 0x01a00390
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rt = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STREXD{<c>}{<q>} <Rd>, <Rt>, <Rt2>, [<Rn>] ; A1
|
|
strexd(condition,
|
|
Register(rd),
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00ff0) != 0x1a00f90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200020: {
|
|
// 0x012000b0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
AddrMode addrmode = PreIndex;
|
|
// STRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
|
|
strh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
if (((instr & 0xf700ff0) != 0x12000b0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200040: {
|
|
// 0x012000d0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
AddrMode addrmode = PreIndex;
|
|
// LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
|
|
ldrd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
if (((instr & 0xf700ff0) != 0x12000d0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200060: {
|
|
// 0x012000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
AddrMode addrmode = PreIndex;
|
|
// STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>, #{+/-}<Rm>]! ; A1
|
|
strd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
if (((instr & 0xf700ff0) != 0x12000f0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x00400010
|
|
switch (instr & 0x01a00000) {
|
|
case 0x00000000: {
|
|
// 0x00400010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// SUB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
sub(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x00600010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// RSB{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
rsb(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x00c00010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// SBC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
sbc(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x00a00000: {
|
|
// 0x00e00010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// RSC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
rsc(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x01400010
|
|
switch (instr & 0x00000060) {
|
|
case 0x00000040: {
|
|
// 0x01400050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// QDADD{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
|
|
qdadd(condition,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rn));
|
|
if (((instr & 0xff00ff0) != 0x1400050)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000060: {
|
|
// 0x01400070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
uint32_t imm = (instr & 0xf) | ((instr >> 4) & 0xfff0);
|
|
// HVC{<q>} {#}<imm16> ; A1
|
|
hvc(al, imm);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x01600010
|
|
switch (instr & 0x00000060) {
|
|
case 0x00000000: {
|
|
// 0x01600010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CLZ{<c>}{<q>} <Rd>, <Rm> ; A1
|
|
clz(condition, Register(rd), Register(rm));
|
|
if (((instr & 0xfff0ff0) != 0x16f0f10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0x01600050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// QDSUB{<c>}{<q>} {<Rd>}, <Rm>, <Rn> ; A1
|
|
qdsub(condition,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rn));
|
|
if (((instr & 0xff00ff0) != 0x1600050)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000060: {
|
|
// 0x01600070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("SMC", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01800000: {
|
|
// 0x01c00010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// BIC{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
bic(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x01a00000: {
|
|
// 0x01e00010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// MVN{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
|
|
mvn(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
if (((instr & 0xfff0090) != 0x1e00010)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400080: {
|
|
// 0x00400090
|
|
switch (instr & 0x00000060) {
|
|
case 0x00000000: {
|
|
// 0x00400090
|
|
switch (instr & 0x01a00000) {
|
|
case 0x00000000: {
|
|
// 0x00400090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// UMAAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
umaal(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x00600090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// MLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
mls(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x00c00090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMULL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
smull(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x00a00000: {
|
|
// 0x00e00090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMLAL{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
smlal(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x01800000: {
|
|
// 0x01c00090
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0x01c00090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STLB{<c>}{<q>} <Rt>, [<Rn>] ; A1
|
|
stlb(condition,
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff0fff0) != 0x1c0fc90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0x01c00290
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rt = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STLEXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
|
|
stlexb(condition,
|
|
Register(rd),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00ff0) != 0x1c00e90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0x01c00390
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rt = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STREXB{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
|
|
strexb(condition,
|
|
Register(rd),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00ff0) != 0x1c00f90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01a00000: {
|
|
// 0x01e00090
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0x01e00090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STLH{<c>}{<q>} <Rt>, [<Rn>] ; A1
|
|
stlh(condition,
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff0fff0) != 0x1e0fc90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0x01e00290
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rt = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STLEXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
|
|
stlexh(condition,
|
|
Register(rd),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00ff0) != 0x1e00e90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0x01e00390
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rt = instr & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// STREXH{<c>}{<q>} <Rd>, <Rt>, [<Rn>] ; A1
|
|
strexh(condition,
|
|
Register(rd),
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00ff0) != 0x1e00f90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0x004000b0
|
|
switch (instr & 0x01200000) {
|
|
case 0x00000000: {
|
|
// 0x004000b0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// STRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
|
|
strh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, PostIndex));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x006000b0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("STRHT", instr);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x014000b0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
|
|
strh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, Offset));
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x016000b0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// STRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
|
|
strh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, PreIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0x004000d0
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x004f00d0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDRD{<c>}{<q>} <Rt>, <Rt2>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldrd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
&location);
|
|
}
|
|
if (((instr & 0xf7f00f0) != 0x14f00d0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x01200000) {
|
|
case 0x00000000: {
|
|
// 0x004000d0
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset =
|
|
(instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1 NOLINT(whitespace/line_length)
|
|
ldrd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x014000d0
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset =
|
|
(instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1 NOLINT(whitespace/line_length)
|
|
ldrd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x016000d0
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset =
|
|
(instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// LDRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1 NOLINT(whitespace/line_length)
|
|
ldrd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PreIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000060: {
|
|
// 0x004000f0
|
|
switch (instr & 0x01200000) {
|
|
case 0x00000000: {
|
|
// 0x004000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>], #{+/-}<imm_1> ; A1 NOLINT(whitespace/line_length)
|
|
strd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn), sign, offset, PostIndex));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x014000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}] ; A1 NOLINT(whitespace/line_length)
|
|
strd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn), sign, offset, Offset));
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x016000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// STRD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>{, #{+/-}<imm_1>}]! ; A1 NOLINT(whitespace/line_length)
|
|
strd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn), sign, offset, PreIndex));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x00100000
|
|
switch (instr & 0x01e00000) {
|
|
case 0x00000000: {
|
|
// 0x00100000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00100060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
ands(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
// ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
ands(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x00300000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00300060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
eors(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
// EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
eors(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x00500000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000d0000: {
|
|
// 0x005d0000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x005d0060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SUBS{<c>}{<q>} {<Rd>}, SP, <Rm>, RRX ; A1
|
|
subs(condition,
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// SUBS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
subs(condition,
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00500060
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xd0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
subs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xd0000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
subs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00600000: {
|
|
// 0x00700000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00700060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
rsbs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
// RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
rsbs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x00900000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000d0000: {
|
|
// 0x009d0000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x009d0060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ADDS{<c>}{<q>} {<Rd>}, SP, <Rm>, RRX ; A1
|
|
adds(condition,
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// ADDS{<c>}{<q>} {<Rd>}, SP, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
adds(condition,
|
|
Best,
|
|
Register(rd),
|
|
sp,
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00900060
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xd0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
adds(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xd0000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) &
|
|
0x1f);
|
|
// ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
adds(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00a00000: {
|
|
// 0x00b00000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00b00060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
adcs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
// ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
adcs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00c00000: {
|
|
// 0x00d00000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00d00060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
sbcs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
// SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
sbcs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00e00000: {
|
|
// 0x00f00000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x00f00060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
rscs(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
// RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
rscs(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x01100000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x01100060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// TST{<c>}{<q>} <Rn>, <Rm>, RRX ; A1
|
|
tst(condition,
|
|
Best,
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xff0fff0) != 0x1100060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
// TST{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
|
|
tst(condition,
|
|
Best,
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xff0f010) != 0x1100000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x01300000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x01300060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// TEQ{<c>}{<q>} <Rn>, <Rm>, RRX ; A1
|
|
teq(condition, Register(rn), Operand(Register(rm), RRX));
|
|
if (((instr & 0xff0fff0) != 0x1300060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
// TEQ{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
|
|
teq(condition,
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xff0f010) != 0x1300000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01400000: {
|
|
// 0x01500000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x01500060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CMP{<c>}{<q>} <Rn>, <Rm>, RRX ; A1
|
|
cmp(condition,
|
|
Best,
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xff0fff0) != 0x1500060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
// CMP{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
|
|
cmp(condition,
|
|
Best,
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xff0f010) != 0x1500000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01600000: {
|
|
// 0x01700000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x01700060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// CMN{<c>}{<q>} <Rn>, <Rm>, RRX ; A1
|
|
cmn(condition,
|
|
Best,
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xff0fff0) != 0x1700060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
// CMN{<c>}{<q>} <Rn>, <Rm> {, <shift> #<amount> } ; A1
|
|
cmn(condition,
|
|
Best,
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xff0f010) != 0x1700000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01800000: {
|
|
// 0x01900000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x01900060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
orrs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
// ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
orrs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01a00000: {
|
|
// 0x01b00000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x01b00060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// RRXS{<c>}{<q>} {<Rd>}, <Rm> ; A1
|
|
rrxs(condition, Register(rd), Register(rm));
|
|
if (((instr & 0xfff0ff0) != 0x1b00060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// MOVS{<c>}{<q>} <Rd>, <Rm>, RRX ; A1
|
|
movs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0ff0) != 0x1b00060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) == Uint32(0x2)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = (instr >> 7) & 0x1f;
|
|
if (amount == 0) amount = 32;
|
|
// ASRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
|
|
asrs(condition, Best, Register(rd), Register(rm), amount);
|
|
if (((instr & 0xfff0070) != 0x1b00040)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) == Uint32(0x0)) &&
|
|
((instr & 0xf0000000) != 0xf0000000) &&
|
|
((instr & 0x00000f80) != 0x00000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = (instr >> 7) & 0x1f;
|
|
// LSLS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
|
|
lsls(condition, Best, Register(rd), Register(rm), amount);
|
|
if (((instr & 0xfff0070) != 0x1b00000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) == Uint32(0x1)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = (instr >> 7) & 0x1f;
|
|
if (amount == 0) amount = 32;
|
|
// LSRS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
|
|
lsrs(condition, Best, Register(rd), Register(rm), amount);
|
|
if (((instr & 0xfff0070) != 0x1b00020)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) == Uint32(0x3)) &&
|
|
((instr & 0xf0000000) != 0xf0000000) &&
|
|
((instr & 0x00000f80) != 0x00000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = (instr >> 7) & 0x1f;
|
|
// RORS{<c>}{<q>} {<Rd>}, <Rm>, #<imm> ; A1
|
|
rors(condition, Best, Register(rd), Register(rm), amount);
|
|
if (((instr & 0xfff0070) != 0x1b00060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
// MOVS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
|
|
movs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff0010) != 0x1b00000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01c00000: {
|
|
// 0x01d00000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x01d00060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, RRX ; A1
|
|
bics(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), RRX));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
// BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, <shift> #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
bics(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01e00000: {
|
|
// 0x01f00000
|
|
switch (instr & 0x00000fe0) {
|
|
case 0x00000060: {
|
|
// 0x01f00060
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// MVNS{<c>}{<q>} <Rd>, <Rm>, RRX ; A1
|
|
mvns(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), RRX));
|
|
if (((instr & 0xfff0ff0) != 0x1f00060)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xfe0) == 0x60)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
ImmediateShiftOperand shift_operand((instr >> 5) & 0x3,
|
|
(instr >> 7) & 0x1f);
|
|
// MVNS{<c>}{<q>} <Rd>, <Rm> {, <shift> #<amount> } ; A1
|
|
mvns(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm),
|
|
shift_operand.GetType(),
|
|
shift_operand.GetAmount()));
|
|
if (((instr & 0xfff0010) != 0x1f00000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100010: {
|
|
// 0x00100010
|
|
switch (instr & 0x00400080) {
|
|
case 0x00000000: {
|
|
// 0x00100010
|
|
switch (instr & 0x01a00000) {
|
|
case 0x00000000: {
|
|
// 0x00100010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// ANDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
ands(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x00300010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// EORS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
eors(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x00900010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// ADDS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
adds(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x00a00000: {
|
|
// 0x00b00010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// ADCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
adcs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x01100010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// TST{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
tst(condition,
|
|
Best,
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
if (((instr & 0xff0f090) != 0x1100010)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x01300010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// TEQ{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
teq(condition,
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
if (((instr & 0xff0f090) != 0x1300010)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01800000: {
|
|
// 0x01900010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// ORRS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
orrs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x01a00000: {
|
|
// 0x01b00010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) == Uint32(0x2)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// ASRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
|
|
asrs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
if (((instr & 0xfff00f0) != 0x1b00050)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) == Uint32(0x0)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// LSLS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
|
|
lsls(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
if (((instr & 0xfff00f0) != 0x1b00010)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) == Uint32(0x1)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// LSRS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
|
|
lsrs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
if (((instr & 0xfff00f0) != 0x1b00030)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 5)) & Uint32(0x3)) == Uint32(0x3)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// RORS{<c>}{<q>} {<Rd>}, <Rm>, <Rs> ; A1
|
|
rors(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rm),
|
|
Register(rs));
|
|
if (((instr & 0xfff00f0) != 0x1b00070)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// MOVS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
|
|
movs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
if (((instr & 0xfff0090) != 0x1b00010)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x00100090
|
|
switch (instr & 0x01200060) {
|
|
case 0x00000000: {
|
|
// 0x00100090
|
|
switch (instr & 0x00800000) {
|
|
case 0x00000000: {
|
|
// 0x00100090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// MULS{<c>}{<q>} <Rd>, <Rn>, {<Rm>} ; A1
|
|
muls(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xff0f0f0) != 0x100090)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x00900090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// UMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
umulls(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0x001000b0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
// LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
|
|
ldrh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
PostIndex));
|
|
if (((instr & 0xf700ff0) != 0x1000b0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0x001000d0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
// LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
|
|
ldrsb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
PostIndex));
|
|
if (((instr & 0xf700ff0) != 0x1000d0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000060: {
|
|
// 0x001000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
// LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<Rm> ; A1
|
|
ldrsh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
PostIndex));
|
|
if (((instr & 0xf700ff0) != 0x1000f0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x00300090
|
|
switch (instr & 0x00800000) {
|
|
case 0x00000000: {
|
|
// 0x00300090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// MLAS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
mlas(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x00b00090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// UMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
umlals(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200020: {
|
|
// 0x003000b0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDRHT", instr);
|
|
break;
|
|
}
|
|
case 0x00200040: {
|
|
// 0x003000d0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDRSBT", instr);
|
|
break;
|
|
}
|
|
case 0x00200060: {
|
|
// 0x003000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDRSHT", instr);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x01100090
|
|
switch (instr & 0x00800300) {
|
|
case 0x00800000: {
|
|
// 0x01900090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDA{<c>}{<q>} <Rt>, [<Rn>] ; A1
|
|
lda(condition,
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00fff) != 0x1900c9f)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800200: {
|
|
// 0x01900290
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDAEX{<c>}{<q>} <Rt>, [<Rn>] ; A1
|
|
ldaex(condition,
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00fff) != 0x1900e9f)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800300: {
|
|
// 0x01900390
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDREX{<c>}{<q>} <Rt>, [<Rn>{, #<imm_1>}] ; A1
|
|
ldrex(condition,
|
|
Register(rt),
|
|
MemOperand(Register(rn), plus, 0, Offset));
|
|
if (((instr & 0xff00fff) != 0x1900f9f)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000020: {
|
|
// 0x011000b0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
AddrMode addrmode = Offset;
|
|
// LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
|
|
ldrh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
if (((instr & 0xf700ff0) != 0x11000b0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000040: {
|
|
// 0x011000d0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
AddrMode addrmode = Offset;
|
|
// LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
|
|
ldrsb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
if (((instr & 0xf700ff0) != 0x11000d0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000060: {
|
|
// 0x011000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
AddrMode addrmode = Offset;
|
|
// LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>] ; A1
|
|
ldrsh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
if (((instr & 0xf700ff0) != 0x11000f0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x01300090
|
|
switch (instr & 0x00800300) {
|
|
case 0x00800200: {
|
|
// 0x01b00290
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDAEXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
|
|
ldaexd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00fff) != 0x1b00e9f)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800300: {
|
|
// 0x01b00390
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDREXD{<c>}{<q>} <Rt>, <Rt2>, [<Rn>] ; A1
|
|
ldrexd(condition,
|
|
Register(rt),
|
|
Register(rt + 1),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00fff) != 0x1b00f9f)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200020: {
|
|
// 0x013000b0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
AddrMode addrmode = PreIndex;
|
|
// LDRH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
|
|
ldrh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
if (((instr & 0xf700ff0) != 0x13000b0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200040: {
|
|
// 0x013000d0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
AddrMode addrmode = PreIndex;
|
|
// LDRSB{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
|
|
ldrsb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
if (((instr & 0xf700ff0) != 0x13000d0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200060: {
|
|
// 0x013000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
AddrMode addrmode = PreIndex;
|
|
// LDRSH{<c>}{<q>} <Rt>, [<Rn>, #{+/-}<Rm>]! ; A1
|
|
ldrsh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
addrmode));
|
|
if (((instr & 0xf700ff0) != 0x13000f0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x00500010
|
|
switch (instr & 0x01a00000) {
|
|
case 0x00000000: {
|
|
// 0x00500010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// SUBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
subs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x00700010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// RSBS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
rsbs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x00d00010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// SBCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
sbcs(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x00a00000: {
|
|
// 0x00f00010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// RSCS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
rscs(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x01500010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// CMP{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
cmp(condition,
|
|
Best,
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
if (((instr & 0xff0f090) != 0x1500010)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x01700010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// CMN{<c>}{<q>} <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
cmn(condition,
|
|
Best,
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
if (((instr & 0xff0f090) != 0x1700010)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x01800000: {
|
|
// 0x01d00010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// BICS{<c>}{<q>} {<Rd>}, <Rn>, <Rm>, <shift> <Rs> ; A1
|
|
bics(condition,
|
|
Best,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
break;
|
|
}
|
|
case 0x01a00000: {
|
|
// 0x01f00010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
Shift shift((instr >> 5) & 0x3);
|
|
unsigned rs = (instr >> 8) & 0xf;
|
|
// MVNS{<c>}{<q>} <Rd>, <Rm>, <shift> <Rs> ; A1
|
|
mvns(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), shift.GetType(), Register(rs)));
|
|
if (((instr & 0xfff0090) != 0x1f00010)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400080: {
|
|
// 0x00500090
|
|
switch (instr & 0x00000060) {
|
|
case 0x00000000: {
|
|
// 0x00500090
|
|
switch (instr & 0x01a00000) {
|
|
case 0x00800000: {
|
|
// 0x00d00090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMULLS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
smulls(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x00a00000: {
|
|
// 0x00f00090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMLALS{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
smlals(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x01800000: {
|
|
// 0x01d00090
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0x01d00090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDAB{<c>}{<q>} <Rt>, [<Rn>] ; A1
|
|
ldab(condition,
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00fff) != 0x1d00c9f)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0x01d00290
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDAEXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
|
|
ldaexb(condition,
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00fff) != 0x1d00e9f)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0x01d00390
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDREXB{<c>}{<q>} <Rt>, [<Rn>] ; A1
|
|
ldrexb(condition,
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00fff) != 0x1d00f9f)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01a00000: {
|
|
// 0x01f00090
|
|
switch (instr & 0x00000300) {
|
|
case 0x00000000: {
|
|
// 0x01f00090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDAH{<c>}{<q>} <Rt>, [<Rn>] ; A1
|
|
ldah(condition,
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00fff) != 0x1f00c9f)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000200: {
|
|
// 0x01f00290
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDAEXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
|
|
ldaexh(condition,
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00fff) != 0x1f00e9f)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000300: {
|
|
// 0x01f00390
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
// LDREXH{<c>}{<q>} <Rt>, [<Rn>] ; A1
|
|
ldrexh(condition,
|
|
Register(rt),
|
|
MemOperand(Register(rn), Offset));
|
|
if (((instr & 0xff00fff) != 0x1f00f9f)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0x005000b0
|
|
switch (instr & 0x01200000) {
|
|
case 0x00000000: {
|
|
// 0x005000b0
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x005f00b0
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x1200000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDRH{<c>}{<q>} <Rt>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldrh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrh(condition, Register(rt), &location);
|
|
}
|
|
if (((instr & 0xf7f00f0) != 0x15f00b0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset =
|
|
(instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// LDRH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
|
|
ldrh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x007000b0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDRHT", instr);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x015000b0
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x015f00b0
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x1200000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDRH{<c>}{<q>} <Rt>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldrh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrh(condition, Register(rt), &location);
|
|
}
|
|
if (((instr & 0xf7f00f0) != 0x15f00b0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset =
|
|
(instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
|
|
ldrh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x017000b0
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x017f00b0
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x1200000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDRH{<c>}{<q>} <Rt>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldrh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrh(condition, Register(rt), &location);
|
|
}
|
|
if (((instr & 0xf7f00f0) != 0x15f00b0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset =
|
|
(instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// LDRH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1 NOLINT(whitespace/line_length)
|
|
ldrh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PreIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0x005000d0
|
|
switch (instr & 0x01200000) {
|
|
case 0x00000000: {
|
|
// 0x005000d0
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x005f00d0
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x1200000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDRSB{<c>}{<q>} <Rt>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldrsb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrsb(condition, Register(rt), &location);
|
|
}
|
|
if (((instr & 0xf7f00f0) != 0x15f00d0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset =
|
|
(instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// LDRSB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
|
|
ldrsb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x007000d0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDRSBT", instr);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x015000d0
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x015f00d0
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x1200000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDRSB{<c>}{<q>} <Rt>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldrsb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrsb(condition, Register(rt), &location);
|
|
}
|
|
if (((instr & 0xf7f00f0) != 0x15f00d0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset =
|
|
(instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1 NOLINT(whitespace/line_length)
|
|
ldrsb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x017000d0
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x017f00d0
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x1200000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDRSB{<c>}{<q>} <Rt>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldrsb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrsb(condition, Register(rt), &location);
|
|
}
|
|
if (((instr & 0xf7f00f0) != 0x15f00d0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset =
|
|
(instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// LDRSB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1 NOLINT(whitespace/line_length)
|
|
ldrsb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PreIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000060: {
|
|
// 0x005000f0
|
|
switch (instr & 0x01200000) {
|
|
case 0x00000000: {
|
|
// 0x005000f0
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x005f00f0
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x1200000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDRSH{<c>}{<q>} <Rt>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldrsh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrsh(condition, Register(rt), &location);
|
|
}
|
|
if (((instr & 0xf7f00f0) != 0x15f00f0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset =
|
|
(instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// LDRSH{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_2> ; A1
|
|
ldrsh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x007000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDRSHT", instr);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x015000f0
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x015f00f0
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x1200000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDRSH{<c>}{<q>} <Rt>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldrsh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrsh(condition, Register(rt), &location);
|
|
}
|
|
if (((instr & 0xf7f00f0) != 0x15f00f0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset =
|
|
(instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}] ; A1 NOLINT(whitespace/line_length)
|
|
ldrsh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x017000f0
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x017f00f0
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x1200000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = (instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDRSH{<c>}{<q>} <Rt>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldrsh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrsh(condition, Register(rt), &location);
|
|
}
|
|
if (((instr & 0xf7f00f0) != 0x15f00f0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus
|
|
: plus);
|
|
int32_t offset =
|
|
(instr & 0xf) | ((instr >> 4) & 0xf0);
|
|
// LDRSH{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_2>}]! ; A1 NOLINT(whitespace/line_length)
|
|
ldrsh(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
offset,
|
|
PreIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x02000000: {
|
|
// 0x02000000
|
|
switch (instr & 0x01b00000) {
|
|
case 0x00000000: {
|
|
// 0x02000000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x02000000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// AND{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
and_(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x02400000
|
|
switch (instr & 0x000d0000) {
|
|
case 0x000d0000: {
|
|
// 0x024d0000
|
|
switch (instr & 0x00020000) {
|
|
case 0x00000000: {
|
|
// 0x024d0000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// SUB{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
|
|
sub(condition, Best, Register(rd), sp, imm);
|
|
break;
|
|
}
|
|
case 0x00020000: {
|
|
// 0x024f0000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr & 0xf0000000) != 0xf0000000) &&
|
|
((Uint32(instr) & Uint32(0xfff)) == Uint32(0x0))) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// SUB{<c>}{<q>} <Rd>, PC, #<const> ; A2
|
|
sub(condition, Best, Register(rd), pc, imm);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
Location location(-imm, kA32PcDelta);
|
|
// ADR{<c>}{<q>} <Rd>, <label> ; A2
|
|
adr(condition, Best, Register(rd), &location);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xd0000) == 0xd0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// SUB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
sub(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x02100000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x02100000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// ANDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
ands(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x02500000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000d0000: {
|
|
// 0x025d0000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// SUBS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
|
|
subs(condition, Best, Register(rd), sp, imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xd0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// SUBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
subs(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x02200000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x02200000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// EOR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
eor(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x02600000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// RSB{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
rsb(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00300000: {
|
|
// 0x02300000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x02300000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// EORS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
eors(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x02700000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// RSBS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
rsbs(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x02800000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x02800000
|
|
switch (instr & 0x000d0000) {
|
|
case 0x000d0000: {
|
|
// 0x028d0000
|
|
switch (instr & 0x00020000) {
|
|
case 0x00000000: {
|
|
// 0x028d0000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// ADD{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
|
|
add(condition, Best, Register(rd), sp, imm);
|
|
break;
|
|
}
|
|
case 0x00020000: {
|
|
// 0x028f0000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
Location location(imm, kA32PcDelta);
|
|
// ADR{<c>}{<q>} <Rd>, <label> ; A1
|
|
adr(condition, Best, Register(rd), &location);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xd0000) == 0xd0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// ADD{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
add(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x02c00000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// SBC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
sbc(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00900000: {
|
|
// 0x02900000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x02900000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000d0000: {
|
|
// 0x029d0000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// ADDS{<c>}{<q>} {<Rd>}, SP, #<const> ; A1
|
|
adds(condition, Best, Register(rd), sp, imm);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xd0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// ADDS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
adds(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x02d00000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// SBCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
sbcs(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00a00000: {
|
|
// 0x02a00000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x02a00000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// ADC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
adc(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x02e00000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// RSC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
rsc(condition, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00b00000: {
|
|
// 0x02b00000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x02b00000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// ADCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
adcs(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x02f00000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// RSCS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
rscs(condition, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x03000000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x03000000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = (instr & 0xfff) | ((instr >> 4) & 0xf000);
|
|
if (!ImmediateA32::IsImmediateA32(imm)) {
|
|
// MOV{<c>}{<q>} <Rd>, #<imm16> ; A2
|
|
mov(condition, Best, Register(rd), imm);
|
|
} else {
|
|
// MOVW{<c>}{<q>} <Rd>, #<imm16> ; A2
|
|
movw(condition, Register(rd), imm);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x03400000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = (instr & 0xfff) | ((instr >> 4) & 0xf000);
|
|
// MOVT{<c>}{<q>} <Rd>, #<imm16> ; A1
|
|
movt(condition, Register(rd), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01100000: {
|
|
// 0x03100000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x03100000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// TST{<c>}{<q>} <Rn>, #<const> ; A1
|
|
tst(condition, Best, Register(rn), imm);
|
|
if (((instr & 0xff0f000) != 0x3100000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x03500000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// CMP{<c>}{<q>} <Rn>, #<const> ; A1
|
|
cmp(condition, Best, Register(rn), imm);
|
|
if (((instr & 0xff0f000) != 0x3500000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x03200000
|
|
switch (instr & 0x004f0000) {
|
|
case 0x00000000: {
|
|
// 0x03200000
|
|
switch (instr & 0x000000f0) {
|
|
case 0x00000000: {
|
|
// 0x03200000
|
|
switch (instr & 0x0000000f) {
|
|
case 0x00000000: {
|
|
// 0x03200000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
// NOP{<c>}{<q>} ; A1
|
|
nop(condition, Best);
|
|
if (((instr & 0xfffffff) != 0x320f000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000001: {
|
|
// 0x03200001
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
// YIELD{<c>}{<q>} ; A1
|
|
yield(condition, Best);
|
|
if (((instr & 0xfffffff) != 0x320f001)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000002: {
|
|
// 0x03200002
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("WFE", instr);
|
|
break;
|
|
}
|
|
case 0x00000003: {
|
|
// 0x03200003
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("WFI", instr);
|
|
break;
|
|
}
|
|
case 0x00000004: {
|
|
// 0x03200004
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("SEV", instr);
|
|
break;
|
|
}
|
|
case 0x00000005: {
|
|
// 0x03200005
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("SEVL", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x000000f0: {
|
|
// 0x032000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("DBG", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x4f0000) == 0x0)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned spec_reg =
|
|
((instr >> 16) & 0xf) | ((instr >> 18) & 0x10);
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// MSR{<c>}{<q>} <spec_reg>, #<imm> ; A1
|
|
msr(condition, MaskedSpecialRegister(spec_reg), imm);
|
|
if (((instr & 0xfb0f000) != 0x320f000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01300000: {
|
|
// 0x03300000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x03300000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// TEQ{<c>}{<q>} <Rn>, #<const> ; A1
|
|
teq(condition, Register(rn), imm);
|
|
if (((instr & 0xff0f000) != 0x3300000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x03700000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// CMN{<c>}{<q>} <Rn>, #<const> ; A1
|
|
cmn(condition, Best, Register(rn), imm);
|
|
if (((instr & 0xff0f000) != 0x3700000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01800000: {
|
|
// 0x03800000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x03800000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// ORR{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
orr(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x03c00000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// BIC{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
bic(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01900000: {
|
|
// 0x03900000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x03900000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// ORRS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
orrs(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x03d00000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// BICS{<c>}{<q>} {<Rd>}, <Rn>, #<const> ; A1
|
|
bics(condition, Best, Register(rd), Register(rn), imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01a00000: {
|
|
// 0x03a00000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x03a00000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// MOV{<c>}{<q>} <Rd>, #<const> ; A1
|
|
mov(condition, Best, Register(rd), imm);
|
|
if (((instr & 0xfff0000) != 0x3a00000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x03e00000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// MVN{<c>}{<q>} <Rd>, #<const> ; A1
|
|
mvn(condition, Best, Register(rd), imm);
|
|
if (((instr & 0xfff0000) != 0x3e00000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01b00000: {
|
|
// 0x03b00000
|
|
switch (instr & 0x00400000) {
|
|
case 0x00000000: {
|
|
// 0x03b00000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// MOVS{<c>}{<q>} <Rd>, #<const> ; A1
|
|
movs(condition, Best, Register(rd), imm);
|
|
if (((instr & 0xfff0000) != 0x3b00000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x03f00000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = ImmediateA32::Decode(instr & 0xfff);
|
|
// MVNS{<c>}{<q>} <Rd>, #<const> ; A1
|
|
mvns(condition, Best, Register(rd), imm);
|
|
if (((instr & 0xfff0000) != 0x3f00000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x04000000: {
|
|
// 0x04000000
|
|
switch (instr & 0x00500000) {
|
|
case 0x00000000: {
|
|
// 0x04000000
|
|
switch (instr & 0x01200000) {
|
|
case 0x00000000: {
|
|
// 0x04000000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xfff;
|
|
// STR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
|
|
str(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, PostIndex));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x04200000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("STRT", instr);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x05000000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xfff;
|
|
// STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
|
|
str(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, Offset));
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x05200000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 23)) & Uint32(0x1)) == Uint32(0x0)) &&
|
|
((Uint32((instr >> 16)) & Uint32(0xf)) == Uint32(0xd)) &&
|
|
((Uint32(instr) & Uint32(0xfff)) == Uint32(0x4)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
// PUSH{<c>}{<q>} <single_register_list> ; A1
|
|
push(condition, Best, Register(rt));
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xfff;
|
|
// STR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
|
|
str(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, PreIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x04100000
|
|
switch (instr & 0x01200000) {
|
|
case 0x00000000: {
|
|
// 0x04100000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x041f0000
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x1200000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xfff;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDR{<c>}{<q>} <Rt>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldr(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldr(condition, Best, Register(rt), &location);
|
|
}
|
|
if (((instr & 0xf7f0000) != 0x51f0000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 23)) & Uint32(0x1)) ==
|
|
Uint32(0x1)) &&
|
|
((Uint32((instr >> 16)) & Uint32(0xf)) ==
|
|
Uint32(0xd)) &&
|
|
((Uint32(instr) & Uint32(0xfff)) == Uint32(0x4)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
// POP{<c>}{<q>} <single_register_list> ; A1
|
|
pop(condition, Best, Register(rt));
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xfff;
|
|
// LDR{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
|
|
ldr(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x04300000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDRT", instr);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x05100000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x051f0000
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x1200000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xfff;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDR{<c>}{<q>} <Rt>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldr(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldr(condition, Best, Register(rt), &location);
|
|
}
|
|
if (((instr & 0xf7f0000) != 0x51f0000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xfff;
|
|
// LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
|
|
ldr(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x05300000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x053f0000
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x1200000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xfff;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDR{<c>}{<q>} <Rt>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldr(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldr(condition, Best, Register(rt), &location);
|
|
}
|
|
if (((instr & 0xf7f0000) != 0x51f0000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xfff;
|
|
// LDR{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
|
|
ldr(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, PreIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x04400000
|
|
switch (instr & 0x01200000) {
|
|
case 0x00000000: {
|
|
// 0x04400000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xfff;
|
|
// STRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
|
|
strb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, PostIndex));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x04600000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("STRBT", instr);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x05400000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xfff;
|
|
// STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
|
|
strb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, Offset));
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x05600000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xfff;
|
|
// STRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
|
|
strb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, PreIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00500000: {
|
|
// 0x04500000
|
|
switch (instr & 0x01200000) {
|
|
case 0x00000000: {
|
|
// 0x04500000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x045f0000
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x1200000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xfff;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDRB{<c>}{<q>} <Rt>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldrb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrb(condition, Register(rt), &location);
|
|
}
|
|
if (((instr & 0xf7f0000) != 0x55f0000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xfff;
|
|
// LDRB{<c>}{<q>} <Rt>, [<Rn>], #{+/-}<imm_3> ; A1
|
|
ldrb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x04700000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDRBT", instr);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x05500000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x055f0000
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x1200000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xfff;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDRB{<c>}{<q>} <Rt>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldrb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrb(condition, Register(rt), &location);
|
|
}
|
|
if (((instr & 0xf7f0000) != 0x55f0000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xfff;
|
|
// LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}] ; A1
|
|
ldrb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x05700000
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x057f0000
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0x1200000) == 0x200000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xfff;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// LDRB{<c>}{<q>} <Rt>, <label> ; A1
|
|
if (minus_zero) {
|
|
ldrb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
ldrb(condition, Register(rt), &location);
|
|
}
|
|
if (((instr & 0xf7f0000) != 0x55f0000)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = instr & 0xfff;
|
|
// LDRB{<c>}{<q>} <Rt>, [<Rn>{, #{+/-}<imm_3>}]! ; A1
|
|
ldrb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn), sign, offset, PreIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x06000000: {
|
|
// 0x06000000
|
|
switch (instr & 0x01600010) {
|
|
case 0x00000000: {
|
|
// 0x06000000
|
|
switch (instr & 0x00100000) {
|
|
case 0x00000000: {
|
|
// 0x06000000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t imm_and_type_ = ((instr >> 5) & 0x7f);
|
|
ImmediateShiftOperand shift_operand(imm_and_type_ & 0x3,
|
|
(imm_and_type_ & 0x7c) >>
|
|
2);
|
|
Shift shift = shift_operand.GetShift();
|
|
uint32_t amount = shift_operand.GetAmount();
|
|
// STR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
|
|
str(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06100000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t imm_and_type_ = ((instr >> 5) & 0x7f);
|
|
ImmediateShiftOperand shift_operand(imm_and_type_ & 0x3,
|
|
(imm_and_type_ & 0x7c) >>
|
|
2);
|
|
Shift shift = shift_operand.GetShift();
|
|
uint32_t amount = shift_operand.GetAmount();
|
|
// LDR{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
|
|
ldr(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000010: {
|
|
// 0x06000010
|
|
switch (instr & 0x00900060) {
|
|
case 0x00100000: {
|
|
// 0x06100010
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0x06100010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
sadd16(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6100f10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x06100090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
sadd8(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6100f90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100020: {
|
|
// 0x06100030
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
sasx(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6100f30)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100040: {
|
|
// 0x06100050
|
|
if ((instr & 0x00000080) == 0x00000000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
ssax(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6100f50)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100060: {
|
|
// 0x06100070
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0x06100070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
ssub16(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6100f70)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x061000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
ssub8(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6100ff0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x06800010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = (instr >> 7) & 0x1f;
|
|
// PKHBT{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, LSL #<imm> } ; A1
|
|
pkhbt(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), LSL, amount));
|
|
break;
|
|
}
|
|
case 0x00800020: {
|
|
// 0x06800030
|
|
if ((instr & 0x00000080) == 0x00000080) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SEL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
sel(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6800fb0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800040: {
|
|
// 0x06800050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = (instr >> 7) & 0x1f;
|
|
if (amount == 0) amount = 32;
|
|
// PKHTB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ASR #<imm> } ; A1
|
|
pkhtb(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), ASR, amount));
|
|
break;
|
|
}
|
|
case 0x00800060: {
|
|
// 0x06800070
|
|
switch (instr & 0x00000080) {
|
|
case 0x00000000: {
|
|
// 0x06800070
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x068f0070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 10) & 0x3) * 8;
|
|
// SXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
|
|
sxtb16(condition,
|
|
Register(rd),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfff03f0) != 0x68f0070)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 10) & 0x3) * 8;
|
|
// SXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
sxtab16(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xff003f0) != 0x6800070)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x06200000
|
|
switch (instr & 0x00100000) {
|
|
case 0x00000000: {
|
|
// 0x06200000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("STRT", instr);
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06300000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDRT", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200010: {
|
|
// 0x06200010
|
|
switch (instr & 0x00800060) {
|
|
case 0x00000000: {
|
|
// 0x06200010
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x06200010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// QADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
qadd16(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6200f10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x06200090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// QADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
qadd8(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6200f90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06300010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
shadd16(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6300f10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100080: {
|
|
// 0x06300090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
shadd8(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6300f90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0x06200030
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x06200030
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// QASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
qasx(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6200f30)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06300030
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
shasx(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6300f30)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0x06200050
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x06200050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// QSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
qsax(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6200f50)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06300050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
shsax(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6300f50)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000060: {
|
|
// 0x06200070
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x06200070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// QSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
qsub16(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6200f70)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x062000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// QSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
qsub8(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6200ff0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06300070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
shsub16(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6300f70)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100080: {
|
|
// 0x063000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// SHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
shsub8(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6300ff0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x06a00010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = ((instr >> 16) & 0x1f) + 1;
|
|
unsigned rn = instr & 0xf;
|
|
uint32_t amount = (instr >> 7) & 0x1f;
|
|
// SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
|
|
ssat(condition,
|
|
Register(rd),
|
|
imm,
|
|
Operand(Register(rn), LSL, amount));
|
|
break;
|
|
}
|
|
case 0x00800020: {
|
|
// 0x06a00030
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x06a00030
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = ((instr >> 16) & 0xf) + 1;
|
|
unsigned rn = instr & 0xf;
|
|
// SSAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
|
|
ssat16(condition, Register(rd), imm, Register(rn));
|
|
if (((instr & 0xff00ff0) != 0x6a00f30)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06b00030
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// REV{<c>}{<q>} <Rd>, <Rm> ; A1
|
|
rev(condition, Best, Register(rd), Register(rm));
|
|
if (((instr & 0xfff0ff0) != 0x6bf0f30)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100080: {
|
|
// 0x06b000b0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// REV16{<c>}{<q>} <Rd>, <Rm> ; A1
|
|
rev16(condition, Best, Register(rd), Register(rm));
|
|
if (((instr & 0xfff0ff0) != 0x6bf0fb0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800040: {
|
|
// 0x06a00050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = ((instr >> 16) & 0x1f) + 1;
|
|
unsigned rn = instr & 0xf;
|
|
uint32_t amount = (instr >> 7) & 0x1f;
|
|
if (amount == 0) amount = 32;
|
|
// SSAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
|
|
ssat(condition,
|
|
Register(rd),
|
|
imm,
|
|
Operand(Register(rn), ASR, amount));
|
|
break;
|
|
}
|
|
case 0x00800060: {
|
|
// 0x06a00070
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x06a00070
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x06af0070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 10) & 0x3) * 8;
|
|
// SXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
|
|
sxtb(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfff03f0) != 0x6af0070)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 10) & 0x3) * 8;
|
|
// SXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
sxtab(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xff003f0) != 0x6a00070)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06b00070
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x06bf0070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 10) & 0x3) * 8;
|
|
// SXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
|
|
sxth(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfff03f0) != 0x6bf0070)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 10) & 0x3) * 8;
|
|
// SXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
sxtah(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xff003f0) != 0x6b00070)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x06400000
|
|
switch (instr & 0x00100000) {
|
|
case 0x00000000: {
|
|
// 0x06400000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t imm_and_type_ = ((instr >> 5) & 0x7f);
|
|
ImmediateShiftOperand shift_operand(imm_and_type_ & 0x3,
|
|
(imm_and_type_ & 0x7c) >>
|
|
2);
|
|
Shift shift = shift_operand.GetShift();
|
|
uint32_t amount = shift_operand.GetAmount();
|
|
// STRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
|
|
strb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06500000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t imm_and_type_ = ((instr >> 5) & 0x7f);
|
|
ImmediateShiftOperand shift_operand(imm_and_type_ & 0x3,
|
|
(imm_and_type_ & 0x7c) >>
|
|
2);
|
|
Shift shift = shift_operand.GetShift();
|
|
uint32_t amount = shift_operand.GetAmount();
|
|
// LDRB{<c>}{<q>} <Rt>, [<Rn>], {+/-}<Rm>{, <shift>} ; A1
|
|
ldrb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
PostIndex));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400010: {
|
|
// 0x06400010
|
|
switch (instr & 0x009000e0) {
|
|
case 0x00100000: {
|
|
// 0x06500010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
uadd16(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6500f10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100020: {
|
|
// 0x06500030
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
uasx(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6500f30)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100040: {
|
|
// 0x06500050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// USAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
usax(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6500f50)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100060: {
|
|
// 0x06500070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// USUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
usub16(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6500f70)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100080: {
|
|
// 0x06500090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
uadd8(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6500f90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x001000e0: {
|
|
// 0x065000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// USUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
usub8(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6500ff0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800060: {
|
|
// 0x06c00070
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x06cf0070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 10) & 0x3) * 8;
|
|
// UXTB16{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
|
|
uxtb16(condition,
|
|
Register(rd),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfff03f0) != 0x6cf0070)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 10) & 0x3) * 8;
|
|
// UXTAB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
uxtab16(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xff003f0) != 0x6c00070)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00600000: {
|
|
// 0x06600000
|
|
switch (instr & 0x00100000) {
|
|
case 0x00000000: {
|
|
// 0x06600000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("STRBT", instr);
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06700000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDRBT", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00600010: {
|
|
// 0x06600010
|
|
switch (instr & 0x00800060) {
|
|
case 0x00000000: {
|
|
// 0x06600010
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x06600010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UQADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
uqadd16(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6600f10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x06600090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UQADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
uqadd8(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6600f90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06700010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UHADD16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
uhadd16(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6700f10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100080: {
|
|
// 0x06700090
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UHADD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
uhadd8(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6700f90)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0x06600030
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x06600030
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UQASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
uqasx(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6600f30)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06700030
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UHASX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
uhasx(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6700f30)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0x06600050
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x06600050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UQSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
uqsax(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6600f50)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06700050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UHSAX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
uhsax(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6700f50)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000060: {
|
|
// 0x06600070
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x06600070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UQSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
uqsub16(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6600f70)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x066000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UQSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
uqsub8(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6600ff0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06700070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UHSUB16{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
uhsub16(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6700f70)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100080: {
|
|
// 0x067000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// UHSUB8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
uhsub8(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff00ff0) != 0x6700ff0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x06e00010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = (instr >> 16) & 0x1f;
|
|
unsigned rn = instr & 0xf;
|
|
uint32_t amount = (instr >> 7) & 0x1f;
|
|
// USAT{<c>}{<q>} <Rd>, #<imm>, <Rn> {, LSL #<amount> } ; A1
|
|
usat(condition,
|
|
Register(rd),
|
|
imm,
|
|
Operand(Register(rn), LSL, amount));
|
|
break;
|
|
}
|
|
case 0x00800020: {
|
|
// 0x06e00030
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x06e00030
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
// USAT16{<c>}{<q>} <Rd>, #<imm>, <Rn> ; A1
|
|
usat16(condition, Register(rd), imm, Register(rn));
|
|
if (((instr & 0xff00ff0) != 0x6e00f30)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06f00030
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// RBIT{<c>}{<q>} <Rd>, <Rm> ; A1
|
|
rbit(condition, Register(rd), Register(rm));
|
|
if (((instr & 0xfff0ff0) != 0x6ff0f30)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100080: {
|
|
// 0x06f000b0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
// REVSH{<c>}{<q>} <Rd>, <Rm> ; A1
|
|
revsh(condition, Best, Register(rd), Register(rm));
|
|
if (((instr & 0xfff0ff0) != 0x6ff0fb0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800040: {
|
|
// 0x06e00050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t imm = (instr >> 16) & 0x1f;
|
|
unsigned rn = instr & 0xf;
|
|
uint32_t amount = (instr >> 7) & 0x1f;
|
|
if (amount == 0) amount = 32;
|
|
// USAT{<c>}{<q>} <Rd>, #<imm>, <Rn>, ASR #<amount> ; A1
|
|
usat(condition,
|
|
Register(rd),
|
|
imm,
|
|
Operand(Register(rn), ASR, amount));
|
|
break;
|
|
}
|
|
case 0x00800060: {
|
|
// 0x06e00070
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x06e00070
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x06ef0070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 10) & 0x3) * 8;
|
|
// UXTB{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
|
|
uxtb(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfff03f0) != 0x6ef0070)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 10) & 0x3) * 8;
|
|
// UXTAB{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
uxtab(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xff003f0) != 0x6e00070)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x06f00070
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x06ff0070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 10) & 0x3) * 8;
|
|
// UXTH{<c>}{<q>} {<Rd>}, <Rm> {, ROR #<amount> } ; A1
|
|
uxth(condition,
|
|
Best,
|
|
Register(rd),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xfff03f0) != 0x6ff0070)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t amount = ((instr >> 10) & 0x3) * 8;
|
|
// UXTAH{<c>}{<q>} {<Rd>}, <Rn>, <Rm> {, ROR #<amount> } ; A1 NOLINT(whitespace/line_length)
|
|
uxtah(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Operand(Register(rm), ROR, amount));
|
|
if (((instr & 0xff003f0) != 0x6f00070)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x07000000
|
|
switch (instr & 0x00100000) {
|
|
case 0x00000000: {
|
|
// 0x07000000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t imm_and_type_ = ((instr >> 5) & 0x7f);
|
|
ImmediateShiftOperand shift_operand(imm_and_type_ & 0x3,
|
|
(imm_and_type_ & 0x7c) >>
|
|
2);
|
|
Shift shift = shift_operand.GetShift();
|
|
uint32_t amount = shift_operand.GetAmount();
|
|
AddrMode addrmode = Offset;
|
|
// STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
|
|
str(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x07100000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t imm_and_type_ = ((instr >> 5) & 0x7f);
|
|
ImmediateShiftOperand shift_operand(imm_and_type_ & 0x3,
|
|
(imm_and_type_ & 0x7c) >>
|
|
2);
|
|
Shift shift = shift_operand.GetShift();
|
|
uint32_t amount = shift_operand.GetAmount();
|
|
AddrMode addrmode = Offset;
|
|
// LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
|
|
ldr(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000010: {
|
|
// 0x07000010
|
|
switch (instr & 0x009000e0) {
|
|
case 0x00000000: {
|
|
// 0x07000010
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0x0700f010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMUAD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
smuad(condition, Register(rd), Register(rn), Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
smlad(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0x07000030
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0x0700f030
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMUADX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
smuadx(condition, Register(rd), Register(rn), Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLADX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
smladx(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0x07000050
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0x0700f050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMUSD{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
smusd(condition, Register(rd), Register(rn), Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLSD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
smlsd(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000060: {
|
|
// 0x07000070
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0x0700f070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMUSDX{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
smusdx(condition, Register(rd), Register(rn), Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMLSDX{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
smlsdx(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x07100010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
sdiv(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff0f0f0) != 0x710f010)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x07800010
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0x0780f010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// USAD8{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
usad8(condition, Register(rd), Register(rn), Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// USADA8{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
usada8(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200000: {
|
|
// 0x07200000
|
|
switch (instr & 0x00100000) {
|
|
case 0x00000000: {
|
|
// 0x07200000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t imm_and_type_ = ((instr >> 5) & 0x7f);
|
|
ImmediateShiftOperand shift_operand(imm_and_type_ & 0x3,
|
|
(imm_and_type_ & 0x7c) >>
|
|
2);
|
|
Shift shift = shift_operand.GetShift();
|
|
uint32_t amount = shift_operand.GetAmount();
|
|
AddrMode addrmode = PreIndex;
|
|
// STR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
|
|
str(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x07300000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t imm_and_type_ = ((instr >> 5) & 0x7f);
|
|
ImmediateShiftOperand shift_operand(imm_and_type_ & 0x3,
|
|
(imm_and_type_ & 0x7c) >>
|
|
2);
|
|
Shift shift = shift_operand.GetShift();
|
|
uint32_t amount = shift_operand.GetAmount();
|
|
AddrMode addrmode = PreIndex;
|
|
// LDR{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
|
|
ldr(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01200010: {
|
|
// 0x07200010
|
|
switch (instr & 0x00800060) {
|
|
case 0x00000000: {
|
|
// 0x07200010
|
|
if ((instr & 0x00100080) == 0x00100000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// UDIV{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
udiv(condition, Register(rd), Register(rn), Register(rm));
|
|
if (((instr & 0xff0f0f0) != 0x730f010)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800040: {
|
|
// 0x07a00050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
uint32_t lsb = (instr >> 7) & 0x1f;
|
|
uint32_t widthm1 = (instr >> 16) & 0x1f;
|
|
uint32_t width = widthm1 + 1;
|
|
// SBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
|
|
sbfx(condition, Register(rd), Register(rn), lsb, width);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01400000: {
|
|
// 0x07400000
|
|
switch (instr & 0x00100000) {
|
|
case 0x00000000: {
|
|
// 0x07400000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t imm_and_type_ = ((instr >> 5) & 0x7f);
|
|
ImmediateShiftOperand shift_operand(imm_and_type_ & 0x3,
|
|
(imm_and_type_ & 0x7c) >>
|
|
2);
|
|
Shift shift = shift_operand.GetShift();
|
|
uint32_t amount = shift_operand.GetAmount();
|
|
AddrMode addrmode = Offset;
|
|
// STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
|
|
strb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x07500000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t imm_and_type_ = ((instr >> 5) & 0x7f);
|
|
ImmediateShiftOperand shift_operand(imm_and_type_ & 0x3,
|
|
(imm_and_type_ & 0x7c) >>
|
|
2);
|
|
Shift shift = shift_operand.GetShift();
|
|
uint32_t amount = shift_operand.GetAmount();
|
|
AddrMode addrmode = Offset;
|
|
// LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}] ; A1
|
|
ldrb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01400010: {
|
|
// 0x07400010
|
|
switch (instr & 0x00800060) {
|
|
case 0x00000000: {
|
|
// 0x07400010
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x07400010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMLALD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
smlald(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x07500010
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0x0750f010
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMMUL{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
smmul(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMMLA{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
smmla(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000020: {
|
|
// 0x07400030
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x07400030
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMLALDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
smlaldx(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x07500030
|
|
switch (instr & 0x0000f000) {
|
|
case 0x0000f000: {
|
|
// 0x0750f030
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMMULR{<c>}{<q>} {<Rd>}, <Rn>, <Rm> ; A1
|
|
smmulr(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf000) == 0xf000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMMLAR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
smmlar(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0x07400050
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x07400050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMLSLD{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
smlsld(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x00100080: {
|
|
// 0x075000d0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMMLS{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
smmls(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000060: {
|
|
// 0x07400070
|
|
switch (instr & 0x00100080) {
|
|
case 0x00000000: {
|
|
// 0x07400070
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rdlo = (instr >> 12) & 0xf;
|
|
unsigned rdhi = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
// SMLSLDX{<c>}{<q>} <Rd>, <Rd>, <Rn>, <Rm> ; A1
|
|
smlsldx(condition,
|
|
Register(rdlo),
|
|
Register(rdhi),
|
|
Register(rn),
|
|
Register(rm));
|
|
break;
|
|
}
|
|
case 0x00100080: {
|
|
// 0x075000f0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 16) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
unsigned rm = (instr >> 8) & 0xf;
|
|
unsigned ra = (instr >> 12) & 0xf;
|
|
// SMMLSR{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> ; A1
|
|
smmlsr(condition,
|
|
Register(rd),
|
|
Register(rn),
|
|
Register(rm),
|
|
Register(ra));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x07c00010
|
|
switch (instr & 0x0000000f) {
|
|
case 0x0000000f: {
|
|
// 0x07c0001f
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
uint32_t lsb = (instr >> 7) & 0x1f;
|
|
uint32_t msb = (instr >> 16) & 0x1f;
|
|
uint32_t width = msb - lsb + 1;
|
|
// BFC{<c>}{<q>} <Rd>, #<lsb>, #<width> ; A1
|
|
bfc(condition, Register(rd), lsb, width);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf) == 0xf)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
uint32_t lsb = (instr >> 7) & 0x1f;
|
|
uint32_t msb = (instr >> 16) & 0x1f;
|
|
uint32_t width = msb - lsb + 1;
|
|
// BFI{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
|
|
bfi(condition, Register(rd), Register(rn), lsb, width);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01600000: {
|
|
// 0x07600000
|
|
switch (instr & 0x00100000) {
|
|
case 0x00000000: {
|
|
// 0x07600000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t imm_and_type_ = ((instr >> 5) & 0x7f);
|
|
ImmediateShiftOperand shift_operand(imm_and_type_ & 0x3,
|
|
(imm_and_type_ & 0x7c) >>
|
|
2);
|
|
Shift shift = shift_operand.GetShift();
|
|
uint32_t amount = shift_operand.GetAmount();
|
|
AddrMode addrmode = PreIndex;
|
|
// STRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
|
|
strb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x07700000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign(((instr >> 23) & 0x1) == 0 ? minus : plus);
|
|
unsigned rm = instr & 0xf;
|
|
uint32_t imm_and_type_ = ((instr >> 5) & 0x7f);
|
|
ImmediateShiftOperand shift_operand(imm_and_type_ & 0x3,
|
|
(imm_and_type_ & 0x7c) >>
|
|
2);
|
|
Shift shift = shift_operand.GetShift();
|
|
uint32_t amount = shift_operand.GetAmount();
|
|
AddrMode addrmode = PreIndex;
|
|
// LDRB{<c>}{<q>} <Rt>, [<Rn>, {+/-}<Rm>{, <shift>}]! ; A1
|
|
ldrb(condition,
|
|
Best,
|
|
Register(rt),
|
|
MemOperand(Register(rn),
|
|
sign,
|
|
Register(rm),
|
|
shift,
|
|
amount,
|
|
addrmode));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01600010: {
|
|
// 0x07600010
|
|
switch (instr & 0x00800060) {
|
|
case 0x00800040: {
|
|
// 0x07e00050
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = (instr >> 12) & 0xf;
|
|
unsigned rn = instr & 0xf;
|
|
uint32_t lsb = (instr >> 7) & 0x1f;
|
|
uint32_t widthm1 = (instr >> 16) & 0x1f;
|
|
uint32_t width = widthm1 + 1;
|
|
// UBFX{<c>}{<q>} <Rd>, <Rn>, #<lsb>, #<width> ; A1
|
|
ubfx(condition, Register(rd), Register(rn), lsb, width);
|
|
break;
|
|
}
|
|
case 0x00800060: {
|
|
// 0x07e00070
|
|
if ((instr & 0xf0100080) == 0xe0100080) {
|
|
uint32_t imm = (instr & 0xf) | ((instr >> 4) & 0xfff0);
|
|
// UDF{<c>}{<q>} {#}<imm> ; A1
|
|
udf(al, Best, imm);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x08000000: {
|
|
// 0x08000000
|
|
switch (instr & 0x00500000) {
|
|
case 0x00000000: {
|
|
// 0x08000000
|
|
switch (instr & 0x01800000) {
|
|
case 0x00000000: {
|
|
// 0x08000000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
RegisterList registers((instr & 0xffff));
|
|
// STMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
|
|
stmda(condition, Register(rn), write_back, registers);
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x08800000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
RegisterList registers((instr & 0xffff));
|
|
// STM{<c>}{<q>} <Rn>{!}, <registers> ; A1
|
|
stm(condition, Best, Register(rn), write_back, registers);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x09000000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 21)) & Uint32(0x1)) == Uint32(0x1)) &&
|
|
((Uint32((instr >> 16)) & Uint32(0xf)) == Uint32(0xd)) &&
|
|
((instr & 0xf0000000) != 0xf0000000) &&
|
|
(BitCount((Uint32(instr) & Uint32(0xffff))) > Int64(1))) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
RegisterList registers((instr & 0xffff));
|
|
// PUSH{<c>}{<q>} <registers> ; A1
|
|
push(condition, Best, registers);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
RegisterList registers((instr & 0xffff));
|
|
// STMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
|
|
stmdb(condition, Best, Register(rn), write_back, registers);
|
|
break;
|
|
}
|
|
case 0x01800000: {
|
|
// 0x09800000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
RegisterList registers((instr & 0xffff));
|
|
// STMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
|
|
stmib(condition, Register(rn), write_back, registers);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100000: {
|
|
// 0x08100000
|
|
switch (instr & 0x01800000) {
|
|
case 0x00000000: {
|
|
// 0x08100000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
RegisterList registers((instr & 0xffff));
|
|
// LDMDA{<c>}{<q>} <Rn>{!}, <registers> ; A1
|
|
ldmda(condition, Register(rn), write_back, registers);
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x08900000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 21)) & Uint32(0x1)) == Uint32(0x1)) &&
|
|
((Uint32((instr >> 16)) & Uint32(0xf)) == Uint32(0xd)) &&
|
|
((instr & 0xf0000000) != 0xf0000000) &&
|
|
(BitCount((Uint32(instr) & Uint32(0xffff))) > Int64(1))) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
RegisterList registers((instr & 0xffff));
|
|
// POP{<c>}{<q>} <registers> ; A1
|
|
pop(condition, Best, registers);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
RegisterList registers((instr & 0xffff));
|
|
// LDM{<c>}{<q>} <Rn>{!}, <registers> ; A1
|
|
ldm(condition, Best, Register(rn), write_back, registers);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x09100000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
RegisterList registers((instr & 0xffff));
|
|
// LDMDB{<c>}{<q>} <Rn>{!}, <registers> ; A1
|
|
ldmdb(condition, Register(rn), write_back, registers);
|
|
break;
|
|
}
|
|
case 0x01800000: {
|
|
// 0x09900000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
RegisterList registers((instr & 0xffff));
|
|
// LDMIB{<c>}{<q>} <Rn>{!}, <registers> ; A1
|
|
ldmib(condition, Register(rn), write_back, registers);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x08400000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("STM", instr);
|
|
break;
|
|
}
|
|
case 0x00500000: {
|
|
// 0x08500000
|
|
switch (instr & 0x00008000) {
|
|
case 0x00000000: {
|
|
// 0x08500000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDM", instr);
|
|
break;
|
|
}
|
|
case 0x00008000: {
|
|
// 0x08508000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDM", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x0a000000: {
|
|
// 0x0a000000
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0x0a000000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
int32_t imm = SignExtend<int32_t>((instr & 0xffffff) << 2, 26);
|
|
Location location(imm, kA32PcDelta);
|
|
// B{<c>}{<q>} <label> ; A1
|
|
b(condition, Best, &location);
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x0b000000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
int32_t imm = SignExtend<int32_t>((instr & 0xffffff) << 2, 26);
|
|
Location location(imm, kA32PcDelta);
|
|
// BL{<c>}{<q>} <label> ; A1
|
|
bl(condition, &location);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x0c000000: {
|
|
// 0x0c000000
|
|
switch (instr & 0x01100e00) {
|
|
case 0x00000a00: {
|
|
// 0x0c000a00
|
|
switch (instr & 0x00800100) {
|
|
case 0x00000000: {
|
|
// 0x0c000a00
|
|
if ((instr & 0x006000d0) == 0x00400010) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 16) & 0xf;
|
|
// VMOV{<c>}{<q>} <Sm>, <Sm1>, <Rt>, <Rt2> ; A1
|
|
vmov(condition,
|
|
SRegister(rm),
|
|
SRegister(rm + 1),
|
|
Register(rt),
|
|
Register(rt2));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0x0c000b00
|
|
if ((instr & 0x006000d0) == 0x00400010) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 16) & 0xf;
|
|
// VMOV{<c>}{<q>} <Dm>, <Rt>, <Rt2> ; A1
|
|
vmov(condition, DRegister(rm), Register(rt), Register(rt2));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x0c800a00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
unsigned first = ExtractSRegister(instr, 22, 12);
|
|
unsigned len = instr & 0xff;
|
|
// VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
|
|
vstm(condition,
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
write_back,
|
|
SRegisterList(SRegister(first), len));
|
|
if ((len == 0) || ((first + len) > kNumberOfSRegisters)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800100: {
|
|
// 0x0c800b00
|
|
switch (instr & 0x00000001) {
|
|
case 0x00000000: {
|
|
// 0x0c800b00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// VSTM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
|
|
vstm(condition,
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
write_back,
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) ||
|
|
(end > kMaxNumberOfDRegisters)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000001: {
|
|
// 0x0c800b01
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// FSTMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
|
|
fstmiax(condition,
|
|
Register(rn),
|
|
write_back,
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) || (end > 16)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000e00: {
|
|
// 0x0c000e00
|
|
switch (instr & 0x00600000) {
|
|
case 0x00000000: {
|
|
// 0x0c000e00
|
|
if ((instr & 0x0080f100) == 0x00805000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("STC", instr);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x0c200e00
|
|
if ((instr & 0x0000f100) == 0x00005000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("STC", instr);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x0c400e00
|
|
if ((instr & 0x00800000) == 0x00000000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("MCRR", instr);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100a00: {
|
|
// 0x0c100a00
|
|
switch (instr & 0x00800100) {
|
|
case 0x00000000: {
|
|
// 0x0c100a00
|
|
if ((instr & 0x006000d0) == 0x00400010) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 16) & 0xf;
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VMOV{<c>}{<q>} <Rt>, <Rt2>, <Sm>, <Sm1> ; A1
|
|
vmov(condition,
|
|
Register(rt),
|
|
Register(rt2),
|
|
SRegister(rm),
|
|
SRegister(rm + 1));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0x0c100b00
|
|
if ((instr & 0x006000d0) == 0x00400010) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rt2 = (instr >> 16) & 0xf;
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMOV{<c>}{<q>} <Rt>, <Rt2>, <Dm> ; A1
|
|
vmov(condition, Register(rt), Register(rt2), DRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x0c900a00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 21)) & Uint32(0x1)) == Uint32(0x1)) &&
|
|
((Uint32((instr >> 16)) & Uint32(0xf)) == Uint32(0xd)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned first = ExtractSRegister(instr, 22, 12);
|
|
unsigned len = instr & 0xff;
|
|
// VPOP{<c>}{<q>}{.<size>} <sreglist> ; A2
|
|
vpop(condition,
|
|
kDataTypeValueNone,
|
|
SRegisterList(SRegister(first), len));
|
|
if ((len == 0) || ((first + len) > kNumberOfSRegisters)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
unsigned first = ExtractSRegister(instr, 22, 12);
|
|
unsigned len = instr & 0xff;
|
|
// VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <sreglist> ; A2
|
|
vldm(condition,
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
write_back,
|
|
SRegisterList(SRegister(first), len));
|
|
if ((len == 0) || ((first + len) > kNumberOfSRegisters)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800100: {
|
|
// 0x0c900b00
|
|
switch (instr & 0x00000001) {
|
|
case 0x00000000: {
|
|
// 0x0c900b00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 21)) & Uint32(0x1)) ==
|
|
Uint32(0x1)) &&
|
|
((Uint32((instr >> 16)) & Uint32(0xf)) ==
|
|
Uint32(0xd)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// VPOP{<c>}{<q>}{.<size>} <dreglist> ; A1
|
|
vpop(condition,
|
|
kDataTypeValueNone,
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) ||
|
|
(end > kMaxNumberOfDRegisters)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// VLDM{<c>}{<q>}{.<size>} <Rn>{!}, <dreglist> ; A1
|
|
vldm(condition,
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
write_back,
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) ||
|
|
(end > kMaxNumberOfDRegisters)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000001: {
|
|
// 0x0c900b01
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
WriteBack write_back((instr >> 21) & 0x1);
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// FLDMIAX{<c>}{<q>} <Rn>{!}, <dreglist> ; A1
|
|
fldmiax(condition,
|
|
Register(rn),
|
|
write_back,
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) || (end > 16)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100e00: {
|
|
// 0x0c100e00
|
|
switch (instr & 0x00600000) {
|
|
case 0x00000000: {
|
|
// 0x0c100e00
|
|
switch (instr & 0x0080f100) {
|
|
case 0x00805000: {
|
|
// 0x0c905e00
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x0c9f5e00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDC", instr);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDC", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x0c300e00
|
|
if ((instr & 0x0000f100) == 0x00005000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDC", instr);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00400000: {
|
|
// 0x0c500e00
|
|
if ((instr & 0x00800000) == 0x00000000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("MRRC", instr);
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000a00: {
|
|
// 0x0d000a00
|
|
switch (instr & 0x00200100) {
|
|
case 0x00000000: {
|
|
// 0x0d000a00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// VSTR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
|
|
vstr(condition,
|
|
Untyped32,
|
|
SRegister(rd),
|
|
MemOperand(Register(rn), sign, offset, Offset));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0x0d000b00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// VSTR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
|
|
vstr(condition,
|
|
Untyped64,
|
|
DRegister(rd),
|
|
MemOperand(Register(rn), sign, offset, Offset));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x0d200a00
|
|
if ((instr & 0x00800000) == 0x00000000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 16)) & Uint32(0xf)) == Uint32(0xd)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned first = ExtractSRegister(instr, 22, 12);
|
|
unsigned len = instr & 0xff;
|
|
// VPUSH{<c>}{<q>}{.<size>} <sreglist> ; A2
|
|
vpush(condition,
|
|
kDataTypeValueNone,
|
|
SRegisterList(SRegister(first), len));
|
|
if ((len == 0) || ((first + len) > kNumberOfSRegisters)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned first = ExtractSRegister(instr, 22, 12);
|
|
unsigned len = instr & 0xff;
|
|
// VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
|
|
vstmdb(condition,
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
WriteBack(WRITE_BACK),
|
|
SRegisterList(SRegister(first), len));
|
|
if ((len == 0) || ((first + len) > kNumberOfSRegisters)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200100: {
|
|
// 0x0d200b00
|
|
switch (instr & 0x00800001) {
|
|
case 0x00000000: {
|
|
// 0x0d200b00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((Uint32((instr >> 16)) & Uint32(0xf)) ==
|
|
Uint32(0xd)) &&
|
|
((instr & 0xf0000000) != 0xf0000000)) {
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// VPUSH{<c>}{<q>}{.<size>} <dreglist> ; A1
|
|
vpush(condition,
|
|
kDataTypeValueNone,
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) ||
|
|
(end > kMaxNumberOfDRegisters)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// VSTMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
|
|
vstmdb(condition,
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
WriteBack(WRITE_BACK),
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) ||
|
|
(end > kMaxNumberOfDRegisters)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000001: {
|
|
// 0x0d200b01
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// FSTMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
|
|
fstmdbx(condition,
|
|
Register(rn),
|
|
WriteBack(WRITE_BACK),
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) || (end > 16)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000e00: {
|
|
// 0x0d000e00
|
|
switch (instr & 0x0060f100) {
|
|
case 0x00005000: {
|
|
// 0x0d005e00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("STC", instr);
|
|
break;
|
|
}
|
|
case 0x00205000: {
|
|
// 0x0d205e00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("STC", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01100a00: {
|
|
// 0x0d100a00
|
|
switch (instr & 0x00200100) {
|
|
case 0x00000000: {
|
|
// 0x0d100a00
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x0d1f0a00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xff;
|
|
imm <<= 2;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// VLDR{<c>}{<q>}{.32} <Sd>, <label> ; A2
|
|
if (minus_zero) {
|
|
vldr(condition,
|
|
Untyped32,
|
|
SRegister(rd),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
vldr(condition, Untyped32, SRegister(rd), &location);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// VLDR{<c>}{<q>}{.32} <Sd>, [<Rn>{, #{+/-}<imm>}] ; A2
|
|
vldr(condition,
|
|
Untyped32,
|
|
SRegister(rd),
|
|
MemOperand(Register(rn), sign, offset, Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0x0d100b00
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x0d1f0b00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
uint32_t U = (instr >> 23) & 0x1;
|
|
int32_t imm = instr & 0xff;
|
|
imm <<= 2;
|
|
if (U == 0) imm = -imm;
|
|
bool minus_zero = (imm == 0) && (U == 0);
|
|
Location location(imm, kA32PcDelta);
|
|
// VLDR{<c>}{<q>}{.64} <Dd>, <label> ; A1
|
|
if (minus_zero) {
|
|
vldr(condition,
|
|
Untyped64,
|
|
DRegister(rd),
|
|
MemOperand(pc, minus, 0));
|
|
} else {
|
|
vldr(condition, Untyped64, DRegister(rd), &location);
|
|
}
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
Sign sign((((instr >> 23) & 0x1) == 0) ? minus : plus);
|
|
int32_t offset = (instr & 0xff) << 2;
|
|
// VLDR{<c>}{<q>}{.64} <Dd>, [<Rn>{, #{+/-}<imm>}] ; A1
|
|
vldr(condition,
|
|
Untyped64,
|
|
DRegister(rd),
|
|
MemOperand(Register(rn), sign, offset, Offset));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x0d300a00
|
|
if ((instr & 0x00800000) == 0x00000000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned first = ExtractSRegister(instr, 22, 12);
|
|
unsigned len = instr & 0xff;
|
|
// VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <sreglist> ; A2
|
|
vldmdb(condition,
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
WriteBack(WRITE_BACK),
|
|
SRegisterList(SRegister(first), len));
|
|
if ((len == 0) || ((first + len) > kNumberOfSRegisters)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200100: {
|
|
// 0x0d300b00
|
|
switch (instr & 0x00800001) {
|
|
case 0x00000000: {
|
|
// 0x0d300b00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// VLDMDB{<c>}{<q>}{.<size>} <Rn>!, <dreglist> ; A1
|
|
vldmdb(condition,
|
|
kDataTypeValueNone,
|
|
Register(rn),
|
|
WriteBack(WRITE_BACK),
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) ||
|
|
(end > kMaxNumberOfDRegisters)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000001: {
|
|
// 0x0d300b01
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = (instr >> 16) & 0xf;
|
|
unsigned first = ExtractDRegister(instr, 22, 12);
|
|
unsigned imm8 = (instr & 0xff);
|
|
unsigned len = imm8 / 2;
|
|
unsigned end = first + len;
|
|
// FLDMDBX{<c>}{<q>} <Rn>!, <dreglist> ; A1
|
|
fldmdbx(condition,
|
|
Register(rn),
|
|
WriteBack(WRITE_BACK),
|
|
DRegisterList(DRegister(first), len));
|
|
if ((len == 0) || (len > 16) || (end > 16)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x01100e00: {
|
|
// 0x0d100e00
|
|
switch (instr & 0x0060f100) {
|
|
case 0x00005000: {
|
|
// 0x0d105e00
|
|
switch (instr & 0x000f0000) {
|
|
case 0x000f0000: {
|
|
// 0x0d1f5e00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDC", instr);
|
|
break;
|
|
}
|
|
default: {
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDC", instr);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00205000: {
|
|
// 0x0d305e00
|
|
if (((instr & 0xf0000000) == 0xf0000000) ||
|
|
((instr & 0xf0000) == 0xf0000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("LDC", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x0e000000: {
|
|
// 0x0e000000
|
|
switch (instr & 0x01000000) {
|
|
case 0x00000000: {
|
|
// 0x0e000000
|
|
switch (instr & 0x00100e10) {
|
|
case 0x00000a00: {
|
|
// 0x0e000a00
|
|
switch (instr & 0x00a00140) {
|
|
case 0x00000000: {
|
|
// 0x0e000a00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
|
|
vmla(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0x0e000a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
|
|
vmls(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0x0e000b00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
|
|
vmla(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000140: {
|
|
// 0x0e000b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
|
|
vmls(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x0e200a00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
|
|
vmul(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200040: {
|
|
// 0x0e200a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VNMUL{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
|
|
vnmul(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200100: {
|
|
// 0x0e200b00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
|
|
vmul(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200140: {
|
|
// 0x0e200b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VNMUL{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
|
|
vnmul(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x0e800a00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VDIV{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A1
|
|
vdiv(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00800100: {
|
|
// 0x0e800b00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VDIV{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A1
|
|
vdiv(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00a00000: {
|
|
// 0x0ea00a00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VFMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
|
|
vfma(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00a00040: {
|
|
// 0x0ea00a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VFMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A2
|
|
vfms(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00a00100: {
|
|
// 0x0ea00b00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VFMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
|
|
vfma(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00a00140: {
|
|
// 0x0ea00b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VFMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A2
|
|
vfms(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000a10: {
|
|
// 0x0e000a10
|
|
switch (instr & 0x00800100) {
|
|
case 0x00000000: {
|
|
// 0x0e000a10
|
|
if ((instr & 0x00600000) == 0x00000000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
// VMOV{<c>}{<q>} <Sn>, <Rt> ; A1
|
|
vmov(condition, SRegister(rn), Register(rt));
|
|
if (((instr & 0xff00f7f) != 0xe000a10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0x0e000b10
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned lane;
|
|
DataType dt =
|
|
Dt_opc1_opc2_1_Decode(((instr >> 5) & 0x3) |
|
|
((instr >> 19) & 0xc),
|
|
&lane);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 7, 16);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
// VMOV{<c>}{<q>}{.<size>} <Dd[x]>, <Rt> ; A1
|
|
vmov(condition, dt, DRegisterLane(rd, lane), Register(rt));
|
|
if (((instr & 0xf900f1f) != 0xe000b10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x0e800a10
|
|
if ((instr & 0x00600000) == 0x00600000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned spec_reg = (instr >> 16) & 0xf;
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
switch (spec_reg) {
|
|
case 0x0:
|
|
case 0x1:
|
|
case 0x8: {
|
|
// VMSR{<c>}{<q>} <spec_reg>, <Rt> ; A1
|
|
vmsr(condition,
|
|
SpecialFPRegister(spec_reg),
|
|
Register(rt));
|
|
if (((instr & 0xff00fff) != 0xee00a10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00800100: {
|
|
// 0x0e800b10
|
|
switch (instr & 0x00200040) {
|
|
case 0x00000000: {
|
|
// 0x0e800b10
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
DataType dt = Dt_B_E_1_Decode(((instr >> 5) & 0x1) |
|
|
((instr >> 21) & 0x2));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 7, 16);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
// VDUP{<c>}{<q>}.<dt> <Dd>, <Rt> ; A1
|
|
vdup(condition, dt, DRegister(rd), Register(rt));
|
|
if (((instr & 0xfb00f5f) != 0xe800b10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x0ea00b10
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
DataType dt = Dt_B_E_1_Decode(((instr >> 5) & 0x1) |
|
|
((instr >> 21) & 0x2));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
if (((instr >> 16) & 1) != 0) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractQRegister(instr, 7, 16);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
// VDUP{<c>}{<q>}.<dt> <Qd>, <Rt> ; A1
|
|
vdup(condition, dt, QRegister(rd), Register(rt));
|
|
if (((instr & 0xfb00f5f) != 0xea00b10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000e10: {
|
|
// 0x0e000e10
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("MCR", instr);
|
|
break;
|
|
}
|
|
case 0x00100a00: {
|
|
// 0x0e100a00
|
|
switch (instr & 0x00a00140) {
|
|
case 0x00000000: {
|
|
// 0x0e100a00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VNMLS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
|
|
vnmls(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000040: {
|
|
// 0x0e100a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VNMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
|
|
vnmla(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0x0e100b00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VNMLS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
|
|
vnmls(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000140: {
|
|
// 0x0e100b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VNMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
|
|
vnmla(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200000: {
|
|
// 0x0e300a00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VADD{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
|
|
vadd(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200040: {
|
|
// 0x0e300a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VSUB{<c>}{<q>}.F32 {<Sd>}, <Sn>, <Sm> ; A2
|
|
vsub(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200100: {
|
|
// 0x0e300b00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VADD{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
|
|
vadd(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00200140: {
|
|
// 0x0e300b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSUB{<c>}{<q>}.F64 {<Dd>}, <Dn>, <Dm> ; A2
|
|
vsub(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00800000: {
|
|
// 0x0e900a00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VFNMS{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
|
|
vfnms(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00800040: {
|
|
// 0x0e900a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VFNMA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> ; A1
|
|
vfnma(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rn),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00800100: {
|
|
// 0x0e900b00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VFNMS{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
|
|
vfnms(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00800140: {
|
|
// 0x0e900b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VFNMA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> ; A1
|
|
vfnma(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rn),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00a00000: {
|
|
// 0x0eb00a00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
uint32_t encoded_imm =
|
|
(instr & 0xf) | ((instr >> 12) & 0xf0);
|
|
NeonImmediate imm =
|
|
ImmediateVFP::Decode<float>(encoded_imm);
|
|
// VMOV{<c>}{<q>}.F32 <Sd>, #<imm> ; A2
|
|
vmov(condition, F32, SRegister(rd), imm);
|
|
if (((instr & 0xfb00ff0) != 0xeb00a00)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00a00040: {
|
|
// 0x0eb00a40
|
|
switch (instr & 0x000e0000) {
|
|
case 0x00000000: {
|
|
// 0x0eb00a40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0x0eb00a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VMOV{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
|
|
vmov(condition, F32, SRegister(rd), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x0eb00ac0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VABS{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
|
|
vabs(condition, F32, SRegister(rd), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0x0eb10a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VNEG{<c>}{<q>}.F32 <Sd>, <Sm> ; A2
|
|
vneg(condition, F32, SRegister(rd), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0x0eb10ac0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VSQRT{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
|
|
vsqrt(condition, F32, SRegister(rd), SRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00020000: {
|
|
// 0x0eb20a40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0x0eb20a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTB{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
|
|
vcvtb(condition,
|
|
F32,
|
|
F16,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x0eb20ac0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTT{<c>}{<q>}.F32.F16 <Sd>, <Sm> ; A1
|
|
vcvtt(condition,
|
|
F32,
|
|
F16,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0x0eb30a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTB{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
|
|
vcvtb(condition,
|
|
F16,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0x0eb30ac0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTT{<c>}{<q>}.F16.F32 <Sd>, <Sm> ; A1
|
|
vcvtt(condition,
|
|
F16,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00040000: {
|
|
// 0x0eb40a40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0x0eb40a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCMP{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
|
|
vcmp(condition, F32, SRegister(rd), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x0eb40ac0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCMPE{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
|
|
vcmpe(condition, F32, SRegister(rd), SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0x0eb50a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
// VCMP{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
|
|
vcmp(condition, F32, SRegister(rd), 0.0);
|
|
if (((instr & 0xfbf0fff) != 0xeb50a40)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0x0eb50ac0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
// VCMPE{<c>}{<q>}.F32 <Sd>, #0.0 ; A2
|
|
vcmpe(condition, F32, SRegister(rd), 0.0);
|
|
if (((instr & 0xfbf0fff) != 0xeb50ac0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00060000: {
|
|
// 0x0eb60a40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0x0eb60a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VRINTR{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
|
|
vrintr(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x0eb60ac0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VRINTZ{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
|
|
vrintz(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0x0eb70a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VRINTX{<c>}{<q>}.F32 <Sd>, <Sm> ; A1
|
|
vrintx(condition,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0x0eb70ac0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.F64.F32 <Dd>, <Sm> ; A1
|
|
vcvt(condition,
|
|
F64,
|
|
F32,
|
|
DRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00080000: {
|
|
// 0x0eb80a40
|
|
if ((instr & 0x00010000) == 0x00000000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.F32.<dt> <Sd>, <Sm> ; A1
|
|
vcvt(condition,
|
|
F32,
|
|
dt,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000a0000: {
|
|
// 0x0eba0a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
DataType dt = Dt_U_sx_1_Decode(((instr >> 7) & 0x1) |
|
|
((instr >> 15) & 0x2));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned offset = 32;
|
|
if (dt.Is(S16) || dt.Is(U16)) {
|
|
offset = 16;
|
|
}
|
|
uint32_t fbits = offset - (((instr >> 5) & 0x1) |
|
|
((instr << 1) & 0x1e));
|
|
// VCVT{<c>}{<q>}.F32.<dt> <Sdm>, <Sdm>, #<fbits> ; A1
|
|
vcvt(condition,
|
|
F32,
|
|
dt,
|
|
SRegister(rd),
|
|
SRegister(rd),
|
|
fbits);
|
|
break;
|
|
}
|
|
case 0x000c0000: {
|
|
// 0x0ebc0a40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0x0ebc0a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTR{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
|
|
vcvtr(condition,
|
|
U32,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x0ebc0ac0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.U32.F32 <Sd>, <Sm> ; A1
|
|
vcvt(condition,
|
|
U32,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0x0ebd0a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTR{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
|
|
vcvtr(condition,
|
|
S32,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0x0ebd0ac0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.S32.F32 <Sd>, <Sm> ; A1
|
|
vcvt(condition,
|
|
S32,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x000e0000: {
|
|
// 0x0ebe0a40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
DataType dt = Dt_U_sx_1_Decode(((instr >> 7) & 0x1) |
|
|
((instr >> 15) & 0x2));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned offset = 32;
|
|
if (dt.Is(S16) || dt.Is(U16)) {
|
|
offset = 16;
|
|
}
|
|
uint32_t fbits = offset - (((instr >> 5) & 0x1) |
|
|
((instr << 1) & 0x1e));
|
|
// VCVT{<c>}{<q>}.<dt>.F32 <Sdm>, <Sdm>, #<fbits> ; A1
|
|
vcvt(condition,
|
|
dt,
|
|
F32,
|
|
SRegister(rd),
|
|
SRegister(rd),
|
|
fbits);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00a00100: {
|
|
// 0x0eb00b00
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
uint32_t encoded_imm =
|
|
(instr & 0xf) | ((instr >> 12) & 0xf0);
|
|
NeonImmediate imm =
|
|
ImmediateVFP::Decode<double>(encoded_imm);
|
|
// VMOV{<c>}{<q>}.F64 <Dd>, #<imm> ; A2
|
|
vmov(condition, F64, DRegister(rd), imm);
|
|
if (((instr & 0xfb00ff0) != 0xeb00b00)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00a00140: {
|
|
// 0x0eb00b40
|
|
switch (instr & 0x000e0000) {
|
|
case 0x00000000: {
|
|
// 0x0eb00b40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0x0eb00b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VMOV{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
|
|
vmov(condition, F64, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x0eb00bc0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VABS{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
|
|
vabs(condition, F64, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0x0eb10b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VNEG{<c>}{<q>}.F64 <Dd>, <Dm> ; A2
|
|
vneg(condition, F64, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0x0eb10bc0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VSQRT{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
|
|
vsqrt(condition, F64, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00020000: {
|
|
// 0x0eb20b40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0x0eb20b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTB{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
|
|
vcvtb(condition,
|
|
F64,
|
|
F16,
|
|
DRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x0eb20bc0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVTT{<c>}{<q>}.F64.F16 <Dd>, <Sm> ; A1
|
|
vcvtt(condition,
|
|
F64,
|
|
F16,
|
|
DRegister(rd),
|
|
SRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0x0eb30b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTB{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
|
|
vcvtb(condition,
|
|
F16,
|
|
F64,
|
|
SRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0x0eb30bc0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTT{<c>}{<q>}.F16.F64 <Sd>, <Dm> ; A1
|
|
vcvtt(condition,
|
|
F16,
|
|
F64,
|
|
SRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00040000: {
|
|
// 0x0eb40b40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0x0eb40b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCMP{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
|
|
vcmp(condition, F64, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x0eb40bc0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCMPE{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
|
|
vcmpe(condition, F64, DRegister(rd), DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0x0eb50b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
// VCMP{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
|
|
vcmp(condition, F64, DRegister(rd), 0.0);
|
|
if (((instr & 0xfbf0fff) != 0xeb50b40)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0x0eb50bc0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
// VCMPE{<c>}{<q>}.F64 <Dd>, #0.0 ; A2
|
|
vcmpe(condition, F64, DRegister(rd), 0.0);
|
|
if (((instr & 0xfbf0fff) != 0xeb50bc0)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00060000: {
|
|
// 0x0eb60b40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0x0eb60b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTR{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
|
|
vrintr(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x0eb60bc0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTZ{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
|
|
vrintz(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0x0eb70b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VRINTX{<c>}{<q>}.F64 <Dd>, <Dm> ; A1
|
|
vrintx(condition,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0x0eb70bc0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.F32.F64 <Sd>, <Dm> ; A1
|
|
vcvt(condition,
|
|
F32,
|
|
F64,
|
|
SRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00080000: {
|
|
// 0x0eb80b40
|
|
if ((instr & 0x00010000) == 0x00000000) {
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
DataType dt = Dt_op_2_Decode((instr >> 7) & 0x1);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned rm = ExtractSRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.F64.<dt> <Dd>, <Sm> ; A1
|
|
vcvt(condition,
|
|
F64,
|
|
dt,
|
|
DRegister(rd),
|
|
SRegister(rm));
|
|
} else {
|
|
UnallocatedA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x000a0000: {
|
|
// 0x0eba0b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
DataType dt = Dt_U_sx_1_Decode(((instr >> 7) & 0x1) |
|
|
((instr >> 15) & 0x2));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned offset = 32;
|
|
if (dt.Is(S16) || dt.Is(U16)) {
|
|
offset = 16;
|
|
}
|
|
uint32_t fbits = offset - (((instr >> 5) & 0x1) |
|
|
((instr << 1) & 0x1e));
|
|
// VCVT{<c>}{<q>}.F64.<dt> <Ddm>, <Ddm>, #<fbits> ; A1
|
|
vcvt(condition,
|
|
F64,
|
|
dt,
|
|
DRegister(rd),
|
|
DRegister(rd),
|
|
fbits);
|
|
break;
|
|
}
|
|
case 0x000c0000: {
|
|
// 0x0ebc0b40
|
|
switch (instr & 0x00010080) {
|
|
case 0x00000000: {
|
|
// 0x0ebc0b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTR{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
|
|
vcvtr(condition,
|
|
U32,
|
|
F64,
|
|
SRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00000080: {
|
|
// 0x0ebc0bc0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.U32.F64 <Sd>, <Dm> ; A1
|
|
vcvt(condition,
|
|
U32,
|
|
F64,
|
|
SRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010000: {
|
|
// 0x0ebd0b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVTR{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
|
|
vcvtr(condition,
|
|
S32,
|
|
F64,
|
|
SRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
case 0x00010080: {
|
|
// 0x0ebd0bc0
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rd = ExtractSRegister(instr, 22, 12);
|
|
unsigned rm = ExtractDRegister(instr, 5, 0);
|
|
// VCVT{<c>}{<q>}.S32.F64 <Sd>, <Dm> ; A1
|
|
vcvt(condition,
|
|
S32,
|
|
F64,
|
|
SRegister(rd),
|
|
DRegister(rm));
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x000e0000: {
|
|
// 0x0ebe0b40
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
DataType dt = Dt_U_sx_1_Decode(((instr >> 7) & 0x1) |
|
|
((instr >> 15) & 0x2));
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rd = ExtractDRegister(instr, 22, 12);
|
|
unsigned offset = 32;
|
|
if (dt.Is(S16) || dt.Is(U16)) {
|
|
offset = 16;
|
|
}
|
|
uint32_t fbits = offset - (((instr >> 5) & 0x1) |
|
|
((instr << 1) & 0x1e));
|
|
// VCVT{<c>}{<q>}.<dt>.F64 <Ddm>, <Ddm>, #<fbits> ; A1
|
|
vcvt(condition,
|
|
dt,
|
|
F64,
|
|
DRegister(rd),
|
|
DRegister(rd),
|
|
fbits);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100a10: {
|
|
// 0x0e100a10
|
|
switch (instr & 0x00000100) {
|
|
case 0x00000000: {
|
|
// 0x0e100a10
|
|
switch (instr & 0x00e00000) {
|
|
case 0x00000000: {
|
|
// 0x0e100a10
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = ExtractSRegister(instr, 7, 16);
|
|
// VMOV{<c>}{<q>} <Rt>, <Sn> ; A1
|
|
vmov(condition, Register(rt), SRegister(rn));
|
|
if (((instr & 0xff00f7f) != 0xe100a10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
case 0x00e00000: {
|
|
// 0x0ef00a10
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned spec_reg = (instr >> 16) & 0xf;
|
|
switch (spec_reg) {
|
|
case 0x0:
|
|
case 0x1:
|
|
case 0x5:
|
|
case 0x6:
|
|
case 0x7:
|
|
case 0x8: {
|
|
// VMRS{<c>}{<q>} <Rt>, <spec_reg> ; A1
|
|
vmrs(condition,
|
|
RegisterOrAPSR_nzcv(rt),
|
|
SpecialFPRegister(spec_reg));
|
|
if (((instr & 0xff00fff) != 0xef00a10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x00000100: {
|
|
// 0x0e100b10
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
unsigned lane;
|
|
DataType dt =
|
|
Dt_U_opc1_opc2_1_Decode(((instr >> 5) & 0x3) |
|
|
((instr >> 19) & 0xc) |
|
|
((instr >> 19) & 0x10),
|
|
&lane);
|
|
if (dt.Is(kDataTypeValueInvalid)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
unsigned rt = (instr >> 12) & 0xf;
|
|
unsigned rn = ExtractDRegister(instr, 7, 16);
|
|
// VMOV{<c>}{<q>}{.<dt>} <Rt>, <Dn[x]> ; A1
|
|
vmov(condition, dt, Register(rt), DRegisterLane(rn, lane));
|
|
if (((instr & 0xf100f1f) != 0xe100b10)) {
|
|
UnpredictableA32(instr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case 0x00100e10: {
|
|
// 0x0e100e10
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
UnimplementedA32("MRC", instr);
|
|
break;
|
|
}
|
|
default:
|
|
UnallocatedA32(instr);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case 0x01000000: {
|
|
// 0x0f000000
|
|
if (((instr & 0xf0000000) == 0xf0000000)) {
|
|
UnallocatedA32(instr);
|
|
return;
|
|
}
|
|
Condition condition((instr >> 28) & 0xf);
|
|
uint32_t imm = instr & 0xffffff;
|
|
// SVC{<c>}{<q>} {#}<imm> ; A1
|
|
svc(condition, imm);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} // NOLINT(readability/fn_size)
|
|
// End of generated code.
|
|
|
|
const uint16_t* PrintDisassembler::DecodeT32At(
|
|
const uint16_t* instruction_address, const uint16_t* buffer_end) {
|
|
uint32_t instruction = *instruction_address++ << 16;
|
|
|
|
if (instruction >= kLowestT32_32Opcode) {
|
|
if (instruction_address >= buffer_end) {
|
|
os() << "?\n";
|
|
return instruction_address;
|
|
}
|
|
instruction |= *instruction_address++;
|
|
}
|
|
|
|
DecodeT32(instruction);
|
|
return instruction_address;
|
|
}
|
|
|
|
void PrintDisassembler::DecodeT32(uint32_t instruction) {
|
|
PrintCodeAddress(GetCodeAddress());
|
|
if (T32Size(instruction) == 2) {
|
|
PrintOpcode16(instruction >> 16);
|
|
Disassembler::DecodeT32(instruction);
|
|
} else {
|
|
PrintOpcode32(instruction);
|
|
Disassembler::DecodeT32(instruction);
|
|
}
|
|
os() << "\n";
|
|
}
|
|
|
|
|
|
void PrintDisassembler::DecodeA32(uint32_t instruction) {
|
|
PrintCodeAddress(GetCodeAddress());
|
|
PrintOpcode32(instruction);
|
|
Disassembler::DecodeA32(instruction);
|
|
os() << "\n";
|
|
}
|
|
|
|
|
|
void PrintDisassembler::DisassembleA32Buffer(const uint32_t* buffer,
|
|
size_t size_in_bytes) {
|
|
VIXL_ASSERT(IsAligned<sizeof(buffer[0])>(buffer));
|
|
VIXL_ASSERT(IsMultiple<sizeof(buffer[0])>(size_in_bytes));
|
|
const uint32_t* const end_buffer =
|
|
buffer + (size_in_bytes / sizeof(uint32_t));
|
|
while (buffer < end_buffer) {
|
|
DecodeA32(*buffer++);
|
|
}
|
|
}
|
|
|
|
|
|
void PrintDisassembler::DisassembleT32Buffer(const uint16_t* buffer,
|
|
size_t size_in_bytes) {
|
|
VIXL_ASSERT(IsAligned<sizeof(buffer[0])>(buffer));
|
|
VIXL_ASSERT(IsMultiple<sizeof(buffer[0])>(size_in_bytes));
|
|
const uint16_t* const end_buffer =
|
|
buffer + (size_in_bytes / sizeof(uint16_t));
|
|
while (buffer < end_buffer) {
|
|
buffer = DecodeT32At(buffer, end_buffer);
|
|
}
|
|
VIXL_ASSERT(buffer == end_buffer);
|
|
}
|
|
|
|
} // namespace aarch32
|
|
} // namespace vixl
|