// Section A8.8.64, page A8-410 (LDR encoding A1) private (uint reg_t, ushort imm)? getLdrLit(uint inst) { if (inst.Bits(16, 16) != 0b_1110_0101_1001_1111) { return(null); } var reg_t = inst.Bits(12, 4); var imm12 = inst.Bits(0, 12); return(reg_t, (ushort)imm12); }
// Section A8.8.66, page A8-414 (LDR encoding A1) // Specifically LDR Rx, [Ry, Rz] private (uint reg_t, uint reg_n, uint reg_m)? getLdrReg(uint inst) { if (inst.Bits(20, 12) != 0b_1110_0111_1001) { return(null); } var reg_n = inst.Bits(16, 4); var reg_t = inst.Bits(12, 4); var reg_m = inst.Bits(0, 4); return(reg_t, reg_n, reg_m); }
private (uint reg_t, uint reg_n, uint simm)? getLdr64ImmOffset(uint inst) { if (inst.Bits(22, 10) != 0b_11_1110_0101) { return(null); } var imm = inst.Bits(10, 12); var reg_t = inst.Bits(0, 5); var reg_n = inst.Bits(5, 5); return(reg_t, reg_n, imm); }
// ARMv7-A Architecture Reference Manual: https://static.docs.arm.com/ddi0406/c/DDI0406C_C_arm_architecture_reference_manual.pdf // Section A8.8.7, page A8-312 (ADD encoding A1) private (uint reg_d, uint reg_n, uint reg_m)? getAddReg(uint inst) { if (inst.Bits(21, 11) != 0b_1110_0000_100) { return(null); } var reg_d = inst.Bits(12, 4); var reg_n = inst.Bits(16, 4); var reg_m = inst.Bits(0, 4); return(reg_d, reg_n, reg_m); }
private (uint reg_n, uint reg_d, uint imm)? getAdd64(uint inst) { if (inst.Bits(22, 10) != 0b_1001_0001_00) { return(null); } var imm = inst.Bits(10, 12); var reg_n = inst.Bits(5, 5); var reg_d = inst.Bits(0, 5); return(reg_n, reg_d, imm); }
private (uint reg, ulong page)? getAdrp(uint inst, ulong pc) { if ((inst.Bits(24, 8) & 0b_1000_1111) != 1 << 7) { return(null); } var addendLo = inst.Bits(29, 2); var addendHi = inst.Bits(5, 19); var addend = (addendHi << 14) + (addendLo << 12); var page = pc & ~((1Lu << 12) - 1); var reg = inst.Bits(0, 5); return(reg, page + addend); }
// Thumb 2 Supplement Reference Manual: http://class.ece.iastate.edu/cpre288/resources/docs/Thumb-2SupplementReferenceManual.pdf // Section 3.1 private uint getNextThumbInstruction(IFileFormatReader image) { // Assume 16-bit uint inst = image.ReadUInt16(); // Is 32-bit? if (inst.Bits(13, 15) == 0b111) { if (inst.Bits(11, 2) != 0b00) { inst = (inst << 16) + image.ReadUInt16(); } } return(inst); }
// https://static.docs.arm.com/100878/0100/fundamentals_of_armv8_a_100878_0100_en.pdf states: // Unlike ARMv7-A, there is no implied offset of 4 or 8 bytes private (uint reg, ulong addr)? getAdr(uint inst, ulong pc) { if (inst.Bits(24, 5) != 0b10000 || inst.Bits(31, 1) != 0) { return(null); } ulong imm = (inst.Bits(5, 19) << 2) + inst.Bits(29, 2); // Sign extend the 21-bit number to 64 bits imm = (imm & (1 << 20)) == 0 ? imm : imm | unchecked ((ulong)-(1 << 21)); var reg = inst.Bits(0, 5); return(reg, pc + imm); }
// Section A8.8.18, page A8-334 (B encoding A1) private bool isB(uint inst) => inst.Bits(24, 8) == 0b_1110_1010;
public void BitEnumerateUInt32Test(uint num, int[] expected) { num.Bits().Should().Equal(expected); }
private bool isB(uint inst) => inst.Bits(26, 6) == 0b_000101;
public static uint NormalisedBits(this uint value, int firstIndex, int lastIndex) { var lsb = Math.Min(firstIndex, lastIndex); return(value.Bits(firstIndex, lastIndex) >> lsb); }