+ // Handle NEON VST1 complex aliases.
+ case ARM::VST1LNdWB_register_Asm_8:
+ case ARM::VST1LNdWB_register_Asm_P8:
+ case ARM::VST1LNdWB_register_Asm_I8:
+ case ARM::VST1LNdWB_register_Asm_S8:
+ case ARM::VST1LNdWB_register_Asm_U8:
+ case ARM::VST1LNdWB_register_Asm_16:
+ case ARM::VST1LNdWB_register_Asm_P16:
+ case ARM::VST1LNdWB_register_Asm_I16:
+ case ARM::VST1LNdWB_register_Asm_S16:
+ case ARM::VST1LNdWB_register_Asm_U16:
+ case ARM::VST1LNdWB_register_Asm_32:
+ case ARM::VST1LNdWB_register_Asm_F:
+ case ARM::VST1LNdWB_register_Asm_F32:
+ case ARM::VST1LNdWB_register_Asm_I32:
+ case ARM::VST1LNdWB_register_Asm_S32:
+ case ARM::VST1LNdWB_register_Asm_U32: {
+ MCInst TmpInst;
+ // Shuffle the operands around so the lane index operand is in the
+ // right place.
+ TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode()));
+ TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
+ TmpInst.addOperand(Inst.getOperand(2)); // Rn
+ TmpInst.addOperand(Inst.getOperand(3)); // alignment
+ TmpInst.addOperand(Inst.getOperand(4)); // Rm
+ TmpInst.addOperand(Inst.getOperand(0)); // Vd
+ TmpInst.addOperand(Inst.getOperand(1)); // lane
+ TmpInst.addOperand(Inst.getOperand(5)); // CondCode
+ TmpInst.addOperand(Inst.getOperand(6));
+ Inst = TmpInst;
+ return true;
+ }
+ case ARM::VST1LNdWB_fixed_Asm_8:
+ case ARM::VST1LNdWB_fixed_Asm_P8:
+ case ARM::VST1LNdWB_fixed_Asm_I8:
+ case ARM::VST1LNdWB_fixed_Asm_S8:
+ case ARM::VST1LNdWB_fixed_Asm_U8:
+ case ARM::VST1LNdWB_fixed_Asm_16:
+ case ARM::VST1LNdWB_fixed_Asm_P16:
+ case ARM::VST1LNdWB_fixed_Asm_I16:
+ case ARM::VST1LNdWB_fixed_Asm_S16:
+ case ARM::VST1LNdWB_fixed_Asm_U16:
+ case ARM::VST1LNdWB_fixed_Asm_32:
+ case ARM::VST1LNdWB_fixed_Asm_F:
+ case ARM::VST1LNdWB_fixed_Asm_F32:
+ case ARM::VST1LNdWB_fixed_Asm_I32:
+ case ARM::VST1LNdWB_fixed_Asm_S32:
+ case ARM::VST1LNdWB_fixed_Asm_U32: {
+ MCInst TmpInst;
+ // Shuffle the operands around so the lane index operand is in the
+ // right place.
+ TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode()));
+ TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
+ TmpInst.addOperand(Inst.getOperand(2)); // Rn
+ TmpInst.addOperand(Inst.getOperand(3)); // alignment
+ TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(Inst.getOperand(0)); // Vd
+ TmpInst.addOperand(Inst.getOperand(1)); // lane
+ TmpInst.addOperand(Inst.getOperand(4)); // CondCode
+ TmpInst.addOperand(Inst.getOperand(5));
+ Inst = TmpInst;
+ return true;
+ }
+ case ARM::VST1LNdAsm_8:
+ case ARM::VST1LNdAsm_P8:
+ case ARM::VST1LNdAsm_I8:
+ case ARM::VST1LNdAsm_S8:
+ case ARM::VST1LNdAsm_U8:
+ case ARM::VST1LNdAsm_16:
+ case ARM::VST1LNdAsm_P16:
+ case ARM::VST1LNdAsm_I16:
+ case ARM::VST1LNdAsm_S16:
+ case ARM::VST1LNdAsm_U16:
+ case ARM::VST1LNdAsm_32:
+ case ARM::VST1LNdAsm_F:
+ case ARM::VST1LNdAsm_F32:
+ case ARM::VST1LNdAsm_I32:
+ case ARM::VST1LNdAsm_S32:
+ case ARM::VST1LNdAsm_U32: {
+ MCInst TmpInst;
+ // Shuffle the operands around so the lane index operand is in the
+ // right place.
+ TmpInst.setOpcode(getRealVSTLNOpcode(Inst.getOpcode()));
+ TmpInst.addOperand(Inst.getOperand(2)); // Rn
+ TmpInst.addOperand(Inst.getOperand(3)); // alignment
+ TmpInst.addOperand(Inst.getOperand(0)); // Vd
+ TmpInst.addOperand(Inst.getOperand(1)); // lane
+ TmpInst.addOperand(Inst.getOperand(4)); // CondCode
+ TmpInst.addOperand(Inst.getOperand(5));
+ Inst = TmpInst;
+ return true;
+ }
+ // Handle NEON VLD1 complex aliases.
+ case ARM::VLD1LNdWB_register_Asm_8:
+ case ARM::VLD1LNdWB_register_Asm_P8:
+ case ARM::VLD1LNdWB_register_Asm_I8:
+ case ARM::VLD1LNdWB_register_Asm_S8:
+ case ARM::VLD1LNdWB_register_Asm_U8:
+ case ARM::VLD1LNdWB_register_Asm_16:
+ case ARM::VLD1LNdWB_register_Asm_P16:
+ case ARM::VLD1LNdWB_register_Asm_I16:
+ case ARM::VLD1LNdWB_register_Asm_S16:
+ case ARM::VLD1LNdWB_register_Asm_U16:
+ case ARM::VLD1LNdWB_register_Asm_32:
+ case ARM::VLD1LNdWB_register_Asm_F:
+ case ARM::VLD1LNdWB_register_Asm_F32:
+ case ARM::VLD1LNdWB_register_Asm_I32:
+ case ARM::VLD1LNdWB_register_Asm_S32:
+ case ARM::VLD1LNdWB_register_Asm_U32: {
+ MCInst TmpInst;
+ // Shuffle the operands around so the lane index operand is in the
+ // right place.
+ TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode()));
+ TmpInst.addOperand(Inst.getOperand(0)); // Vd
+ TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
+ TmpInst.addOperand(Inst.getOperand(2)); // Rn
+ TmpInst.addOperand(Inst.getOperand(3)); // alignment
+ TmpInst.addOperand(Inst.getOperand(4)); // Rm
+ TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
+ TmpInst.addOperand(Inst.getOperand(1)); // lane
+ TmpInst.addOperand(Inst.getOperand(5)); // CondCode
+ TmpInst.addOperand(Inst.getOperand(6));
+ Inst = TmpInst;
+ return true;
+ }
+ case ARM::VLD1LNdWB_fixed_Asm_8:
+ case ARM::VLD1LNdWB_fixed_Asm_P8:
+ case ARM::VLD1LNdWB_fixed_Asm_I8:
+ case ARM::VLD1LNdWB_fixed_Asm_S8:
+ case ARM::VLD1LNdWB_fixed_Asm_U8:
+ case ARM::VLD1LNdWB_fixed_Asm_16:
+ case ARM::VLD1LNdWB_fixed_Asm_P16:
+ case ARM::VLD1LNdWB_fixed_Asm_I16:
+ case ARM::VLD1LNdWB_fixed_Asm_S16:
+ case ARM::VLD1LNdWB_fixed_Asm_U16:
+ case ARM::VLD1LNdWB_fixed_Asm_32:
+ case ARM::VLD1LNdWB_fixed_Asm_F:
+ case ARM::VLD1LNdWB_fixed_Asm_F32:
+ case ARM::VLD1LNdWB_fixed_Asm_I32:
+ case ARM::VLD1LNdWB_fixed_Asm_S32:
+ case ARM::VLD1LNdWB_fixed_Asm_U32: {
+ MCInst TmpInst;
+ // Shuffle the operands around so the lane index operand is in the
+ // right place.
+ TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode()));
+ TmpInst.addOperand(Inst.getOperand(0)); // Vd
+ TmpInst.addOperand(Inst.getOperand(2)); // Rn_wb
+ TmpInst.addOperand(Inst.getOperand(2)); // Rn
+ TmpInst.addOperand(Inst.getOperand(3)); // alignment
+ TmpInst.addOperand(MCOperand::CreateReg(0)); // Rm
+ TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
+ TmpInst.addOperand(Inst.getOperand(1)); // lane
+ TmpInst.addOperand(Inst.getOperand(4)); // CondCode
+ TmpInst.addOperand(Inst.getOperand(5));
+ Inst = TmpInst;
+ return true;
+ }
+ case ARM::VLD1LNdAsm_8:
+ case ARM::VLD1LNdAsm_P8:
+ case ARM::VLD1LNdAsm_I8:
+ case ARM::VLD1LNdAsm_S8:
+ case ARM::VLD1LNdAsm_U8:
+ case ARM::VLD1LNdAsm_16:
+ case ARM::VLD1LNdAsm_P16:
+ case ARM::VLD1LNdAsm_I16:
+ case ARM::VLD1LNdAsm_S16:
+ case ARM::VLD1LNdAsm_U16:
+ case ARM::VLD1LNdAsm_32:
+ case ARM::VLD1LNdAsm_F:
+ case ARM::VLD1LNdAsm_F32:
+ case ARM::VLD1LNdAsm_I32:
+ case ARM::VLD1LNdAsm_S32:
+ case ARM::VLD1LNdAsm_U32: {
+ MCInst TmpInst;
+ // Shuffle the operands around so the lane index operand is in the
+ // right place.
+ TmpInst.setOpcode(getRealVLDLNOpcode(Inst.getOpcode()));
+ TmpInst.addOperand(Inst.getOperand(0)); // Vd
+ TmpInst.addOperand(Inst.getOperand(2)); // Rn
+ TmpInst.addOperand(Inst.getOperand(3)); // alignment
+ TmpInst.addOperand(Inst.getOperand(0)); // Tied operand src (== Vd)
+ TmpInst.addOperand(Inst.getOperand(1)); // lane
+ TmpInst.addOperand(Inst.getOperand(4)); // CondCode
+ TmpInst.addOperand(Inst.getOperand(5));
+ Inst = TmpInst;
+ return true;
+ }
+ // Handle the MOV complex aliases.
+ case ARM::ASRr:
+ case ARM::LSRr:
+ case ARM::LSLr:
+ case ARM::RORr: {
+ ARM_AM::ShiftOpc ShiftTy;
+ switch(Inst.getOpcode()) {
+ default: llvm_unreachable("unexpected opcode!");
+ case ARM::ASRr: ShiftTy = ARM_AM::asr; break;
+ case ARM::LSRr: ShiftTy = ARM_AM::lsr; break;
+ case ARM::LSLr: ShiftTy = ARM_AM::lsl; break;
+ case ARM::RORr: ShiftTy = ARM_AM::ror; break;
+ }
+ // A shift by zero is a plain MOVr, not a MOVsi.
+ unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, 0);
+ MCInst TmpInst;
+ TmpInst.setOpcode(ARM::MOVsr);
+ TmpInst.addOperand(Inst.getOperand(0)); // Rd
+ TmpInst.addOperand(Inst.getOperand(1)); // Rn
+ TmpInst.addOperand(Inst.getOperand(2)); // Rm
+ TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
+ TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+ TmpInst.addOperand(Inst.getOperand(4));
+ TmpInst.addOperand(Inst.getOperand(5)); // cc_out
+ Inst = TmpInst;
+ return true;
+ }
+ case ARM::ASRi:
+ case ARM::LSRi:
+ case ARM::LSLi:
+ case ARM::RORi: {
+ ARM_AM::ShiftOpc ShiftTy;
+ switch(Inst.getOpcode()) {
+ default: llvm_unreachable("unexpected opcode!");
+ case ARM::ASRi: ShiftTy = ARM_AM::asr; break;
+ case ARM::LSRi: ShiftTy = ARM_AM::lsr; break;
+ case ARM::LSLi: ShiftTy = ARM_AM::lsl; break;
+ case ARM::RORi: ShiftTy = ARM_AM::ror; break;
+ }
+ // A shift by zero is a plain MOVr, not a MOVsi.
+ unsigned Amt = Inst.getOperand(2).getImm();
+ unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
+ unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
+ MCInst TmpInst;
+ TmpInst.setOpcode(Opc);
+ TmpInst.addOperand(Inst.getOperand(0)); // Rd
+ TmpInst.addOperand(Inst.getOperand(1)); // Rn
+ if (Opc == ARM::MOVsi)
+ TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
+ TmpInst.addOperand(Inst.getOperand(3)); // CondCode
+ TmpInst.addOperand(Inst.getOperand(4));
+ TmpInst.addOperand(Inst.getOperand(5)); // cc_out
+ Inst = TmpInst;
+ return true;
+ }
+ case ARM::RRXi: {
+ unsigned Shifter = ARM_AM::getSORegOpc(ARM_AM::rrx, 0);
+ MCInst TmpInst;
+ TmpInst.setOpcode(ARM::MOVsi);
+ TmpInst.addOperand(Inst.getOperand(0)); // Rd
+ TmpInst.addOperand(Inst.getOperand(1)); // Rn
+ TmpInst.addOperand(MCOperand::CreateImm(Shifter)); // Shift value and ty
+ TmpInst.addOperand(Inst.getOperand(2)); // CondCode
+ TmpInst.addOperand(Inst.getOperand(3));
+ TmpInst.addOperand(Inst.getOperand(4)); // cc_out
+ Inst = TmpInst;
+ return true;
+ }
+ case ARM::t2LDMIA_UPD: {
+ // If this is a load of a single register, then we should use
+ // a post-indexed LDR instruction instead, per the ARM ARM.
+ if (Inst.getNumOperands() != 5)
+ return false;
+ MCInst TmpInst;
+ TmpInst.setOpcode(ARM::t2LDR_POST);
+ TmpInst.addOperand(Inst.getOperand(4)); // Rt
+ TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
+ TmpInst.addOperand(Inst.getOperand(1)); // Rn
+ TmpInst.addOperand(MCOperand::CreateImm(4));
+ TmpInst.addOperand(Inst.getOperand(2)); // CondCode
+ TmpInst.addOperand(Inst.getOperand(3));
+ Inst = TmpInst;
+ return true;
+ }
+ case ARM::t2STMDB_UPD: {
+ // If this is a store of a single register, then we should use
+ // a pre-indexed STR instruction instead, per the ARM ARM.
+ if (Inst.getNumOperands() != 5)
+ return false;
+ MCInst TmpInst;
+ TmpInst.setOpcode(ARM::t2STR_PRE);
+ TmpInst.addOperand(Inst.getOperand(0)); // Rn_wb
+ TmpInst.addOperand(Inst.getOperand(4)); // Rt
+ TmpInst.addOperand(Inst.getOperand(1)); // Rn
+ TmpInst.addOperand(MCOperand::CreateImm(-4));
+ TmpInst.addOperand(Inst.getOperand(2)); // CondCode
+ TmpInst.addOperand(Inst.getOperand(3));
+ Inst = TmpInst;
+ return true;
+ }