uint64_t Address, const void *Decoder);
static bool DecodeCoprocessor(llvm::MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
-static bool DecodeAddrMode3Offset(llvm::MCInst &Inst, unsigned Insn,
- uint64_t Address, const void *Decoder);
static bool DecodeMemBarrierOption(llvm::MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder);
+static bool DecodeMSRMask(llvm::MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder);
+static bool DecodeDoubleRegLoad(llvm::MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder);
+static bool DecodeDoubleRegStore(llvm::MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder);
+static bool DecodeSTRPreImm(llvm::MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder);
+static bool DecodeSTRPreReg(llvm::MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder);
static bool DecodeThumbAddSpecialReg(llvm::MCInst &Inst, uint16_t Insn,
}
MI.clear();
- result = decodeNEONInstruction32(MI, insn, Address, this);
+ result = decodeNEONDataInstruction32(MI, insn, Address, this);
if (result) {
+ Size = 4;
// Add a fake predicate operand, because we share these instruction
// definitions with Thumb2 where these instructions are predicable.
if (!DecodePredicateOperand(MI, 0xE, Address, this)) return false;
+ return true;
+ }
+
+ MI.clear();
+ result = decodeNEONLoadStoreInstruction32(MI, insn, Address, this);
+ if (result) {
Size = 4;
+ // Add a fake predicate operand, because we share these instruction
+ // definitions with Thumb2 where these instructions are predicable.
+ if (!DecodePredicateOperand(MI, 0xE, Address, this)) return false;
+ return true;
+ }
+
+ MI.clear();
+ result = decodeNEONDupInstruction32(MI, insn, Address, this);
+ if (result) {
+ Size = 4;
+ // Add a fake predicate operand, because we share these instruction
+ // definitions with Thumb2 where these instructions are predicable.
+ if (!DecodePredicateOperand(MI, 0xE, Address, this)) return false;
return true;
}
return true;
}
+ MI.clear();
+ result = decodeCommonInstruction32(MI, insn32, Address, this);
+ if (result) {
+ Size = 4;
+ AddThumbPredicate(MI);
+ return true;
+ }
+
MI.clear();
result = decodeVFPInstruction32(MI, insn32, Address, this);
if (result) {
}
MI.clear();
- result = decodeCommonInstruction32(MI, insn32, Address, this);
+ if (fieldFromInstruction32(insn32, 24, 4) == 0xF) {
+ uint32_t NEONDataInsn = insn32;
+ NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
+ NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
+ NEONDataInsn |= 0x12000000; // Set bits 28 and 25
+ result = decodeNEONDataInstruction32(MI, NEONDataInsn, Address, this);
+ if (result) {
+ Size = 4;
+ AddThumbPredicate(MI);
+ return true;
+ }
+ }
+
+ MI.clear();
+ result = decodeNEONLoadStoreInstruction32(MI, insn32, Address, this);
+ if (result) {
+ Size = 4;
+ AddThumbPredicate(MI);
+ return true;
+ }
+
+ MI.clear();
+ result = decodeNEONDupInstruction32(MI, insn32, Address, this);
if (result) {
Size = 4;
AddThumbPredicate(MI);
unsigned imm = fieldFromInstruction32(Val, 7, 5);
// Register-immediate
- DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)) return false;
ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
switch (type) {
static bool DecodeRegListOperand(llvm::MCInst &Inst, unsigned Val,
uint64_t Address, const void *Decoder) {
+ // Empty register lists are not allowed.
+ if (CountPopulation_32(Val) == 0) return false;
for (unsigned i = 0; i < 16; ++i) {
- if (Val & (1 << i))
- DecodeGPRRegisterClass(Inst, i, Address, Decoder);
+ if (Val & (1 << i)) {
+ if (!DecodeGPRRegisterClass(Inst, i, Address, Decoder)) return false;
+ }
}
return true;
unsigned Vd = fieldFromInstruction32(Val, 8, 4);
unsigned regs = Val & 0xFF;
- DecodeSPRRegisterClass(Inst, Vd, Address, Decoder);
- for (unsigned i = 0; i < (regs - 1); ++i)
- DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder);
+ if (!DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)) return false;
+ for (unsigned i = 0; i < (regs - 1); ++i) {
+ if (!DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)) return false;
+ }
return true;
}
unsigned Vd = fieldFromInstruction32(Val, 8, 4);
unsigned regs = (Val & 0xFF) / 2;
- DecodeDPRRegisterClass(Inst, Vd, Address, Decoder);
- for (unsigned i = 0; i < (regs - 1); ++i)
- DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)) return false;
+ for (unsigned i = 0; i < (regs - 1); ++i) {
+ if (!DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)) return false;
+ }
return true;
}
Inst.addOperand(MCOperand::CreateImm(coproc));
Inst.addOperand(MCOperand::CreateImm(CRd));
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
switch (Inst.getOpcode()) {
case ARM::LDC_OPTION:
case ARM::LDCL_OPTION:
switch (Inst.getOpcode()) {
case ARM::STR_POST_IMM:
case ARM::STR_POST_REG:
- case ARM::STRTr:
- case ARM::STRTi:
- case ARM::STRBTr:
- case ARM::STRBTi:
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ case ARM::STRB_POST_IMM:
+ case ARM::STRB_POST_REG:
+ case ARM::STRT_POST_REG:
+ case ARM::STRT_POST_IMM:
+ case ARM::STRBT_POST_REG:
+ case ARM::STRBT_POST_IMM:
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
break;
default:
break;
}
- DecodeGPRRegisterClass(Inst, Rt, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)) return false;
// On loads, the writeback operand comes after Rt.
switch (Inst.getOpcode()) {
case ARM::LDR_POST_IMM:
case ARM::LDR_POST_REG:
+ case ARM::LDRB_POST_IMM:
+ case ARM::LDRB_POST_REG:
case ARM::LDR_PRE:
+ case ARM::LDRB_PRE:
case ARM::LDRBT_POST_REG:
case ARM::LDRBT_POST_IMM:
- case ARM::LDRTr:
- case ARM::LDRTi:
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ case ARM::LDRT_POST_REG:
+ case ARM::LDRT_POST_IMM:
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))
+ return false;
break;
default:
break;
}
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
ARM_AM::AddrOpc Op = ARM_AM::add;
if (!fieldFromInstruction32(Insn, 23, 1))
else if (!P && writeback)
idx_mode = ARMII::IndexModePost;
+ if (writeback && (Rn == 15 || Rn == Rt)) return false; // UNPREDICTABLE
+
if (reg) {
- DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
+ if (!DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)) return false;
ARM_AM::ShiftOpc Opc = ARM_AM::lsl;
switch( fieldFromInstruction32(Insn, 5, 2)) {
case 0:
break;
}
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
- DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
+ if (!DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)) return false;
unsigned shift;
if (U)
shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp);
case ARM::STRD:
case ARM::STRD_PRE:
case ARM::STRD_POST:
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ case ARM::STRH:
+ case ARM::STRH_PRE:
+ case ARM::STRH_POST:
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))
+ return false;
break;
default:
break;
}
}
- DecodeGPRRegisterClass(Inst, Rt, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))
+ return false;
switch (Inst.getOpcode()) {
case ARM::STRD:
case ARM::STRD_PRE:
case ARM::LDRD:
case ARM::LDRD_PRE:
case ARM::LDRD_POST:
- DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder))
+ return false;
break;
default:
break;
case ARM::LDRD:
case ARM::LDRD_PRE:
case ARM::LDRD_POST:
+ case ARM::LDRH:
+ case ARM::LDRH_PRE:
+ case ARM::LDRH_POST:
+ case ARM::LDRSH:
+ case ARM::LDRSH_PRE:
+ case ARM::LDRSH_POST:
+ case ARM::LDRSB:
+ case ARM::LDRSB_PRE:
+ case ARM::LDRSB_POST:
case ARM::LDRHTr:
case ARM::LDRSBTr:
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))
+ return false;
break;
default:
break;
}
}
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))
+ return false;
if (type) {
Inst.addOperand(MCOperand::CreateReg(0));
Inst.addOperand(MCOperand::CreateImm(U | (imm << 4) | Rm));
} else {
- DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))
+ return false;
Inst.addOperand(MCOperand::CreateImm(U));
}
}
Inst.addOperand(MCOperand::CreateImm(mode));
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
return true;
}
return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
}
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder); // Tied
- if (!DecodePredicateOperand(Inst, pred, Address, Decoder)) return false;
- DecodeRegListOperand(Inst, reglist, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder) ||
+ !DecodeGPRRegisterClass(Inst, Rn, Address, Decoder) || // Tied
+ !DecodePredicateOperand(Inst, pred, Address, Decoder) ||
+ !DecodeRegListOperand(Inst, reglist, Address, Decoder))
+ return false;
return true;
}
if (pred == 0xF)
return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
- DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder);
- DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder);
- DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder);
- DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder);
+ if (!DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder) ||
+ !DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder) ||
+ !DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder) ||
+ !DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder))
+ return false;
+
+ if (!DecodePredicateOperand(Inst, pred, Address, Decoder)) return false;
return true;
}
unsigned imm = fieldFromInstruction32(Val, 0, 12);
unsigned Rn = fieldFromInstruction32(Val, 13, 4);
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))
+ return false;
if (!add) imm *= -1;
if (imm == 0 && !add) imm = INT32_MIN;
unsigned U = fieldFromInstruction32(Val, 8, 1);
unsigned imm = fieldFromInstruction32(Val, 0, 8);
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))
+ return false;
if (U)
Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, imm)));
unsigned Rm = fieldFromInstruction32(Val, 0, 4);
unsigned align = fieldFromInstruction32(Val, 4, 2);
- DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))
+ return false;
if (!align)
Inst.addOperand(MCOperand::CreateImm(0));
else
unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
// First output register
- DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)) return false;
// Second output register
switch (Inst.getOpcode()) {
case ARM::VLD4d8_UPD:
case ARM::VLD4d16_UPD:
case ARM::VLD4d32_UPD:
- DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)) return false;
break;
case ARM::VLD2b8:
case ARM::VLD2b16:
case ARM::VLD4q8_UPD:
case ARM::VLD4q16_UPD:
case ARM::VLD4q32_UPD:
- DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)) return false;
default:
break;
}
case ARM::VLD4d8_UPD:
case ARM::VLD4d16_UPD:
case ARM::VLD4d32_UPD:
- DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)) return false;
break;
case ARM::VLD3q8:
case ARM::VLD3q16:
case ARM::VLD4q8_UPD:
case ARM::VLD4q16_UPD:
case ARM::VLD4q32_UPD:
- DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)) return false;
break;
default:
break;
case ARM::VLD4d8_UPD:
case ARM::VLD4d16_UPD:
case ARM::VLD4d32_UPD:
- DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)) return false;
break;
case ARM::VLD4q8:
case ARM::VLD4q16:
case ARM::VLD4q8_UPD:
case ARM::VLD4q16_UPD:
case ARM::VLD4q32_UPD:
- DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)) return false;
break;
default:
break;
case ARM::VLD4q8_UPD:
case ARM::VLD4q16_UPD:
case ARM::VLD4q32_UPD:
- DecodeGPRRegisterClass(Inst, wb, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, wb, Address, Decoder)) return false;
break;
default:
break;
}
// AddrMode6 Base (register+alignment)
- DecodeAddrMode6Operand(Inst, Rn, Address, Decoder);
+ if (!DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)) return false;
// AddrMode6 Offset (register)
if (Rm == 0xD)
Inst.addOperand(MCOperand::CreateReg(0));
- else if (Rm != 0xF)
- DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
+ else if (Rm != 0xF) {
+ if (!DecodeGPRRegisterClass(Inst, Rm, Address, Decoder))
+ return false;
+ }
return true;
}
case ARM::VST4q8_UPD:
case ARM::VST4q16_UPD:
case ARM::VST4q32_UPD:
- DecodeGPRRegisterClass(Inst, wb, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, wb, Address, Decoder))
+ return false;
break;
default:
break;
}
// AddrMode6 Base (register+alignment)
- DecodeAddrMode6Operand(Inst, Rn, Address, Decoder);
+ if (!DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)) return false;
// AddrMode6 Offset (register)
if (Rm == 0xD)
Inst.addOperand(MCOperand::CreateReg(0));
- else if (Rm != 0xF)
- DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
+ else if (Rm != 0xF) {
+ if (!DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)) return false;
+ }
// First input register
- DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)) return false;
// Second input register
switch (Inst.getOpcode()) {
case ARM::VST4d8_UPD:
case ARM::VST4d16_UPD:
case ARM::VST4d32_UPD:
- DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)) return false;
break;
case ARM::VST2b8:
case ARM::VST2b16:
case ARM::VST4q8_UPD:
case ARM::VST4q16_UPD:
case ARM::VST4q32_UPD:
- DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)) return false;
break;
default:
break;
case ARM::VST4d8_UPD:
case ARM::VST4d16_UPD:
case ARM::VST4d32_UPD:
- DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)) return false;
break;
case ARM::VST3q8:
case ARM::VST3q16:
case ARM::VST4q8_UPD:
case ARM::VST4q16_UPD:
case ARM::VST4q32_UPD:
- DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)) return false;
break;
default:
break;
case ARM::VST4d8_UPD:
case ARM::VST4d16_UPD:
case ARM::VST4d32_UPD:
- DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)) return false;
break;
case ARM::VST4q8:
case ARM::VST4q16:
case ARM::VST4q8_UPD:
case ARM::VST4q16_UPD:
case ARM::VST4q32_UPD:
- DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)) return false;
break;
default:
break;
align *= (1 << size);
- DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
- if (regs == 2) DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder);
- if (Rm == 0xD) DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)) return false;
+ if (regs == 2) {
+ if (!DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)) return false;
+ }
+ if (Rm == 0xD) {
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
+ }
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
Inst.addOperand(MCOperand::CreateImm(align));
if (Rm == 0xD)
Inst.addOperand(MCOperand::CreateReg(0));
- else if (Rm != 0xF)
- DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
+ else if (Rm != 0xF) {
+ if (!DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)) return false;
+ }
return true;
}
unsigned inc = fieldFromInstruction32(Insn, 5, 1) + 1;
align *= 2*size;
- DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
- DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder);
- if (Rm == 0xD) DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)) return false;
+ if (!DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)) return false;
+ if (Rm == 0xD) {
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
+ }
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
Inst.addOperand(MCOperand::CreateImm(align));
if (Rm == 0xD)
Inst.addOperand(MCOperand::CreateReg(0));
- else if (Rm != 0xF)
- DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
+ else if (Rm != 0xF) {
+ if (!DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)) return false;
+ }
return true;
}
unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
unsigned inc = fieldFromInstruction32(Insn, 5, 1) + 1;
- DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
- DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder);
- DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder);
- if (Rm == 0xD) DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, Rd, Address, Decoder) ||
+ !DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder) ||
+ !DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder))
+ return false;
+ if (Rm == 0xD) {
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
+ }
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
Inst.addOperand(MCOperand::CreateImm(0));
if (Rm == 0xD)
Inst.addOperand(MCOperand::CreateReg(0));
- else if (Rm != 0xF)
- DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
+ else if (Rm != 0xF) {
+ if (!DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)) return false;
+ }
return true;
}
}
}
- DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
- DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder);
- DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder);
- DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder);
- if (Rm == 0xD) DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, Rd, Address, Decoder) ||
+ !DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder) ||
+ !DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder) ||
+ !DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder))
+ return false;
+ if (Rm == 0xD) {
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
+ }
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
Inst.addOperand(MCOperand::CreateImm(align));
if (Rm == 0xD)
Inst.addOperand(MCOperand::CreateReg(0));
- else if (Rm != 0xF)
- DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
+ else if (Rm != 0xF) {
+ if (!DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)) return false;
+ }
return true;
}
imm |= fieldFromInstruction32(Insn, 5, 1) << 12;
unsigned Q = fieldFromInstruction32(Insn, 6, 1);
- if (Q)
- DecodeQPRRegisterClass(Inst, Rd, Address, Decoder);
- else
- DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
+ if (Q) {
+ if (!DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)) return false;
+ } else {
+ if (!DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)) return false;
+ }
Inst.addOperand(MCOperand::CreateImm(imm));
case ARM::VORRiv2i32:
case ARM::VBICiv4i16:
case ARM::VBICiv2i32:
- DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)) return false;
break;
case ARM::VORRiv8i16:
case ARM::VORRiv4i32:
case ARM::VBICiv8i16:
case ARM::VBICiv4i32:
- DecodeQPRRegisterClass(Inst, Rd, Address, Decoder);
+ if (!DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)) return false;
break;
default:
break;
Rm |= fieldFromInstruction32(Insn, 5, 1) << 4;
unsigned size = fieldFromInstruction32(Insn, 18, 2);
- DecodeQPRRegisterClass(Inst, Rd, Address, Decoder);
- DecodeDPRRegisterClass(Inst, Rm, Address, Decoder);
+ if (!DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)) return false;
+ if (!DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)) return false;
Inst.addOperand(MCOperand::CreateImm(8 << size));
return true;
unsigned op = fieldFromInstruction32(Insn, 6, 1);
unsigned length = fieldFromInstruction32(Insn, 8, 2) + 1;
- DecodeDPRRegisterClass(Inst, Rd, Address, Decoder);
- if (op) DecodeDPRRegisterClass(Inst, Rd, Address, Decoder); // Writeback
+ if (!DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)) return false;
+ if (op) {
+ if (!DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)) return false; // Writeback
+ }
- for (unsigned i = 0; i < length; ++i)
- DecodeDPRRegisterClass(Inst, (Rn+i)%32, Address, Decoder);
+ for (unsigned i = 0; i < length; ++i) {
+ if (!DecodeDPRRegisterClass(Inst, (Rn+i)%32, Address, Decoder)) return false;
+ }
- DecodeDPRRegisterClass(Inst, Rm, Address, Decoder);
+ if (!DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)) return false;
return true;
}
unsigned dst = fieldFromInstruction16(Insn, 8, 3);
unsigned imm = fieldFromInstruction16(Insn, 0, 8);
- DecodetGPRRegisterClass(Inst, dst, Address, Decoder);
+ if (!DecodetGPRRegisterClass(Inst, dst, Address, Decoder)) return false;
if (Inst.getOpcode() == ARM::tADR)
Inst.addOperand(MCOperand::CreateReg(ARM::PC));
unsigned Rn = fieldFromInstruction32(Val, 0, 3);
unsigned Rm = fieldFromInstruction32(Val, 3, 3);
- DecodetGPRRegisterClass(Inst, Rn, Address, Decoder);
- DecodetGPRRegisterClass(Inst, Rm, Address, Decoder);
+ if (!DecodetGPRRegisterClass(Inst, Rn, Address, Decoder) ||
+ !DecodetGPRRegisterClass(Inst, Rm, Address, Decoder))
+ return false;
return true;
}
unsigned Rn = fieldFromInstruction32(Val, 0, 3);
unsigned imm = fieldFromInstruction32(Val, 3, 5);
- DecodetGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
Inst.addOperand(MCOperand::CreateImm(imm));
return true;
unsigned Rm = fieldFromInstruction32(Val, 2, 4);
unsigned imm = fieldFromInstruction32(Val, 0, 2);
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
- DecoderGPRRegisterClass(Inst, Rm, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder) ||
+ !DecoderGPRRegisterClass(Inst, Rm, Address, Decoder))
+ return false;
Inst.addOperand(MCOperand::CreateImm(imm));
return true;
uint64_t Address, const void *Decoder) {
if (Inst.getOpcode() != ARM::t2PLDs) {
unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
- DecodeGPRRegisterClass(Inst, Rt, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)) return false;
}
unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
unsigned Rn = fieldFromInstruction32(Val, 9, 4);
unsigned imm = fieldFromInstruction32(Val, 0, 9);
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
- DecodeT2Imm8S4(Inst, imm, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder) ||
+ !DecodeT2Imm8S4(Inst, imm, Address, Decoder))
+ return false;
return true;
}
break;
}
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
- DecodeT2Imm8(Inst, imm, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder) ||
+ !DecodeT2Imm8(Inst, imm, Address, Decoder))
+ return false;
return true;
}
unsigned Rn = fieldFromInstruction32(Val, 13, 4);
unsigned imm = fieldFromInstruction32(Val, 0, 12);
- DecodeGPRRegisterClass(Inst, Rn, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
Inst.addOperand(MCOperand::CreateImm(imm));
return true;
unsigned Rdm = fieldFromInstruction16(Insn, 0, 3);
Rdm |= fieldFromInstruction16(Insn, 7, 1) << 3;
- DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)) return false;
Inst.addOperand(MCOperand::CreateReg(ARM::SP));
- DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)) return false;
} else if (Inst.getOpcode() == ARM::tADDspr) {
unsigned Rm = fieldFromInstruction16(Insn, 3, 4);
Inst.addOperand(MCOperand::CreateReg(ARM::SP));
Inst.addOperand(MCOperand::CreateReg(ARM::SP));
- DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)) return false;
}
return true;
unsigned Rm = fieldFromInstruction32(Insn, 0, 4);
unsigned add = fieldFromInstruction32(Insn, 4, 1);
- DecodeGPRRegisterClass(Inst, Rm, Address, Decoder);
+ if (!DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)) return false;
Inst.addOperand(MCOperand::CreateImm(add));
return true;
brtarget |= fieldFromInstruction32(Insn, 16, 6) << 12;
brtarget |= fieldFromInstruction32(Insn, 26, 1) << 20;
- DecodeT2BROperand(Inst, brtarget, Address, Decoder);
- if (!DecodePredicateOperand(Inst, pred, Address, Decoder))
+ if (!DecodeT2BROperand(Inst, brtarget, Address, Decoder) ||
+ !DecodePredicateOperand(Inst, pred, Address, Decoder))
return false;
return true;
return true;
}
-static bool DecodeAddrMode3Offset(llvm::MCInst &Inst, unsigned Val,
- uint64_t Address, const void *Decoder) {
- bool isImm = fieldFromInstruction32(Val, 9, 1);
- bool isAdd = fieldFromInstruction32(Val, 8, 1);
- unsigned imm = fieldFromInstruction32(Val, 0, 8);
-
- if (!isImm) {
- DecodeGPRRegisterClass(Inst, imm, Address, Decoder);
- Inst.addOperand(MCOperand::CreateImm(!isAdd << 8));
- } else {
- Inst.addOperand(MCOperand::CreateReg(0));
- Inst.addOperand(MCOperand::CreateImm(imm | (!isAdd << 8)));
- }
-
- return true;
-}
-
static bool DecodeMemBarrierOption(llvm::MCInst &Inst, unsigned Val,
uint64_t Address, const void *Decoder) {
switch (Val) {
return true;
}
+static bool DecodeMSRMask(llvm::MCInst &Inst, unsigned Val,
+ uint64_t Address, const void *Decoder) {
+ if (!Val) return false;
+ Inst.addOperand(MCOperand::CreateImm(Val));
+ return true;
+}
+
+static bool DecodeDoubleRegLoad(llvm::MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder) {
+ unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
+ unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
+ unsigned pred = fieldFromInstruction32(Insn, 28, 4);
+
+ if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return false;
+
+ if (!DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)) return false;
+ if (!DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)) return false;
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
+ if (!DecodePredicateOperand(Inst, pred, Address, Decoder)) return false;
+
+ return true;
+}
+
+
+static bool DecodeDoubleRegStore(llvm::MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder) {
+ unsigned Rd = fieldFromInstruction32(Insn, 12, 4);
+ unsigned Rt = fieldFromInstruction32(Insn, 0, 4);
+ unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
+ unsigned pred = fieldFromInstruction32(Insn, 28, 4);
+
+ if (!DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)) return false;
+
+ if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return false;
+ if (Rd == Rn || Rd == Rt || Rd == Rt+1) return false;
+
+ if (!DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)) return false;
+ if (!DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)) return false;
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
+ if (!DecodePredicateOperand(Inst, pred, Address, Decoder)) return false;
+
+ return true;
+}
+
+static bool DecodeSTRPreImm(llvm::MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder) {
+ unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
+ unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
+ unsigned imm = fieldFromInstruction32(Insn, 0, 12);
+ imm |= fieldFromInstruction32(Insn, 16, 4) << 13;
+ imm |= fieldFromInstruction32(Insn, 23, 1) << 12;
+ unsigned pred = fieldFromInstruction32(Insn, 28, 4);
+
+ if (Rn == 0xF || Rn == Rt) return false; // UNPREDICTABLE
+
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
+ if (!DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)) return false;
+ if (!DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)) return false;
+ if (!DecodePredicateOperand(Inst, pred, Address, Decoder)) return false;
+
+ return true;
+}
+
+static bool DecodeSTRPreReg(llvm::MCInst &Inst, unsigned Insn,
+ uint64_t Address, const void *Decoder) {
+ unsigned Rn = fieldFromInstruction32(Insn, 16, 4);
+ unsigned Rt = fieldFromInstruction32(Insn, 12, 4);
+ unsigned imm = fieldFromInstruction32(Insn, 0, 12);
+ imm |= fieldFromInstruction32(Insn, 16, 4) << 13;
+ imm |= fieldFromInstruction32(Insn, 23, 1) << 12;
+ unsigned pred = fieldFromInstruction32(Insn, 28, 4);
+
+ if (Rn == 0xF || Rn == Rt) return false; // UNPREDICTABLE
+
+ if (!DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)) return false;
+ if (!DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)) return false;
+ if (!DecodeSORegMemOperand(Inst, imm, Address, Decoder)) return false;
+ if (!DecodePredicateOperand(Inst, pred, Address, Decoder)) return false;
+
+ return true;
+}