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 override void AddCodes(OpModule codes) { int len = values.Count; if (len == 0) { codes.Add(I386.JmpD(Block.First)); return; } for (int i = 0; i < values.Count; i++) { var v = values[i] as NodeBase; codes.Add(I386.Push(Reg32.EDX)); if (v.Type is TypeString) { v.AddCodesV(codes, "push", null); codes.Add(codes.GetCall("case", TypeString.Equal)); codes.Add(I386.AddR(Reg32.ESP, Val32.New(8))); codes.Add(I386.Test(Reg32.EAX, Reg32.EAX)); codes.Add(I386.Jcc(Cc.NZ, Block.First)); } else { v.AddCodesV(codes, "mov", null); codes.Add(I386.Pop(Reg32.EDX)); codes.Add(I386.Cmp(Reg32.EDX, Reg32.EAX)); codes.Add(I386.Jcc(Cc.E, Block.First)); } } if (IsLast) codes.Add(I386.JmpD(Parent.Destruct)); }
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 AddDestructor(OpModule codes) { codes.Add(I386.MovRA(Reg32.EAX, Addr32.New(Reg32.ESP))); codes.Add(I386.PushA(Addr32.New(Reg32.EAX))); codes.Add(codes.GetCall("delegate", DelgFunc.Free)); codes.Add(I386.AddR(Reg32.ESP, Val32.New(4))); }
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 AddConstructor(OpModule codes) { var st = GetStruct(); var f1 = st.GetFunction(Define.Initializer); var f2 = st.GetFunction(Define.Constructor); codes.Add(I386.CallD(f1.First)); codes.Add(I386.CallD(f2.First)); }
public override void AddCodes(OpModule codes) { codes.Add(first); if (alias != null) codes.Add(I386.Jmp(codes.Module.GetFunction(module, alias))); else codes.Add(I386.Jmp(codes.Module.GetFunction(module, name))); }
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))); }
public override void AddCodes(OpModule codes) { var dest = Var.Get(this.dest); if (dest == null) { if (this.dest is Variant) { var setter = (this.dest as Variant).GetSetter(); if (setter != null) { var args = new NodeBase[1]; args[0] = values[0] as NodeBase; Call.NewV(Parent, setter, This.New(Parent), args) .AddCodes(codes); return; } } throw Abort("set: destination is not variable"); } var dt = dest.Type; if (dt is TypeConstChar) throw Abort("set: can not change constants"); if (dest is Member) { var mem = dest as Member; if (mem.IsSetter) { mem.AddSetterCodes(codes, values[0] as NodeBase); return; } } var v = values[0] as NodeBase; v.AddCodesV(codes, "push", null); var ad = dest.GetAddress(codes); if (!OpModule.NeedsDtor(v)) { if (ad == null) { ad = Addr32.New(Reg32.ESP); codes.Add(I386.XchgRA(Reg32.EAX, ad)); dt.AddSetCodes(codes, ad); codes.Add(I386.AddR(Reg32.ESP, Val32.New(4))); } else { codes.Add(I386.Pop(Reg32.EAX)); dt.AddSetCodes(codes, ad); } } else { codes.Add(I386.MovRA(Reg32.EAX, Addr32.New(Reg32.ESP))); dt.AddSetCodes(codes, ad); codes.AddDtorCodes(v.Type); } }
protected override void BeforeAddCodes(OpModule codes) { base.BeforeAddCodes(codes); if (Init != null) Init.AddCodes(codes); if (Loop != null) codes.Add(I386.JmpD(Loop.Last)); else codes.Add(I386.JmpD(Block.Last)); }
public override void AddCodes(OpModule codes) { var next = new OpCode(); codes.Add(first); if (Cond != null) { Cond.Next = next.Address; Cond.AddCodes(codes); } Block.AddCodes(codes); if (Next != null) codes.Add(I386.JmpD(Parent.Destruct)); codes.Add(next); }
public override void AddCodes(OpModule codes) { if (Next != null) { (values[0] as NodeBase).AddCodesV(codes, "mov", null); codes.Add(I386.Test(Reg32.EAX, Reg32.EAX)); codes.Add(I386.Jcc(Cc.Z, Next)); } else if (First != null) { (values[0] as NodeBase).AddCodesV(codes, "mov", null); codes.Add(I386.Test(Reg32.EAX, Reg32.EAX)); codes.Add(I386.Jcc(Cc.NZ, First)); } }
public static void AddCallCodes(OpModule codes, Function f, NodeBase[] args) { AddCallCodes2(codes, args, f.CallType, delegate() { codes.Add(I386.CallD(f.First)); }); }
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 override Addr32 GetAddress(OpModule codes) { if (Source is Var) return (Source as Var).GetAddress(codes); else if (Source is IntValue) codes.Add(I386.MovR(Var.DestRegister, Val32.NewI((Source as IntValue).Value))); else if (Source is StringValue) codes.Add(I386.MovR(Var.DestRegister, codes.GetString((Source as StringValue).Value))); else { Source.AddCodesV(codes, "mov", null); return null; } return Addr32.New(Var.DestRegister); }
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 AddCodes(OpModule codes) { ///if (castFailed != null) throw Abort(castFailed); var f = Parent.GetBelongFunction(); if (value != null) { value.AddCodesV(codes, "mov", null); var retval = f.GetRetVal(Parent); var dest = retval.GetAddress(codes); if (!OpModule.NeedsDtor(value)) { codes.Add(I386.MovAR(dest, Reg32.EAX)); var tr = value.Type as TypeReference; if (tr != null && tr.UseGC) TypeReference.AddReferenceCodes(codes); } else { codes.Add(I386.Push(Reg32.EAX)); var rt = f.ReturnType; if (rt == null) codes.Add(I386.MovAR(dest, Reg32.EAX)); else { if (rt is TypeReference) codes.Add(I386.MovA(dest, Val32.New(0))); rt.AddSetCodes(codes, dest); } codes.AddDtorCodes(value.Type); } } var b = Parent; var ptrs = UsingPointers; for (; ; ptrs = b.UsingPointers, b = b.Parent) { b.AddDestructors(codes, ptrs); if (b == f) break; b.AddExitCodes(codes); } if (!IsLast) codes.Add(I386.JmpD(b.Destruct)); }
public override void AddExitCodes(OpModule codes) { switch (Subsystem) { case IMAGE_SUBSYSTEM.WINDOWS_CUI: case IMAGE_SUBSYSTEM.WINDOWS_GUI: if (retVal != null) GetRetVal(this).AddCodesV(codes, "push", null); else codes.Add(I386.PushD(Val32.New(0))); codes.Add(I386.CallA(codes.Module.GetFunction( "kernel32.dll", "ExitProcess"))); break; default: if (retVal != null) GetRetVal(this).AddCodesV(codes, "mov", null); else codes.Add(I386.Xor(Reg32.EAX, Reg32.EAX)); break; } }
// 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 AddCodes(OpModule codes) { var b = Parent; var ptrs = UsingPointers; for (; ; ptrs = b.UsingPointers, b = b.Parent) { if (b == null || b is Function) throw Abort("invalid break"); b.AddDestructors(codes, ptrs); if (b.AcceptsBreak) break; b.AddExitCodes(codes); } codes.Add(I386.JmpD(b.Destruct)); }
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 override void AddDestructor(OpModule codes) { if (!NeedsDtor) return; codes.Add(I386.MovRA(Reg32.EAX, Addr32.New(Reg32.ESP))); codes.Add(I386.MovRA(Reg32.EAX, Addr32.New(Reg32.EAX))); AddDereferenceCodes(codes); }
protected override void AfterAddCodes(OpModule codes) { AddExitCodes(codes); codes.Add(I386.Ret()); }
public override void AddCodes(OpModule codes) { value.AddCodesV(codes, "mov", null); codes.Add(I386.Mov(Reg32.EDX, Reg32.EAX)); }
// set value public override void AddSetCodes(OpModule codes, Addr32 ad) { if (UseGC) { 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.MovRA(Reg32.EAX, ad)); AddDereferenceCodes(codes); codes.Add(I386.MovRA(Reg32.EAX, Addr32.New(Reg32.ESP))); AddReferenceCodes(codes); codes.Add(I386.Pop(Reg32.EAX)); if (flag) codes.Add(I386.Pop(ad.Register)); } base.AddSetCodes(codes, ad); }
public Addr32 GetAddress(OpModule codes, BlockBase scope) { if (IsMember && !IsStatic) { var thisptr = This.New(scope); codes.Add(I386.MovRA(Var.DestRegister, thisptr.GetAddress(codes))); return Addr32.NewAd(Address); } int plv = scope.Level, lv = Parent.Level; if (plv == lv || Address.IsAddress) return Addr32.NewAd(Address); if (lv <= 0 || lv >= plv) throw Abort("Invalid variable scope: " + Name); codes.Add(I386.MovRA(Var.DestRegister, Addr32.NewRO(Reg32.EBP, -lv * 4))); return Addr32.NewRO(Var.DestRegister, Address.Disp); }
public static void AddReferenceCodes(OpModule codes) { codes.Add(I386.Push(Reg32.EAX)); codes.Add(codes.GetCall("var", Reference)); codes.Add(I386.Pop(Reg32.EAX)); }
public override void AddCodesV(OpModule codes, string op, Addr32 dest) { var thisdest = Var.Get(this.dest); if (thisdest == null) throw Abort("{0}: destination is not variable", Tag); var ad1 = thisdest.GetAddress(codes); var ad2 = ad1; thisdest.Type.AddGetCodes(codes, "push", null, ad1); if (thisdest.Type.Size < Var.DefaultSize) { ad2 = Addr32.New(Reg32.ESP); codes.Add(I386.PushA(ad2)); } CheckFunc().AddOpCodes(Tag, codes, ad2); if (thisdest.Type.Size < Var.DefaultSize) { codes.Add(I386.Pop(Reg32.EAX)); thisdest.Type.AddSetCodes(codes, ad1); } codes.Add(I386.Pop(Reg32.EAX)); codes.AddCodes(op, dest); }
private Addr32 Calculate(OpModule codes) { var dest = Var.Get(this.dest); if (dest == null) throw Abort("{0}: destination is not variable", Tag); var ad1 = dest.GetAddress(codes); var ad2 = ad1; if (dest.Type.Size < Var.DefaultSize) { ad2 = Addr32.New(Reg32.ESP); dest.Type.AddGetCodes(codes, "push", null, ad1); } CheckFunc().AddOpCodes(Tag, codes, ad2); if (dest.Type.Size < Var.DefaultSize) { codes.Add(I386.Pop(Reg32.EAX)); dest.Type.AddSetCodes(codes, ad1); } return ad1; }