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 void AddOperatorCodes(TypeBase tb, string op, Addr32 dest, NodeBase arg, bool pushf) { arg.AddCodesV(this, "mov", null); var cleanup = NeedsDtor(arg); if (cleanup) { Add(I386.Push(Reg32.EAX)); if (dest.Register == Reg32.ESP) dest = Addr32.NewRO(dest.Register, dest.Disp + 4); } tb.AddOpCodes(op, this, dest); if (cleanup) { if (pushf) { Add(I386.Pop(Reg32.EAX)); Add(I386.Pushf()); Add(I386.Push(Reg32.EAX)); } AddDtorCodes(arg.Type); if (pushf) Add(I386.Popf()); } }
private void Simd(OpModule codes, string op, NodeBase m1, NodeBase m2) { var m1m = GetMm(m1); var m2m = GetMm(m2); var m1x = GetXmm(m1); var m2x = GetXmm(m2); var op2 = op.Substring(2); if (m1m != -1) { if (m2m != -1) codes.Add(MMX.FromName(op2, (Mm)m1m, (Mm)m2m)); else { m2.AddCodesV(codes, "mov", null); codes.Add(MMX.FromNameA(op2, (Mm)m1m, Addr32.New(Reg32.EAX))); } } else if (m1x != -1) { if (m2x != -1) codes.Add(SSE2.FromName(op2, (Xmm)m1x, (Xmm)m2x)); else { m2.AddCodesV(codes, "mov", null); codes.Add(SSE2.FromNameA(op2, (Xmm)m1x, Addr32.New(Reg32.EAX))); } } else throw Abort("{0}: invalid argument 1", op); }
private void Movq(OpModule codes, NodeBase m1, NodeBase m2) { var m1m = GetMm(m1); var m2m = GetMm(m2); var m1x = GetXmm(m1); var m2x = GetXmm(m2); if (m1m != -1 && m2m != -1) codes.Add(MMX.MovQ((Mm)m1m, (Mm)m2m)); else if (m1x != -1 && m2x != -1) codes.Add(SSE2.MovQ((Xmm)m1x, (Xmm)m2x)); else if (m1m != -1) { m2.AddCodesV(codes, "mov", null); codes.Add(MMX.MovQA((Mm)m1m, Addr32.New(Reg32.EAX))); } else if (m2m != -1) { m1.AddCodesV(codes, "mov", null); codes.Add(MMX.MovQAM(Addr32.New(Reg32.EAX), (Mm)m2m)); } else if (m1x != -1) { m2.AddCodesV(codes, "mov", null); codes.Add(SSE2.MovQA((Xmm)m1x, Addr32.New(Reg32.EAX))); } else if (m2x != -1) { m1.AddCodesV(codes, "mov", null); codes.Add(SSE2.MovQAX(Addr32.New(Reg32.EAX), (Xmm)m2x)); } else throw Abort("__movq: invalid arguments"); }
private void Movdq(OpModule codes, string op, NodeBase m1, NodeBase m2) { var m1x = GetXmm(m1); var m2x = GetXmm(m2); var op2 = op.Substring(2); if (m1x != -1 && m2x != -1) codes.Add(SSE2.FromName(op2, (Xmm)m1x, (Xmm)m2x)); else if (m1x != -1) { m2.AddCodesV(codes, "mov", null); codes.Add(SSE2.FromNameA(op2, (Xmm)m1x, Addr32.New(Reg32.EAX))); } else if (m2x != -1) { m1.AddCodesV(codes, "mov", null); codes.Add(SSE2.FromNameAX(op2, Addr32.New(Reg32.EAX), (Xmm)m2x)); } else throw Abort("{0}: invalid arguments", op); }
private void Movd(OpModule codes, NodeBase m1, NodeBase m2) { var m1m = GetMm(m1); var m2m = GetMm(m2); var m1x = GetXmm(m1); var m2x = GetXmm(m2); if (m1m != -1) { if (m2 is Var && m2.Type is TypeIntBase) { var ad = (m2 as Var).GetAddress(codes); codes.Add(MMX.MovDA((Mm)m1m, ad)); } else if (m2 is IntValue) { m2.AddCodesV(codes, "mov", null); codes.Add(MMX.MovD((Mm)m1m, Reg32.EAX)); } else { m2.AddCodesV(codes, "mov", null); codes.Add(MMX.MovDA((Mm)m1m, Addr32.New(Reg32.EAX))); } return; } else if (m1x != -1) { if (m2 is Var && m2.Type is TypeIntBase) { var m2a = (m2 as Var).GetAddress(codes); codes.Add(SSE2.MovDA((Xmm)m1x, m2a)); } else if (m2 is IntValue) { m2.AddCodesV(codes, "mov", null); codes.Add(SSE2.MovD((Xmm)m1x, Reg32.EAX)); } else { m2.AddCodesV(codes, "mov", null); codes.Add(SSE2.MovDA((Xmm)m1x, Addr32.New(Reg32.EAX))); } return; } var v = Var.Get(m1); if (v == null) throw Abort("__movd: invalid argument 1"); if (m2m != -1) { if (v.Type is TypeIntBase) { var ad = v.GetAddress(codes); codes.Add(MMX.MovDAM(ad, (Mm)m2m)); } else { v.AddCodesV(codes, "mov", null); codes.Add(MMX.MovDAM(Addr32.New(Reg32.EAX), (Mm)m2m)); } } else if (m2x != -1) { if (v.Type is TypeIntBase) { var ad = v.GetAddress(codes); codes.Add(SSE2.MovDAX(ad, (Xmm)m2x)); } else { v.AddCodesV(codes, "mov", null); codes.Add(SSE2.MovDAX(Addr32.New(Reg32.EAX), (Xmm)m2x)); } } else throw Abort("__movd: invalid argument 2"); }