예제 #1
0
        protected ILExpression CreateLabeledExpression(GMCode code)
        {
            int          absolute = GMCodeUtil.getBranchOffset(CurrentRaw) + CurrentPC;
            ILExpression e        = new ILExpression(code, GetLabel(absolute));

            e.Extra = (int)(CurrentRaw & 0xFFFF);
            e.ILRanges.Add(new ILRange(CurrentPC, CurrentPC));
            return(e);
        }
예제 #2
0
        // This pass accepts index or instance values being
        protected override ILExpression CreateExpression(List <ILNode> list)
        {
            ILExpression e       = null;
            OldCode      nOpCode = (OldCode)(CurrentRaw >> 24);

            GM_Type[] types = ReadTypes(CurrentRaw);
            switch (nOpCode) // the bit switch
            {
            case OldCode.Conv: e = CreateExpression(GMCode.Conv, types); break;

            case OldCode.Popz: e = CreateExpression(GMCode.Popz, types); break;

            case OldCode.Mul: e = CreateExpression(GMCode.Mul, types); break;

            case OldCode.Div: e = CreateExpression(GMCode.Div, types); break;

            case OldCode.Rem: e = CreateExpression(GMCode.Rem, types); break;

            case OldCode.Mod: e = CreateExpression(GMCode.Mod, types); break;

            case OldCode.Add: e = CreateExpression(GMCode.Add, types); break;

            case OldCode.Sub: e = CreateExpression(GMCode.Sub, types); break;

            case OldCode.And: e = CreateExpression(GMCode.And, types); break;

            case OldCode.Or: e = CreateExpression(GMCode.Or, types); break;

            case OldCode.Xor: e = CreateExpression(GMCode.Xor, types); break;

            case OldCode.Neg: e = CreateExpression(GMCode.Neg, types); break;

            case OldCode.Not: e = CreateExpression(GMCode.Not, types); break;

            case OldCode.Sal: e = CreateExpression(GMCode.Sal, types); break;

            //    case GMCode.S: e = CreateExpression(GMCode.Sal, types); break;
            //    case GMCode.S: e = CreateExpression(GMCode.Sal, types); break;
            //  case GMCode.shr:     e = CreateExpression(GMCode.Saa, types); break; // hack, handle shift right
            case OldCode.Slt: e = CreateExpression(GMCode.Slt, types); break;

            case OldCode.Sle: e = CreateExpression(GMCode.Sle, types); break;

            case OldCode.Seq: e = CreateExpression(GMCode.Seq, types); break;

            case OldCode.Sne: e = CreateExpression(GMCode.Sne, types); break;

            case OldCode.Sge: e = CreateExpression(GMCode.Sge, types); break;

            case OldCode.Sgt: e = CreateExpression(GMCode.Sgt, types); break;


            case OldCode.Dup:
                e         = CreateExpression(GMCode.Dup, types);
                e.Operand = (int)(CurrentRaw & 0xFFFF);     // dup type
                break;

            case OldCode.Call:
                e         = CreateExpression(GMCode.CallUnresolved, types);
                e.Operand = ILCall.CreateCall(File.Strings[r.ReadInt32()].String, (int)(CurrentRaw & 0xFFFF));

                break;

            case OldCode.Ret: e = CreateExpression(GMCode.Ret, types); break;

            case OldCode.Exit: e = CreateExpression(GMCode.Exit, types); break;

            case OldCode.B: e = CreateLabeledExpression(GMCode.B); break;

            case OldCode.Bt: e = CreateLabeledExpression(GMCode.Bt); break;

            case OldCode.Bf: e = CreateLabeledExpression(GMCode.Bf); break;

            // We have to fix these to a lopp to emulate a while latter
            case OldCode.Pushenv:
            {
                //    Debug.WriteLine("Popenv: Address: {0}, Extra: {1} {1:X8}  Calc: {2}", CurrentPC, CurrentRaw, GMCodeUtil.getBranchOffset(CurrentRaw));
                int sextra = CurrentPC + GMCodeUtil.getBranchOffset(CurrentRaw);
                e = CreateExpression(GMCode.Pushenv, types, GetLabel(sextra + 1)); // we are one instruction after the pop
                pushEnviroment.Add(sextra, GetLabel(CurrentPC));                   // record the pop position
            }
            break;

            case OldCode.Popenv:
            {
                // We convert this to a Branch so the loop detecter will find it
                e = CreateExpression(GMCode.Popenv, types);
                // e = CreateExpression(GMCode.Popenv, types);
                if (CurrentRaw == 0xbcf00000)        // its a break, ugh, old break code ugh
                {
                    foreach (var last in list.Reverse <ILNode>().OfType <ILExpression>())
                    {
                        if (last.Code == GMCode.Pushenv)
                        {
                            e.Operand = last.Operand;
                            return(e);
                        }
                    }
                    Debug.Assert(false);
                }
                else
                {
                    // some reason its the negitive offset?
                    // int offset = GMCodeUtil.getBranchOffset(CurrentRaw) - currentPC;
                    ILLabel endOfEnviroment;
                    if (pushEnviroment.TryGetValue(CurrentPC, out endOfEnviroment)) // this is the code
                    {
                        e.Operand = endOfEnviroment;                                // not a break, set the label BACK to the push as we are simulating a loop
                    }
                    else
                    {
                        throw new Exception("This MUST be a break");
                    }
                }
            }
            break;

            case OldCode.Pop:
                e         = CreateExpression(GMCode.Pop, types);
                e.Operand = BuildUnresolvedVar(r.ReadInt32());

                break;

            case OldCode.Push:
                e = CreatePushExpression(GMCode.Push, types);
                break;

            case OldCode.Break: e = CreateExpression(GMCode.Break, types); break;

            default:
                throw new Exception("Bad opcode");
            }
            return(e);
        }
