コード例 #1
0
        public virtual void make(CpuState cpu)
        {
            pc = cpu.pc;
            for (int i = 0; i < NUMBER_REGISTERS; i++)
            {
                gpr[i] = cpu.getRegister(i);
            }
            threadID   = Modules.ThreadManForUserModule.CurrentThreadID;
            threadName = Modules.ThreadManForUserModule.getThreadName(threadID);

            Memory mem = MemoryViewer.Memory;

            if (MemoryViewer.isAddressGood(cpu.pc))
            {
                opcode = mem.read32(cpu.pc);
                Common.Instruction insn = Decoder.instruction(opcode);
                asm = insn.disasm(cpu.pc, opcode);
            }
            else
            {
                opcode = 0;
                asm    = "?";
            }

            dirty = true;
        }
コード例 #2
0
        public static bool isEndBlockInsn(int pc, int opcode, Common.Instruction insn)
        {
            if (insn.hasFlags(Common.Instruction.FLAG_ENDS_BLOCK))
            {
                if (insn.hasFlags(Common.Instruction.FLAG_IS_CONDITIONAL | Common.Instruction.FLAG_IS_BRANCHING))
                {
                    // Detect the conditional
                    //    "BEQ $xx, $xx, target"
                    // which is equivalent to the unconditional
                    //    "B target"
                    if (insn == Instructions.BEQ)
                    {
                        int rt = (opcode >> 16) & 0x1F;
                        int rs = (opcode >> 21) & 0x1F;
                        if (rs == rt)
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        Console.WriteLine(string.Format("Unknown conditional instruction ending a block: {0}", insn.disasm(pc, opcode)));
                    }
                }
                else
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #3
0
        private void loadBeforeCodeInstructions(NativeCodeSequence nativeCodeSequence, string codeInstructions)
        {
            System.IO.StreamReader reader = new System.IO.StreamReader(new StringReader(codeInstructions));
            if (reader == null)
            {
                return;
            }

            Pattern   codeInstructionPattern = Pattern.compile("\\s*(\\w+\\s*:?\\s*)?\\[(\\p{XDigit}+)\\].*");
            const int opcodeGroup            = 2;
            const int address = 0;

            try
            {
                while (true)
                {
                    string line = reader.ReadLine();
                    if (string.ReferenceEquals(line, null))
                    {
                        break;
                    }

                    line = line.Trim();
                    if (line.Length > 0)
                    {
                        try
                        {
                            Matcher codeInstructionMatcher = codeInstructionPattern.matcher(line);
                            int     opcode = 0;
                            if (codeInstructionMatcher.matches())
                            {
                                opcode = Utilities.parseAddress(codeInstructionMatcher.group(opcodeGroup));
                            }
                            else
                            {
                                opcode = Utilities.parseAddress(line.Trim());
                            }

                            Common.Instruction insn            = Decoder.instruction(opcode);
                            CodeInstruction    codeInstruction = new CodeInstruction(address, opcode, insn, false, false, 0);

                            nativeCodeSequence.addBeforeCodeInstruction(codeInstruction);
                        }
                        catch (System.FormatException e)
                        {
                            Compiler.Console.WriteLine(e);
                        }
                    }
                }
            }
            catch (IOException e)
            {
                Compiler.Console.WriteLine(e);
            }
        }
コード例 #4
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: private IExecutable analyse(CompilerContext context, int startAddress, bool recursive, int instanceIndex) throws ClassFormatError
        private IExecutable analyse(CompilerContext context, int startAddress, bool recursive, int instanceIndex)
        {
            if (log.TraceEnabled)
            {
                log.trace(string.Format("Compiler.analyse Block 0x{0:X8}", startAddress));
            }
            int            maxBranchInstructions = int.MaxValue;  // 5 for FRONTIER_1337 homebrew
            MemorySections memorySections        = MemorySections.Instance;
            CodeBlock      codeBlock             = new CodeBlock(startAddress, instanceIndex);
            Stack <int>    pendingBlockAddresses = new Stack <int>();

            pendingBlockAddresses.Clear();
            pendingBlockAddresses.Push(startAddress);
            ISet <int> branchingToAddresses = new HashSet <int>();

            while (pendingBlockAddresses.Count > 0)
            {
                int pc = pendingBlockAddresses.Pop();
                if (!isAddressGood(pc))
                {
                    if (IgnoreInvalidMemory)
                    {
                        Console.WriteLine(string.Format("IGNORING: Trying to compile an invalid address 0x{0:X8} while compiling from 0x{1:X8}", pc, startAddress));
                    }
                    else
                    {
                        Console.WriteLine(string.Format("Trying to compile an invalid address 0x{0:X8} while compiling from 0x{1:X8}", pc, startAddress));
                    }
                    return(null);
                }
                bool isBranchTarget = true;
                int  endPc          = MemoryMap.END_RAM;

                // Handle branching to a delayed instruction.
                // The delayed instruction has already been analysed, but the next
                // address maybe not.
                if (context.analysedAddresses.Contains(pc) && !context.analysedAddresses.Contains(pc + 4))
                {
                    pc += 4;
                }

                if (context.analysedAddresses.Contains(pc) && isBranchTarget)
                {
                    codeBlock.IsBranchTarget = pc;
                }
                else
                {
                    IMemoryReader memoryReader = MemoryReader.getMemoryReader(pc, 4);
                    while (!context.analysedAddresses.Contains(pc) && pc <= endPc)
                    {
                        int opcode = memoryReader.readNext();

                        Common.Instruction insn = Decoder.instruction(opcode);

                        context.analysedAddresses.Add(pc);
                        int npc = pc + 4;

                        int  branchingTo           = 0;
                        bool isBranching           = false;
                        bool checkDynamicBranching = false;
                        if (insn.hasFlags(Common.Instruction.FLAG_IS_BRANCHING))
                        {
                            branchingTo = branchTarget(npc, opcode);
                            isBranching = true;
                        }
                        else if (insn.hasFlags(Common.Instruction.FLAG_IS_JUMPING))
                        {
                            branchingTo           = jumpTarget(npc, opcode);
                            isBranching           = true;
                            checkDynamicBranching = true;
                        }

                        if (isEndBlockInsn(pc, opcode, insn))
                        {
                            endPc = npc;
                        }
                        else if (pc < endPc && insn.hasFlags(Common.Instruction.FLAG_SYSCALL))
                        {
                            endPc = pc;
                        }

                        if (insn.hasFlags(Common.Instruction.FLAG_STARTS_NEW_BLOCK))
                        {
                            if (recursive)
                            {
                                context.blocksToBeAnalysed.Push(branchingTo);
                            }
                        }
                        else if (isBranching)
                        {
                            if (branchingTo != 0)
                            {                             // Ignore "J 0x00000000" instruction
                                bool analyseBranch = true;
                                if (maxBranchInstructions < 0)
                                {
                                    analyseBranch = false;
                                }
                                else
                                {
                                    maxBranchInstructions--;

                                    // Analyse only the jump instructions that are jumping to
                                    // non-writable memory sections. A jump to a writable memory
                                    // section has to be interpreted at runtime to check if the
                                    // reached code has not been changed (i.e. invalidated).
                                    if (checkDynamicBranching && memorySections.canWrite(branchingTo, false))
                                    {
                                        analyseBranch = false;
                                    }
                                }

                                if (analyseBranch)
                                {
                                    pendingBlockAddresses.Push(branchingTo);
                                }
                                else
                                {
                                    branchingToAddresses.Add(branchingTo);
                                }
                            }
                        }

                        bool useMMIO = useMMIOAddresses.Contains(pc & Memory.addressMask);

                        codeBlock.addInstruction(pc, opcode, insn, isBranchTarget, isBranching, branchingTo, useMMIO);
                        pc = npc;

                        isBranchTarget = false;
                    }
                }

                foreach (int branchingTo in branchingToAddresses)
                {
                    codeBlock.IsBranchTarget = branchingTo;
                }
            }

            codeBlock.addCodeBlock();

            IExecutable executable;

            if (RuntimeContext.CompilerEnabled || codeBlock.hasFlags(FLAG_SYSCALL))
            {
                executable = codeBlock.getExecutable(context);
            }
            else
            {
                executable = null;
            }
            if (log.TraceEnabled)
            {
                log.trace("Executable: " + executable);
            }

            return(executable);
        }
コード例 #5
0
        public virtual bool checkSimpleInterpretedCodeBlock(CodeBlock codeBlock)
        {
            bool isSimple  = true;
            int  insnCount = 0;

            Common.Instruction[] insns = new Common.Instruction[100];
            int[] opcodes    = new int[100];
            int   opcodeJrRa = AllegrexOpcodes.JR | (Common._ra << 21);           // jr $ra

            IMemoryReader memoryReader   = MemoryReader.getMemoryReader(codeBlock.StartAddress, 4);
            int           notSimpleFlags = FLAG_IS_BRANCHING | FLAG_IS_JUMPING | FLAG_STARTS_NEW_BLOCK | FLAG_ENDS_BLOCK;

            while (true)
            {
                if (insnCount >= insns.Length)
                {
                    // Extend insns array
                    Common.Instruction[] newInsns = new Common.Instruction[insnCount + 100];
                    Array.Copy(insns, 0, newInsns, 0, insnCount);
                    insns = newInsns;
                    // Extend opcodes array
                    int[] newOpcodes = new int[newInsns.Length];
                    Array.Copy(opcodes, 0, newOpcodes, 0, insnCount);
                    opcodes = newOpcodes;
                }

                int opcode = memoryReader.readNext();

                if (opcode == opcodeJrRa)
                {
                    int delaySlotOpcode = memoryReader.readNext();
                    Common.Instruction delaySlotInsn = Decoder.instruction(delaySlotOpcode);
                    insns[insnCount]   = delaySlotInsn;
                    opcodes[insnCount] = delaySlotOpcode;
                    insnCount++;
                    break;
                }

                Common.Instruction insn = Decoder.instruction(opcode);
                if ((insn.Flags & notSimpleFlags) != 0)
                {
                    isSimple = false;
                    break;
                }

                insns[insnCount]   = insn;
                opcodes[insnCount] = opcode;
                insnCount++;
            }

            if (isSimple)
            {
                if (insnCount < insns.Length)
                {
                    // Compact insns array
                    Common.Instruction[] newInsns = new Common.Instruction[insnCount];
                    Array.Copy(insns, 0, newInsns, 0, insnCount);
                    insns = newInsns;
                    // Compact opcodes array
                    int[] newOpcodes = new int[insnCount];
                    Array.Copy(opcodes, 0, newOpcodes, 0, insnCount);
                    opcodes = newOpcodes;
                }
                codeBlock.InterpretedInstructions = insns;
                codeBlock.InterpretedOpcodes      = opcodes;
            }
            else
            {
                codeBlock.InterpretedInstructions = null;
                codeBlock.InterpretedOpcodes      = null;
            }

            return(isSimple);
        }