Example #1
0
            public override AArch64Instruction Decode(uint wInstr, AArch64Disassembler dasm)
            {
                TraceDecoder(wInstr);
                uint op = (wInstr >> shift) & mask;

                return(decoders[op].Decode(wInstr, dasm));
            }
Example #2
0
            public override AArch64Instruction Decode(uint wInstr, AArch64Disassembler dasm)
            {
                TraceDecoder(wInstr);
                uint op = Bitfield.ReadFields(bitfields, wInstr);

                return(decoders[op].Decode(wInstr, dasm));
            }
Example #3
0
            public override AArch64Instruction Decode(uint wInstr, AArch64Disassembler dasm)
            {
                base.DumpMaskedInstruction("", wInstr, this.bitfields);
                uint n       = Bitfield.ReadFields(bitfields, wInstr);
                var  decoder = predicate(n) ? trueDecoder : falseDecoder;

                return(decoder.Decode(wInstr, dasm));
            }
            public override AArch64Instruction Decode(uint wInstr, AArch64Disassembler dasm)
            {
                DumpMaskedInstruction(wInstr, mask << shift, tag);
                var op = (wInstr >> shift) & mask;

                if (!decoders.TryGetValue(op, out Decoder decoder))
                {
                    decoder = @default;
                }
                return(decoder.Decode(wInstr, dasm));
            }
Example #5
0
 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);
 }
Example #6
0
            public override AArch64Instruction Decode(uint wInstr, AArch64Disassembler dasm)
            {
                dasm.state.opcode     = this.opcode;
                dasm.state.vectorData = this.vectorData;
                for (int i = 0; i < mutators.Length; ++i)
                {
                    if (!mutators[i](wInstr, dasm))
                    {
                        dasm.state.Invalid();
                        break;
                    }
                }
                var instr = dasm.state.MakeInstruction();

                return(instr);
            }
Example #7
0
        public void AArch64Dis_DecodeReal64Immediate_31()
        {
            var c = AArch64Disassembler.DecodeReal64FpConstant(0x3F);

            Assert.AreEqual("31.0", c.ToString());
        }
Example #8
0
        public void AArch64Dis_DecodeReal64Immediate_minus1_9375()
        {
            var c = AArch64Disassembler.DecodeReal64FpConstant(0xFF);

            Assert.AreEqual("-1.9375", c.ToString());
        }
Example #9
0
        public void AArch64Dis_DecodeReal32Immediate_1()
        {
            var c = AArch64Disassembler.DecodeReal32FpConstant(0x70);

            Assert.AreEqual("1.0F", c.ToString());
        }
Example #10
0
 public override AArch64Instruction Decode(AArch64Disassembler dasm, uint instr)
 {
     return Decode(dasm, instr, format);
 }
Example #11
0
 public abstract AArch64Instruction Decode(AArch64Disassembler dasm, uint opcode) ;
Example #12
0
 public override AArch64Instruction Decode(AArch64Disassembler dasm, uint instr)
 {
     return ((instr & (1 << 23)) != 0 ? mov : logical).Decode(dasm, instr);
 }
Example #13
0
    // https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=opcodes/aarch64-dis.c;h=c11f78f78ab8569db6ebf5295d8047aeeee338bd;hb=master
    // line 694

        /* Decode logical immediate for e.g. ORR <Wd|WSP>, <Wn>, #<imm>.  */

        ArmImmediateOperand LogicalBitmask(AArch64Disassembler dasm, uint value, bool is64)
        {
            ulong imm, mask;
            uint N, R, S;
            uint simd_size;

            // value = extract_fields (code, 0, 3, FLD_N, FLD_immr, FLD_imms);
            //sf = aarch64_get_qualifier_esize (inst->operands[0].qualifier) != 4;

            /* value is N:immr:imms.  */
            S = (value >> 10) & 0x3Fu;
            R = (value >> 16) & 0x3F;
            N = (value >> 22) & 0x1;

            if (!is64 && N == 1)
                throw new InvalidOperationException();

            /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R
               (in other words, right rotated by R), then replicated.  */
            if (N != 0)
            {
                simd_size = 64;
                mask = 0xFFFFFFFFFFFFFFFFul;
            }
            else
            {
                switch (S)
                {
                case 0x00:
                case 0x01:
                case 0x02:
                case 0x03:
                case 0x04:
                case 0x05:
                case 0x06:
                case 0x07:
                case 0x08:
                case 0x09:
                case 0x0A:
                case 0x0B:
                case 0x0C:
                case 0x0D:
                case 0x0E:
                case 0x0F:
                case 0x10:
                case 0x11:
                case 0x12:
                case 0x13:
                case 0x14:
                case 0x15:
                case 0x16:
                case 0x17:
                case 0x18:
                case 0x19:
                case 0x1A:
                case 0x1B:
                case 0x1C:
                case 0x1D:
                case 0x1E:
                case 0x1F:
                    /* 0xxxxx */
                    simd_size = 32;
                    break;
                case 0x20:
                case 0x21:
                case 0x22:
                case 0x23:
                case 0x24:
                case 0x25:
                case 0x26:
                case 0x27:
                case 0x28:
                case 0x29:
                case 0x2A:
                case 0x2B:
                case 0x2C:
                case 0x2D:
                case 0x2E:
                case 0x2F:
                    /* 10xxxx */
                    simd_size = 16; S &= 0xf; break;
                case 0x30:
                case 0x31:
                case 0x32:
                case 0x33:
                case 0x34:
                case 0x35:
                case 0x36:
                case 0x37:
                    /* 110xxx */
                    simd_size = 8; S &= 0x7; break;
                case 0x38:
                case 0x39:
                case 0x3A:
                case 0x3B:
                    /* 1110xx */
                    simd_size = 4; S &= 0x3; break;
                case 0x3C:
                case 0x3D:
                case 0x3E:
                case 0x3F:
                    /* 11110x */
                    simd_size = 2; S &= 0x1; break;
                default: throw new InvalidOperationException();
                }
                mask = ((1ul << (int) simd_size) - 1);
                /* Top bits are IGNORED.  */
                R &= simd_size - 1;
            }
            /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected.  */
            if (S == simd_size - 1)
                throw new InvalidOperationException();
            /* S+1 consecutive bits to 1.  */
            /* NOTE: S can't be 63 due to detection above.  */
            imm = (1ul << (int) (S + 1)) - 1;
            /* Rotate to the left by simd_size - R.  */
            if (R != 0)
                imm = ((imm << (int) (simd_size - R)) & mask) | (imm >> (int) R);
            /* Replicate the value according to SIMD size.  */
            switch (simd_size)
            {
            case 2: imm = (imm << 2) | imm; goto case 4;
            case 4: imm = (imm << 4) | imm; goto case 8;
            case 8: imm = (imm << 8) | imm; goto case 16;
            case 16: imm = (imm << 16) | imm; goto case 32;
            case 32: imm = (imm << 32) | imm; break;
            case 64: break;
            default: throw new InvalidOperationException();
            }

            return is64
                ? dasm.Word64(imm)
                : dasm.Word32((int) imm);
        }
Example #14
0
 public abstract AArch64Instruction Decode(uint wInstr, AArch64Disassembler dasm);
Example #15
0
 public override AArch64Instruction Decode(uint wInstr, AArch64Disassembler dasm)
 {
     return(dasm.NotYetImplemented(message, wInstr));
 }