예제 #3
0
        protected override ILExpression CreateExpression(List <ILNode> list)
        {
            ILExpression e       = null;
            NewOpcode    nOpCode = (NewOpcode)(CurrentRaw >> 24);

            GM_Type[] types = ReadTypes(CurrentRaw);
            switch (nOpCode) // the bit switch
            {
            case NewOpcode.conv: e = CreateExpression(GMCode.Conv, types); break;

            case NewOpcode.popz: e = CreateExpression(GMCode.Popz, types); break;

            case NewOpcode.mul: e = CreateExpression(GMCode.Mul, types); break;

            case NewOpcode.div: e = CreateExpression(GMCode.Div, types); break;

            case NewOpcode.rem: e = CreateExpression(GMCode.Rem, types); break;

            case NewOpcode.mod: e = CreateExpression(GMCode.Mod, types); break;

            case NewOpcode.@add: e = CreateExpression(GMCode.Add, types); break;

            case NewOpcode.sub: e = CreateExpression(GMCode.Sub, types); break;

            case NewOpcode.and: e = CreateExpression(GMCode.And, types); break;

            case NewOpcode.or: e = CreateExpression(GMCode.Or, types); break;

            case NewOpcode.xor: e = CreateExpression(GMCode.Xor, types); break;

            case NewOpcode.neg: e = CreateExpression(GMCode.Neg, types); break;

            case NewOpcode.not: e = CreateExpression(GMCode.Not, types); break;

            case NewOpcode.shl: e = CreateExpression(GMCode.Sal, types); break;

            //  case NewOpcode.shr:     e = CreateExpression(GMCode.Saa, types); break; // hack, handle shift right
            case NewOpcode.@set:
                switch ((CurrentRaw >> 8) & 0xFF)
                {
                case 1: e = CreateExpression(GMCode.Slt, types); break;

                case 2: e = CreateExpression(GMCode.Sle, types); break;

                case 3: e = CreateExpression(GMCode.Seq, types); break;

                case 4: e = CreateExpression(GMCode.Sne, types); break;

                case 5: e = CreateExpression(GMCode.Sge, types); break;

                case 6: e = CreateExpression(GMCode.Sgt, types); break;

                default:
                    throw new Exception("Bad condition");
                }
                break;

            case NewOpcode.dup:
                e         = CreateExpression(GMCode.Dup, types);
                e.Operand = (int)(CurrentRaw & 0xFFFF);     // dup type
                break;

            case NewOpcode.call:
                e         = CreateExpression(GMCode.CallUnresolved, types);
                e.Operand = ILCall.CreateCall(File.Strings[r.ReadInt32()].String, (int)(CurrentRaw & 0xFFFF));
                // since we can have var args on alot of functions, extra is used
                break;

            case NewOpcode.ret: e = CreateExpression(GMCode.Ret, types); break;

            case NewOpcode.exit: e = CreateExpression(GMCode.Exit, types); break;

            case NewOpcode.b: e = CreateLabeledExpression(GMCode.B); break;

            case NewOpcode.bt: e = CreateLabeledExpression(GMCode.Bt); break;

            case NewOpcode.bf: e = CreateLabeledExpression(GMCode.Bf); break;

            // We have to fix these to a lopp to emulate a while latter
            case NewOpcode.pushenv:
            {
                //  Debug.WriteLine("Popenv: Address: {0}, Extra: {1} {1:X8}  Calc: {2}",i.Address, raw, GMCodeUtil.getBranchOffset(raw));
                int sextra = CurrentPC + GMCodeUtil.getBranchOffset(CurrentRaw);
                e = CreateExpression(GMCode.Pushenv, types, GetLabel(sextra + 1)); // we are one instruction after the pop
                pushEnviroment.Add(sextra, GetLabel(CurrentPC));                   // record the pop position
            }
            break;

            case NewOpcode.popenv:
            {
                // We convert this to a Branch so the loop detecter will find it
                e = CreateExpression(GMCode.B, types);
                // e = CreateExpression(GMCode.Popenv, types);
                if (CurrentRaw == 0xBBF00000)        // its a break, ugh
                {
                    foreach (var last in list.Reverse <ILNode>().OfType <ILExpression>())
                    {
                        if (last.Code == GMCode.Pushenv)
                        {
                            e.Operand = last.Operand;
                            return(e);
                        }
                    }
                    Debug.Assert(false);
                }
                else
                {
                    // some reason its the negitive offset?
                    // int offset = GMCodeUtil.getBranchOffset(CurrentRaw) - currentPC;
                    ILLabel endOfEnviroment;
                    if (pushEnviroment.TryGetValue(CurrentPC, out endOfEnviroment)) // this is the code
                    {
                        e.Operand = endOfEnviroment;                                // not a break, set the label BACK to the push as we are simulating a loop
                    }
                    else
                    {
                        throw new Exception("This MUST be a break");
                    }
                }
            }
            break;

            case NewOpcode.pop:
                e         = CreateExpression(GMCode.Pop, types);
                e.Operand = BuildUnresolvedVar(r.ReadInt32());
                break;

            case NewOpcode.pushi:
                Debug.Assert(types[0] == GM_Type.Short);
                e = CreatePushExpression(GMCode.Push, types);
                break;    // push int? ah like a pushe

            case NewOpcode.push:
                e = CreatePushExpression(GMCode.Push, types);
                break;            // generic push is fine right?

            case NewOpcode.pushl: // local
                e = CreatePushExpression(GMCode.Push, types);

                break;            // local? -7

            case NewOpcode.pushg: // Global
                e = CreatePushExpression(GMCode.Push, types);
                break;            // global? -5 // id is the last bit?

            case NewOpcode.pushb: // builtin .. seeing a patern hummmm
                                  // Built in vars?  always -1?
                e = CreatePushExpression(GMCode.Push, types);
                break;

            //      case NewOpcode.call2: e = CreateExpression(GMCode.Sal, types, operand); break;
            case NewOpcode.@break: e = CreateExpression(GMCode.Break, types); break;

            default:
                throw new Exception("Bad opcode");
            }
            return(e);
        }
