Beispiel #1
0
        public static ICondition Emit(byte[] instruction, CompilationContext context)
        {
            // 1TMC00AA AAAAAAAA VVVVVVVV (VVVVVVVV)
            // T: Width of memory write (1, 2, 4, or 8 bytes).
            // M: Memory region to write to (0 = Main NSO, 1 = Heap).
            // C: Condition to use, see below.
            // A: Immediate offset to use from memory region base.
            // V: Value to compare to.

            byte         operationWidth = instruction[OperationWidthIndex];
            MemoryRegion memoryRegion   = (MemoryRegion)instruction[MemoryRegionIndex];
            Comparison   comparison     = (Comparison)instruction[ComparisonTypeIndex];

            ulong   address      = InstructionHelper.GetImmediate(instruction, OffsetImmediateIndex, OffsetImmediateSize);
            Pointer sourceMemory = MemoryHelper.EmitPointer(memoryRegion, address, context);

            int           valueSize      = operationWidth <= 4 ? ValueImmediateSize4 : ValueImmediateSize8;
            ulong         value          = InstructionHelper.GetImmediate(instruction, ValueImmediateIndex, valueSize);
            Value <ulong> compareToValue = new Value <ulong>(value);

            return(InstructionHelper.CreateCondition(comparison, operationWidth, sourceMemory, compareToValue));
        }
        public static ICondition Emit(byte[] instruction, CompilationContext context)
        {
            // C0TcSX##
            // C0TcS0Ma aaaaaaaa
            // C0TcS1Mr
            // C0TcS2Ra aaaaaaaa
            // C0TcS3Rr
            // C0TcS400 VVVVVVVV (VVVVVVVV)
            // C0TcS5X0
            // T: Width of memory write(1, 2, 4, or 8 bytes).
            // c: Condition to use, see below.
            // S: Source Register.
            // X: Operand Type, see below.
            // M: Memory Type(operand types 0 and 1).
            // R: Address Register(operand types 2 and 3).
            // a: Relative Address(operand types 0 and 2).
            // r: Offset Register(operand types 1 and 3).
            // X: Other Register(operand type 5).
            // V: Value to compare to(operand type 4).

            byte       operationWidth         = instruction[OperationWidthIndex];
            Comparison comparison             = (Comparison)instruction[ComparisonTypeIndex];
            Register   sourceRegister         = context.GetRegister(instruction[SourceRegisterIndex]);
            byte       operandType            = instruction[OperandTypeIndex];
            byte       registerOrMemoryRegion = instruction[RegisterOrMemoryRegionIndex];
            byte       offsetRegisterIndex    = instruction[OffsetImmediateIndex];
            ulong      offsetImmediate;
            ulong      valueImmediate;
            int        valueImmediateSize;
            Register   addressRegister;
            Register   offsetRegister;
            IOperand   sourceOperand;

            switch (operandType)
            {
            case MemoryRegionWithOffsetImmediate:
                // *(?x + #a)
                offsetImmediate = InstructionHelper.GetImmediate(instruction, OffsetImmediateIndex, OffsetImmediateSize);
                sourceOperand   = MemoryHelper.EmitPointer((MemoryRegion)registerOrMemoryRegion, offsetImmediate, context);
                break;

            case MemoryRegionWithOffsetRegister:
                // *(?x + $r)
                offsetRegister = context.GetRegister(offsetRegisterIndex);
                sourceOperand  = MemoryHelper.EmitPointer((MemoryRegion)registerOrMemoryRegion, offsetRegister, context);
                break;

            case AddressRegisterWithOffsetImmediate:
                // *($R + #a)
                addressRegister = context.GetRegister(registerOrMemoryRegion);
                offsetImmediate = InstructionHelper.GetImmediate(instruction, OffsetImmediateIndex, OffsetImmediateSize);
                sourceOperand   = MemoryHelper.EmitPointer(addressRegister, offsetImmediate, context);
                break;

            case AddressRegisterWithOffsetRegister:
                // *($R + $r)
                addressRegister = context.GetRegister(registerOrMemoryRegion);
                offsetRegister  = context.GetRegister(offsetRegisterIndex);
                sourceOperand   = MemoryHelper.EmitPointer(addressRegister, offsetRegister, context);
                break;

            case OffsetImmediate:
                valueImmediateSize = operationWidth <= 4 ? ValueImmediateSize8 : ValueImmediateSize16;
                valueImmediate     = InstructionHelper.GetImmediate(instruction, ValueImmediateIndex, valueImmediateSize);
                sourceOperand      = new Value <ulong>(valueImmediate);
                break;

            case AddressRegister:
                // $V
                sourceOperand = context.GetRegister(registerOrMemoryRegion);
                break;

            default:
                throw new TamperCompilationException($"Invalid operand type {operandType} in Atmosphere cheat");
            }

            return(InstructionHelper.CreateCondition(comparison, operationWidth, sourceRegister, sourceOperand));
        }