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