예제 #4
0
        /// <summary>
        /// Diassembles a raw opcode.
        /// </summary>
        /// <param name="i"></param>
        /// <param name="raw"></param>
        /// <returns>Returns truee if operand is needed</returns>
        public static bool DissasembleRawCode(Instruction i, uint raw)
        {
            i.Code        = GMCodeUtil.getFromRaw(raw);
            i.Types       = null;
            i.Operand     = null;
            i.OperandText = null;                  // we clear eveything just in case
            i._extra      = (short)(0xFFFF & raw); // default for almost eveything
            switch (i.Code)
            {
            case GMCode.Call:
                i.Types = new GM_Type[] { (GM_Type)((raw >> 16) & 15) };
                return(true);

            case GMCode.Exit:
            case GMCode.Ret:
            case GMCode.Not:
            case GMCode.Neg:
            case GMCode.Popz:
                i.Types = new GM_Type[] { (GM_Type)((raw >> 16) & 15) };
                break;

            case GMCode.Pop:
                i.Types = new GM_Type[] { (GM_Type)((raw >> 16) & 15), (GM_Type)((raw >> 20) & 15) };
                return(true);

            case GMCode.Push:
                i.Types = new GM_Type[] { (GM_Type)((raw >> 16) & 15) };
                // this should be in the operand, but just in case make sure extra is right
                if (i.Types[0] == GM_Type.Short)
                {
                    i.Operand = i._extra; // convert it to int
                    break;                // set the operand ourselfs don't need it
                }
                else
                {
                    return(true);     // need to read an operand
                }

            case GMCode.Add:
            case GMCode.Sub:
            case GMCode.Mul:
            case GMCode.Div:
            case GMCode.Mod:
            case GMCode.Or:
            case GMCode.And:
            case GMCode.Dup:
            case GMCode.Sal:
            case GMCode.Seq:
            case GMCode.Sge:
            case GMCode.Sgt:
            case GMCode.Sle:
            case GMCode.Sne:
            case GMCode.Conv:
            case GMCode.Rem:
            case GMCode.Slt:
            case GMCode.Xor:
                i.Types = new GM_Type[] { (GM_Type)((raw >> 16) & 15), (GM_Type)((raw >> 20) & 15) };
                break;

            case GMCode.Break:
                //  i._extra = (int)(0x00FFFFFFF & raw); // never seen the need for more than this
                break;

            case GMCode.B:
            case GMCode.Bf:
            case GMCode.Bt:
                i._extra = i.Address + GMCodeUtil.getBranchOffset(raw);
                break;

            case GMCode.Popenv:
                //  Debug.WriteLine("Popenv: Address: {0}, Extra: {1} {1:X8}  Calc: {2}",i.Address, raw, GMCodeUtil.getBranchOffset(raw));
                if (0xBCF00000 == raw)     // its a popbreak
                {
                    i._extra = 0;
                }
                else
                {
                    i._extra = i.Address + GMCodeUtil.getBranchOffset(raw);
                }
                break;

            case GMCode.Pushenv:
                //    Debug.WriteLine("Pushenv: Address: {0}, Extra: {1} {1:X8}  Calc: {2}",i.Address, raw, GMCodeUtil.getBranchOffset(raw));
                i._extra = i.Address + GMCodeUtil.getBranchOffset(raw);
                break;

            case GMCode.BadOp:
                throw new Exception("Bad opcode?");

            default:
                throw new Exception("Unkonwn opcode");
            }
            return(false);
        }