// 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); }
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); }