Example #1
0
        void AppendOp(SSA.Value v, bool isConst = false)
        {
            switch (v.op)
            {
            case Op.FunctionArgument:
            case Op.ConstAggregateZero:
            case Op.ConstInt:
            case Op.ConstReal:
            case Op.ConstArray:
            case Op.ConstStruct:
            case Op.ConstPtr:
            case Op.ConstVoid:
            case Op.Label:
                throw new InvalidCodePath();

            case Op.Function:
            {
                Debug.Assert(!isConst);
                var  f = (Function)v;
                bool declare;
                if (f.blocks == null || f.blocks.Count == 0)
                {
                    AP("declare ");
                    declare = true;
                }
                else
                {
                    AP("define ");
                    if (f.exportDLL)
                    {
                        AP("dllexport ");
                    }
                    if (!f.exportDLL && f.internalLinkage)
                    {
                        AP("internal ");
                    }
                    declare = false;
                }
                var pt = (PointerType)f.type;
                var ft = (FunctionType)pt.elementType;
                AppendType(ft.returnType);
                AP($" {f.name}(");
                for (int i = 0; i < f.args.Count; ++i)
                {
                    var arg = (FunctionArgument)f.args[i];
                    Debug.Assert(arg.op == Op.FunctionArgument);
                    AppendType(arg.type);
                    if (arg.noalias)
                    {
                        AP(" noalias");
                    }
                    if (arg.nocapture)
                    {
                        AP(" nocapture");
                    }
                    if (arg.@readonly)
                    {
                        AP(" readonly");
                    }
                    if (!declare)
                    {
                        AP($" {arg.name}");
                    }
                    if (i != f.args.Count - 1)
                    {
                        AP($", ");
                    }
                }
                var attribIdx = AddAttrib(f.attribs);
                if (!declare)
                {
                    AP($") #{attribIdx}");
                    AppendFunctionDebugInfo(v);
                    AL(" {");
                    foreach (var b in f.blocks)
                    {
                        debugCurrentEmitBlock = b;
                        AL($"{b.name.Substring(1)}:");
                        isIndented = true;
                        if (b.name == "%vars")
                        {
                            AppendFunctionArgumentsDebugInfo(v);
                        }
                        foreach (var op in b.args)
                        {
                            AppendOp(op);
                        }
                        isIndented = false;
                    }
                    AL("}");
                }
                else
                {
                    AL($") #{attribIdx}");
                }

                AL();
            }
            break;

            case Op.GlobalStringPtr:
            {
                if (!isConst)
                {
                    var gsp = (GlobalStringPtr)v;
                    var es  = EscapeString(gsp.data);
                    AL($"{gsp.name} = private unnamed_addr constant [{gsp.data.Length + 1} x i8] c\"{es}\\00\"");
                }
                else
                {
                    AP(v.name);
                }
            }
            break;

            case Op.GlobalVariable:
            {
                if (!isConst)
                {
                    var gv = (GlobalVariable)v;
                    AppendAssignSSA(gv);
                    AP($"internal global {(gv.isConstantVariable ? "constant " : "")}");
                    var pt = (PointerType)gv.type;
                    AppendType(pt.elementType);
                    AP(" ");
                    AppendConstValue(gv.initializer);
                    AppendGlobalVariableDebugInfo(gv);
                    if (v.alignment > 0)
                    {
                        AP($", align {v.alignment}");
                    }
                    AL();
                }
                else
                {
                    AP(v.name);
                }
            }
            break;

            case Op.Br:
            {
                if (v.args.Count == 1)
                {
                    Debug.Assert(!isConst);
                    Indent();
                    AP("br ");
                    AppendArgument(v.args[0]);
                    AppendDebugInfo(v);
                    AL();
                }
                else
                {
                    Indent();
                    AP("br ");
                    AppendArgument(v.args[0]);
                    AP(", ");
                    AppendArgument(v.args[1]);
                    AP(", ");
                    AppendArgument(v.args[2]);
                    AppendDebugInfo(v);
                    AL();
                }
            }

            break;

            case Op.Phi:
            {
                AppendAssignSSA(v);
                AP("phi ");
                AppendType(v.type);
                AP(" ");
                var phi = (Phi)v;
                for (int i = 0; i < phi.incoming.Count; ++i)
                {
                    AP("[ ");
                    var inc = phi.incoming[i];
                    AppendArgument(inc.v, false);
                    AP(", ");
                    AppendArgument(inc.b, false);
                    AP(" ]");
                    if (i != phi.incoming.Count - 1)
                    {
                        AP(", ");
                    }
                }
                AppendDebugInfo(v);
                AL();
            }
            break;

            case Op.Call:
            {
                Debug.Assert(!isConst);
                if (v.type.kind != TypeKind.Void)
                {
                    AppendAssignSSA(v);
                }
                else
                {
                    Indent();
                }
                var fun = v.args[0];
                var pt  = (PointerType)fun.type;
                var ft  = (FunctionType)pt.elementType;

                if (fun is Function f && f.attribs.HasFlag(FunctionAttribs.lvvm))
                {
                    AP($"{f.name.Substring(1)} ");
                    for (int i = 1; i < v.args.Count; ++i)
                    {
                        AppendArgument(v.args[i]);
                        if (i != v.args.Count - 1)
                        {
                            AP(", ");
                        }
                    }
                }
Example #2
0
        void AppendConstValue(SSA.Value v)
        {
            switch (v)
            {
            case ConstInt i:
                var it = i.type as IntegerType;
                if (it.bitWidth == 1)
                {
                    if (i.flags.HasFlag(SSAFlags.undef))
                    {
                        AP("undef");
                    }
                    else if (i.data == 0)
                    {
                        AP("false");
                    }
                    else
                    {
                        AP("true");
                    }
                }
                else
                {
                    if (i.flags.HasFlag(SSAFlags.undef))
                    {
                        AP("undef");
                    }
                    else
                    {
                        AP(i.data.ToString());
                    }
                }
                break;

            case ConstReal r:
                string fs = null;
                var    rt = (FloatType)r.type;
                if (r.flags.HasFlag(SSAFlags.undef))
                {
                    AP("undef");
                }
                else if (rt.width == FloatType.FloatWidths.fp64)
                {
                    var bytes  = BitConverter.GetBytes(r.data);
                    var number = BitConverter.ToUInt64(bytes, 0);
                    fs = $"0x{number.ToString("X16", nfi)}";
                }
                else if (rt.width == FloatType.FloatWidths.fp32)
                {
                    var f32    = (float)r.data;
                    var bytes  = BitConverter.GetBytes((double)f32);
                    var number = BitConverter.ToUInt64(bytes, 0);;
                    fs = $"0x{number.ToString("X16", nfi)}";
                }
                else if (rt.width == FloatType.FloatWidths.fp16)
                {
                    throw new NotImplementedException();
                }
                AP(fs);
                break;

            case ConstPtr p:
                if (p.flags.HasFlag(SSAFlags.undef))
                {
                    AP("undef");
                }
                else if (p.data == 0)
                {
                    AP("null");
                }
                else
                {
                    AP(p.data.ToString());
                }
                break;

            case ConstArray a:
            {
                AP("[ ");
                for (int i = 0; i < a.data.Count; ++i)
                {
                    var d = a.data[i];
                    AppendType(d.type);
                    AP(" ");
                    AppendConstValue(d);
                    if (i != a.data.Count - 1)
                    {
                        AP(", ");
                    }
                }
                AP(" ]");
            }
            break;

            case ConstStruct st:
            {
                if (!st.packed)
                {
                    AP("{ ");
                }
                else
                {
                    AP("<{ ");
                }

                for (int i = 0; i < st.elements.Count; ++i)
                {
                    var el = st.elements[i];
                    AppendType(el.type);
                    AP(" ");
                    AppendConstValue(el);
                    if (i != st.elements.Count - 1)
                    {
                        AP(", ");
                    }
                }
                if (!st.packed)
                {
                    AP(" }");
                }
                else
                {
                    AP(" }>");
                }
            }
            break;

            case ConstVec vec:
            {
                AP("<");
                var vt = (VectorType)vec.type;
                for (int i = 0; i < vt.elementCount; ++i)
                {
                    var el = vec.elements[i];
                    AppendType(el.type);
                    AP(" ");
                    AppendConstValue(el);
                    if (i != vt.elementCount - 1)
                    {
                        AP(", ");
                    }
                }
                AP(">");
            }
            break;

            case Value caz when caz.op == Op.ConstAggregateZero:
                AP("zeroinitializer");
                break;

            default:
                AppendOp(v, true);
                break;
            }
        }