public static TypeArray New(TypeBase type, NodeBase count) { var ret = new TypeArray(); ret.Type = type; ret.count = count; return ret; }
public static void AddCallCodes2( OpModule codes, NodeBase[] args, CallType type, Action delg) { for (int i = args.Length - 1; i >= 0; i--) args[i].AddCodesV(codes, "push", null); delg(); if (type == CallType.CDecl && args.Length > 0) { int p = 4; bool pop = false; for (int i = 0; i < args.Length; i++) { var arg = args[i]; if (OpModule.NeedsDtor(arg)) { if (!pop) { codes.Add(I386.Push(Reg32.EAX)); pop = true; } arg.Type.AddDestructorA(codes, Addr32.NewRO(Reg32.ESP, p)); } p += 4; } if (pop) codes.Add(I386.Pop(Reg32.EAX)); codes.Add(I386.AddR(Reg32.ESP, Val32.New((byte)(args.Length * 4)))); } }
protected static VarOperator Init1(VarOperator op, BlockBase parent, NodeBase dest, NodeBase arg) { op.Parent = parent; op.dest = dest; op.values.Add(arg); return op; }
public static void AddCallCodes(OpModule codes, Function f, NodeBase[] args) { AddCallCodes2(codes, args, f.CallType, delegate() { codes.Add(I386.CallD(f.First)); }); }
public static Return New(BlockBase parent, NodeBase value) { var ret = new Return(); ret.init(parent); if (value != null) ret.Value = value; return ret; }
public static Var Get(NodeBase v) { if (v is Variant) return (v as Variant).GetVar(); else return v as Var; }
public static TypeOf New(BlockBase parent, NodeBase target) { var ret = new TypeOf(); ret.Parent = parent; ret.Target = target; return ret; }
protected static Operator Init2(Operator op, BlockBase parent, NodeBase arg1, NodeBase arg2) { op.Parent = parent; if (arg1 != null) op.values.Add(arg1); if (arg2 != null) op.values.Add(arg2); return op; }
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 static VarDeclare Array(BlockBase parent, string name, TypeBase type, NodeBase count) { var ret = New(parent, name, null); ret.doneInferType = true; ret.type = TypeArray.New(type, count); return ret; }
public static Cast New(BlockBase parent, string type, NodeBase source) { var ret = new Cast(); ret.Parent = parent; ret.name = "__cast"; ret.type = type; ret.Source = source; return ret; }
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); } }
public static TypeBase GetType(BlockBase parent, NodeBase target) { var v = target as Variant; if (v != null) { var vt = v.GetVariantType(); if (vt != null) return vt; return Types.GetType(parent, v.Name); } return target.Type; }
public static IntValue GetValue(NodeBase v) { if (v is ConstInt) return GetValue((v as ConstInt).Value); else if (v is IntValue) return v as IntValue; else if (v is Operator) return (v as Operator).GetConst(); else if (v is Variant) return GetValue((v as Variant).GetConst()); else return null; }
public static bool NeedsDtor(NodeBase v) { while (v is Cast) v = (v as Cast).Source; var vt = v.Type; if (vt == null) return false; var vsm = v as Member; if (vsm != null && vt is TypeDelegate && vsm.GetDelegate() != null) return true; var mem = v as Member; return vt.NeedsDtor && !(v is As) && (v is Call || v is New || v is DelgFunc || v is Operator || (mem != null && mem.IsGetter)); }
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"); }
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); }
protected static Operator Init1(Operator op, BlockBase parent, NodeBase arg1) { return Init2(op, parent, arg1, null); }
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 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); }
public static PostInc New(BlockBase parent, NodeBase dest) { return Init0(new PostInc(), parent, dest) as PostInc; }
private int GetXmm(NodeBase v) { var fp = v as Variant; if (fp == null || !fp.Name.StartsWith("__xmm") || fp.Name.Length != 6) return -1; var n = fp.Name[5]; if (n < '0' || n > '9') return -1; return n - '0'; }
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()); } }
public static Switch New(BlockBase parent, NodeBase expr) { var ret = new Switch(); ret.init(parent); ret.expr = SwitchExpr.New(ret, expr); return ret; }
public static VarShiftRight New(BlockBase parent, NodeBase dest, NodeBase arg) { return Init1(new VarShiftRight(), parent, dest, arg) as VarShiftRight; }
private void SimdShift(OpModule codes, string op, NodeBase m1, NodeBase m2) { IntValue m2i = m2 as IntValue; if (m2i == null) { Simd(codes, op, m1, m2); return; } var m1m = GetMm(m1); var m1x = GetXmm(m1); var op2 = op.Substring(2); if (m1m != -1) codes.Add(MMX.FromNameB(op2, (Mm)m1m, (byte)m2i.Value)); else if (m1x != -1) codes.Add(SSE2.FromNameB(op2, (Xmm)m1x, (byte)m2i.Value)); else throw Abort("{0}: invalid argument 1", op); }
public static VarMod New(BlockBase parent, NodeBase dest, NodeBase arg) { return Init1(new VarMod(), parent, dest, arg) as VarMod; }
public static Dec New(BlockBase parent, NodeBase dest) { return Init0(new Dec(), parent, dest) as Dec; }
public static SwitchExpr New(BlockBase parent, NodeBase value) { var ret = new SwitchExpr(); ret.Parent = parent; ret.value = value; return ret; }
public static Expression New(BlockBase parent, NodeBase arg) { return Init1(new Expression(), parent, arg) as Expression; }