public static void AddCodes(NodeBase caller, BlockBase parent, NodeBase target, OpModule codes, string op, Addr32 dest) { if (target is TypeOf) target = (target as TypeOf).Target; var v = target as Variant; if (v != null && parent.GetFunction(v.Name) == null) { var fpname = (target as Variant).Name; var fpt = Types.GetType(parent, fpname); if (fpt == null || !fpt.Check()) throw caller.Abort("undefined type: {0}", fpname); codes.AddCodesV(op, dest, codes.GetTypeObject(fpt)); return; } var tt = target.Type; var tr = tt as TypeReference; var tts = tt.Type as TypeStruct; if (tr != null && (tr.IsArray || (tts != null && tts.IsClass))) { target.AddCodesV(codes, "mov", null); var label = new OpCode(); codes.Add(I386.Test(Reg32.EAX, Reg32.EAX)); codes.Add(I386.Jcc(Cc.Z, label.Address)); codes.Add(I386.MovRA(Reg32.EAX, Addr32.NewRO(Reg32.EAX, -16))); codes.Add(label); codes.AddCodes(op, dest); } else codes.AddCodesV(op, dest, codes.GetTypeObject(tt)); }
public override void AddCodesV(OpModule codes, string op, Addr32 dest) { Val32 v; var m = codes.Module; if (func != null) v = func.GetAddress(m); else { var vv = GetVar(); if (vv != null) { vv.AddCodesV(codes, op, dest); return; } var c = GetConst(); if (c != null) { c.AddCodesV(codes, op, dest); return; } var f = GetFunction(); if (f == null) { var g = GetGetter(); if (g != null) { Call.NewName(Parent, g.Name).AddCodesV(codes, op, dest); return; } throw Abort("undefined symbol: " + name); } v = f.GetAddress(m); } codes.AddCodesV(op, dest, v); }
public static OpCode FromName1A(string op, Addr32 op1) { switch (op) { case "push": return OpCode.NewA(Util.GetBytes1(0xff), Addr32.NewAdM(op1, 6)); case "pop": return OpCode.NewA(Util.GetBytes1(0x8f), op1); case "inc": return OpCode.NewA(Util.GetBytes1(0xff), op1); case "dec": return OpCode.NewA(Util.GetBytes1(0xff), Addr32.NewAdM(op1, 1)); case "not": return OpCode.NewA(Util.GetBytes1(0xf7), Addr32.NewAdM(op1, 2)); case "neg": return OpCode.NewA(Util.GetBytes1(0xf7), Addr32.NewAdM(op1, 3)); case "mul": return OpCode.NewA(Util.GetBytes1(0xf7), Addr32.NewAdM(op1, 4)); case "imul": return OpCode.NewA(Util.GetBytes1(0xf7), Addr32.NewAdM(op1, 5)); case "div": return OpCode.NewA(Util.GetBytes1(0xf7), Addr32.NewAdM(op1, 6)); case "idiv": return OpCode.NewA(Util.GetBytes1(0xf7), Addr32.NewAdM(op1, 7)); default: throw new Exception("invalid operator: " + op); } }
public override void AddOpCodes(string op, OpModule codes, Addr32 dest) { switch (op) { case "shift-left": Shift("sal", codes, dest); break; case "shift-right": Shift("sar", codes, dest); break; case "mul": codes.Add(I386.ImulA(dest)); codes.Add(I386.MovAR(dest, Reg32.EAX)); break; case "div": codes.Add(I386.XchgRA(Reg32.EAX, dest)); codes.Add(I386.Cdq()); codes.Add(I386.IdivA(dest)); codes.Add(I386.MovAR(dest, Reg32.EAX)); break; case "mod": codes.Add(I386.XchgRA(Reg32.EAX, dest)); codes.Add(I386.Cdq()); codes.Add(I386.IdivA(dest)); codes.Add(I386.MovAR(dest, Reg32.EDX)); break; default: base.AddOpCodes(op, codes, dest); break; } }
public override void AddOpCodes(string op, OpModule codes, Addr32 dest) { switch (op) { case "inc": case "post-inc": if (Type.Size == 1) codes.Add(I386.IncA(dest)); else codes.Add(I386.AddA(dest, Val32.NewI(Type.Size))); break; case "dec": case "post-dec": if (Type.Size == 1) codes.Add(I386.DecA(dest)); else codes.Add(I386.SubA(dest, Val32.NewI(Type.Size))); break; case "add": codes.Add(I386.MovR(Reg32.EDX, Val32.NewI(Type.Size))); codes.Add(I386.Mul(Reg32.EDX)); codes.Add(I386.AddAR(dest, Reg32.EAX)); break; case "sub": codes.Add(I386.MovR(Reg32.EDX, Val32.NewI(Type.Size))); codes.Add(I386.Mul(Reg32.EDX)); codes.Add(I386.SubAR(dest, Reg32.EAX)); break; default: base.AddOpCodes(op, codes, dest); break; } }
public void AddConstructorA(OpModule codes, Addr32 ad) { if (ad != null) codes.Add(I386.Lea(Reg32.EAX, ad)); codes.Add(I386.Push(Reg32.EAX)); AddConstructor(codes); codes.Add(I386.AddR(Reg32.ESP, Val32.New(4))); }
protected bool AddConstCodes(OpModule codes, string op, Addr32 dest) { var v = GetConst(); if (v == null) return false; v.AddCodesV(codes, op, dest); return true; }
public override void AddCodesV(OpModule codes, string op, Addr32 dest) { var t = Var.Get(Target); if (t == null) throw Abort("addrof: variable required"); var ad = t.GetAddress(codes); codes.Add(I386.Lea(Reg32.EAX, ad)); codes.AddCodes(op, dest); }
public override void AddCodesV(OpModule codes, string op, Addr32 dest) { var f = Parent.GetFunction(Tag); if (f == null) throw Abort("is: can not find: {0}", Tag); TypeOf.AddCodes(this, Parent, values[1] as NodeBase, codes, "push", null); TypeOf.AddCodes(this, Parent, values[0] as NodeBase, codes, "push", null); codes.Add(I386.CallD(f.First)); codes.Add(I386.AddR(Reg32.ESP, Val32.New(8))); codes.AddCodes(op, dest); }
public override void AddCodesV(OpModule codes, string op, Addr32 dest) { var t = Type; var st = Source.Type; if (st is TypeIntBase && t.Size < st.Size) { Source.AddCodesV(codes, "mov", null); t.AddGetCodes(codes, op, dest, null); } else Source.AddCodesV(codes, op, dest); }
// set value public override void AddSetCodes(OpModule codes, Addr32 ad) { var flag = !ad.IsAddress && ad.Register == Var.DestRegister; if (flag) codes.Add(I386.Push(ad.Register)); codes.Add(I386.Push(Reg32.EAX)); codes.Add(I386.PushA(ad)); codes.Add(codes.GetCall("delegate", DelgFunc.Free)); codes.Add(I386.AddR(Reg32.ESP, Val32.New(4))); codes.Add(codes.GetCall("delegate", DelgFunc.Duplicate)); codes.Add(I386.AddR(Reg32.ESP, Val32.New(4))); if (flag) codes.Add(I386.Pop(ad.Register)); base.AddSetCodes(codes, ad); }
public override void AddCodesV(OpModule codes, string op, Addr32 dest) { if (AddConstCodes(codes, op, dest)) return; var v = values[0] as NodeBase; if (!OpModule.NeedsDtor(v)) v.AddCodesV(codes, op, dest); else { v.AddCodesV(codes, "mov", null); codes.Add(I386.Push(Reg32.EAX)); codes.AddCodes(op, dest); codes.AddDtorCodes(v.Type); } }
public static OpCode FromNameWA(string op, Reg32 op1, Addr32 op2) { byte b; switch (op) { case "movzx": b = 0xb7; break; case "movsx": b = 0xbf; break; default: throw new Exception("invalid operator: " + op); } return OpCode.NewA(Util.GetBytes2(0x0f, b), Addr32.NewAdM(op2, (byte)op1)); }
public void AddCodesA(string op, Addr32 dest, Addr32 ad) { switch (op) { case "push": if (ad != null) Add(I386.PushA(ad)); else Add(I386.Push(Reg32.EAX)); break; default: if (ad != null) Add(I386.MovRA(Reg32.EAX, ad)); if (dest != null) Add(I386.FromName2AR(op, dest, Reg32.EAX)); break; } }
public override void AddCodesV(OpModule codes, string op, Addr32 dest) { if (AddConstCodes(codes, op, dest)) return; var last = new OpCode(); for (int i = 0; i < values.Count; i++) { var v = values[i] as NodeBase; v.AddCodesV(codes, "mov", null); codes.Add(I386.Test(Reg32.EAX, Reg32.EAX)); codes.Add(I386.Jcc(Cc.Z, last.Address)); } codes.Add(I386.MovR(Reg32.EAX, Val32.New(1))); codes.Add(last); codes.AddCodes(op, dest); }
public override void AddCodesV(OpModule codes, string op, Addr32 dest) { if (AddConstCodes(codes, op, dest)) return; OpCode last = new OpCode(); for (int i = 0; i < values.Count; i++) { (values[i] as NodeBase).AddCodesV(codes, "mov", null); codes.Add(I386.Test(Reg32.EAX, Reg32.EAX)); if (i < values.Count - 1) codes.Add(I386.Jcc(Cc.NZ, last.Address)); } codes.Add(last); codes.Add(I386.MovR(Reg32.EAX, Val32.New(0))); codes.Add(I386.Setcc(Cc.NZ, Reg8.AL)); codes.AddCodes(op, dest); }
public static OpCode[] CallArgs(CallType call, Addr32 func, object[] args) { var list = new ArrayList(); for (int i = args.Length - 1; i >= 0; i--) { var arg = args[i]; if (arg is int) list.Add(PushD(Val32.NewI((int)arg))); else if (arg is uint) list.Add(PushD(Val32.New((uint)arg))); else if (arg is Val32) list.Add(PushD((Val32)arg)); else if (arg is Addr32) list.Add(PushA((Addr32)arg)); else throw new Exception("Unknown argument."); } list.Add(CallA(func)); if (call == CallType.CDecl) { list.Add(AddR(Reg32.ESP, Val32.New((byte)(args.Length * 4)))); } var ret = new OpCode[list.Count]; for (int i = 0; i < ret.Length; i++) ret[i] = list[i] as OpCode; return ret; }
public static OpCode ShiftWA(string op, Addr32 op1, byte op2) { Addr32 ad; switch (op) { case "shl": case "sal": ad = Addr32.NewAdM(op1, 4); break; case "shr": ad = Addr32.NewAdM(op1, 5); break; case "sar": ad = Addr32.NewAdM(op1, 7); break; default: throw new Exception("invalid operator: " + op); } if (op2 == 1) return OpCode.NewA(Util.GetBytes2(0x66, 0xd1), ad); else return OpCode.NewBA(Util.GetBytes2(0x66, 0xc1), op2, ad); }
public override void AddCodesV(OpModule codes, string op, Addr32 dest) { var tt = Type.Type; var tts = tt as TypeStruct; if (!IsArray && (tts == null || !tts.IsClass)) throw Abort("new: is not class: {0}", tts.Name); var f = Parent.GetFunction(Function); if (f == null) throw Abort("new: undefined function: {0}", Function); Val32 type = codes.GetTypeObject(Type), izer = Val32.New(0), ctor = Val32.New(0), init = null; if (!IsArray) { var st = tts.GetStruct(); if (st.IsEmpty) { init = st.First; st = st.GetBaseStruct(); type = codes.GetTypeObjectD(st); } izer = codes.GetAddress(st.GetFunction(Define.Initializer)); ctor = codes.GetAddress(st.GetFunction(Define.Constructor)); } codes.Add(I386.PushD(ctor)); codes.Add(I386.PushD(izer)); Length.AddCodesV(codes, "push", null); codes.Add(I386.PushD(Val32.NewI(tt.Size))); codes.Add(I386.PushD(type)); codes.Add(I386.CallD(f.First)); codes.Add(I386.AddR(Reg32.ESP, Val32.New(16))); if (init != null) { codes.Add(I386.Push(Reg32.EAX)); codes.Add(I386.CallD(init)); codes.Add(I386.Pop(Reg32.EAX)); } codes.AddCodes(op, dest); }
public static OpCode AndAR(Addr32 op1, Reg32 op2) { return FromName2AR("and", op1, op2); }
public static OpCode SarWAR(Addr32 op1, Reg8 op2) { return ShiftWAR("sar", op1, op2); }
public static OpCode SarWA(Addr32 op1, byte op2) { return ShiftWA("sar", op1, op2); }
public static OpCode ShlWAR(Addr32 op1, Reg8 op2) { return ShiftWAR("shl", op1, op2); }
public static OpCode ShlWA(Addr32 op1, byte op2) { return ShiftWA("shl", op1, op2); }
public static OpCode ShiftWAR(string op, Addr32 op1, Reg8 op2) { Addr32 ad; switch (op) { case "shl": case "sal": ad = Addr32.NewAdM(op1, 4); break; case "shr": ad = Addr32.NewAdM(op1, 5); break; case "sar": ad = Addr32.NewAdM(op1, 7); break; default: throw new Exception("invalid operator: " + op); } if (op2 != Reg8.CL) throw new Exception("invalid register: " + op2); else return OpCode.NewA(Util.GetBytes2(0x66, 0xd3), ad); }
public static OpCode CmpAR(Addr32 op1, Reg32 op2) { return FromName2AR("cmp", op1, op2); }
public static OpCode CmpA(Addr32 op1, Val32 op2) { return FromName2A("cmp", op1, op2); }
public static OpCode AndRA(Reg32 op1, Addr32 op2) { return FromName2RA("and", op1, op2); }
public static OpCode AndA(Addr32 op1, Val32 op2) { return FromName2A("and", op1, op2); }
public static OpCode XorRA(Reg32 op1, Addr32 op2) { return FromName2RA("xor", op1, op2); }