public AArch64Instruction Decode(AArch64Disassembler dasm, uint instr, string fmt) { AA64Opcode opcode = this.opcode; List <MachineOperand> ops = new List <MachineOperand>(); MachineOperand op = null; int i = 0; int off; while (i < fmt.Length) { switch (fmt[i++]) { default: throw new InvalidOperationException(string.Format("Bad format character {0}.", fmt[i - 1])); case ',': continue; case 'B': // Logical Bitmask op = LogicalBitmask(dasm, instr, fmt[i++] == 'x'); break; case 'H': // 16-bit Immediate constant off = GetOffset(fmt, ref i); op = ArmImmediateOperand.Word32(GetImm(instr, off, 16)); break; case 'I': // 12-bit Immediate constant off = GetOffset(fmt, ref i); op = ArmImmediateOperand.Word32(GetImm(instr, off, 12)); break; case 'J': // long relative branch int offset = (((int)instr) << 6) >> 4; op = new AddressOperand(dasm.rdr.Address + offset); break; case 'W': // (32-bit) W register operand op = GetWReg(instr, GetOffset(fmt, ref i)); break; case 'X': // (64-bit) X register operand op = GetXReg(instr, GetOffset(fmt, ref i)); break; case 's': // Shift operand by 12 off = GetOffset(fmt, ref i); op = ops[ops.Count - 1]; ops.RemoveAt(ops.Count - 1); uint shiftCode = GetImm(instr, off, 2); switch (shiftCode) { case 0: break; case 1: op = new ShiftOperand(op, Opcode.lsl, 12); break; default: throw new FormatException("Reserved value for shift code."); } break; } ops.Add(op); } return(AArch64Instruction.Create(opcode, ops)); }
public ShiftOperand(MachineOperand op, Opcode opcode, int shAmt) : this(op, opcode, ArmImmediateOperand.Byte((byte)shAmt)) { }