Exemplo n.º 1
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);
        }
Exemplo n.º 2
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);
        }