public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams)
 {
     //$BUG: this is all just to get the ELF loader up and running.
     // fill in with details from
     // https://blackfin.uclinux.org/doku.php?id=toolchain:application_binary_interface
     ccr.LowLevelDetails(4, 0);
     if (dtRet != null && !(dtRet is VoidType))
     {
         ccr.RegReturn(arch.GetRegister("R0"));
     }
     foreach (var dt in dtParams)
     {
         ccr.RegParam(arch.GetRegister("R0"));
     }
 }
Esempio n. 2
0
 public void SetReturnRegister(ICallingConventionEmitter ccr, int bitSize)
 {
     if (bitSize <= 32)
     {
         ccr.RegReturn(argRegs[0]);
     }
     else if (bitSize <= 64)
     {
         ccr.SequenceReturn(argRegs[1], argRegs[0]);
     }
     else
     {
         throw new NotSupportedException(string.Format("Return values of {0} bits are not supported.", bitSize));
     }
 }
Esempio n. 3
0
        public void Generate(ICallingConventionEmitter ccr, DataType?dtRet, DataType?dtThis, List <DataType> dtParams)
        {
            int stackOffset = 4;        // return address

            ccr.LowLevelDetails(4, stackOffset);
            if (dtRet != null)
            {
                ccr.RegReturn(Registers.d0);
            }

            for (int i = 0; i < dtParams.Count; ++i)
            {
                ccr.StackParam(dtParams[i]);
            }
            ccr.CallerCleanup(4);
        }
Esempio n. 4
0
        public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams)
        {
            int fr = 0;
            int gr = 0;

            ccr.LowLevelDetails(8, 160);
            for (int i = 0; i < dtParams.Count; ++i)
            {
                var dt = dtParams[i];
                switch (dt)
                {
                case PrimitiveType pt:
                    if (pt.Domain == Domain.Real)
                    {
                        if (fr < this.fregs.Length)
                        {
                            ccr.RegParam(fregs[fr]);
                            ++fr;
                        }
                        else
                        {
                            ccr.StackParam(dt);
                        }
                        break;
                    }
                    goto default;

                default:
                    if (dt.BitSize <= 64)
                    {
                        if (gr < this.iregs.Length)
                        {
                            ccr.RegParam(iregs[gr]);
                            ++gr;
                            break;
                        }
                    }
                    ccr.StackParam(dt);
                    break;
                }
            }
            if (dtRet is PrimitiveType ptRet &&
                ptRet.Domain == Domain.Real)
            {
                ccr.RegReturn(fregs[0]);
            }
Esempio n. 5
0
        public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams)
        {
            ccr.LowLevelDetails(4, 0);
            if (dtRet != null)
            {
                var a2 = (StorageDomain)2;
                //$TODO: size > 4 bytes?
                ccr.RegReturn(arch.GetRegister(a2, r32));
            }
            int iReg = 2;

            foreach (var dtParam in dtParams)
            {
                //$TODO: size > 4 bytes?
                //$TODO: iReg > 6?
                var arg = (StorageDomain)iReg;
                ccr.RegParam(arch.GetRegister(arg, r32));
                ++iReg;
            }
        }
Esempio n. 6
0
        private void GenerateReturnValue(DataType dtRet, ICallingConventionEmitter ccr)
        {
            int size = dtRet.Size;

            if ((size & 1) != 0) // odd sized register occupies two regs
            {
                // Round size to even # of bytes.
                size = dtRet.Size + 1;
            }

            var iReg = 26 - size;

            if (dtRet.Size <= 8)
            {
                var reg = argRegs[iReg - 8];
                if (dtRet.Size == 1)
                {
                    ccr.RegReturn(reg);
                    return;
                }

                SequenceStorage seq = null;
                for (int r = iReg + 1, i = 1; i < dtRet.Size; ++i, ++r)
                {
                    var regNext = argRegs[r - 8];
                    if (seq != null)
                    {
                        seq = new SequenceStorage(regNext, seq, PrimitiveType.Word32);
                    }
                    else
                    {
                        seq = new SequenceStorage(regNext, reg, PrimitiveType.Word32);
                    }
                }
                ccr.SequenceReturn(seq);
            }
            else
            {
                throw new NotImplementedException("Large AVR8 return values not implemented yet.");
            }
        }
Esempio n. 7
0
        public void Generate(ICallingConventionEmitter ccr, DataType?dtRet, DataType?dtThis, List <DataType> dtParams)
        {
            ccr.LowLevelDetails(4, 4);
            if (dtRet != null)
            {
                if (dtRet.BitSize > 32)
                {
                    throw new NotImplementedException();
                }
                ccr.RegReturn(d0);
            }

            var args     = new List <Storage>();
            int stOffset = arch.PointerType.Size;

            foreach (var dtParam in dtParams)
            {
                ccr.StackParam(dtParam);
            }
            ccr.CallerCleanup(arch.PointerType.Size);
        }
        public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams)
        {
            ccr.LowLevelDetails(8, 0);      //$BUGBUG: the '0' is incorrect, but we need a reliable spec for WinAlpha to determine exact value.
            if (dtRet != null)
            {
                ccr.RegReturn(iRet);
            }
            int iReg = 0;

            foreach (var dtParam in dtParams)
            {
                if (iReg < iRegs.Length)
                {
                    ccr.RegParam(iRegs[iReg]);
                    ++iReg;
                }
                else
                {
                    ccr.StackParam(PrimitiveType.Word64);
                }
            }
        }
Esempio n. 9
0
        public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams)
        {
            int stackOffset = 4 + 4;   // Skip the system call selector + return address.

            ccr.LowLevelDetails(4, stackOffset);
            if (dtRet != null)
            {
                ccr.RegReturn(Registers.d0);
            }

            if (dtThis != null)
            {
                //ImplicitThis = null, //$TODO
                throw new NotImplementedException("C++ implicit `this` arguments are not implemented for Atari TOS.");
            }
            for (int iArg = 0; iArg < dtParams.Count; ++iArg)
            {
                ccr.StackParam(dtParams[iArg]);
            }
            // AFAIK the calling convention on Atari TOS is caller-cleanup,
            // so the only thing we clean up is the return value on the stack.
            ccr.CallerCleanup(4);
        }
Esempio n. 10
0
        private void GenerateReturnValue(DataType dtRet, ICallingConventionEmitter ccr)
        {
            int size = dtRet.Size;

            if ((size & 1) != 0) // odd sized register occupies two regs
            {
                // Round size to even # of bytes.
                size = dtRet.Size + 1;
            }

            var iReg = 26 - size;

            if (dtRet.Size <= 8)
            {
                var reg = argRegs[iReg - 8];
                if (dtRet.Size == 1)
                {
                    ccr.RegReturn(reg);
                    return;
                }

                var retRegs = new List <RegisterStorage> {
                    reg
                };
                for (int r = iReg + 1, i = 1; i < dtRet.Size; ++i, ++r)
                {
                    var regNext = argRegs[r - 8];
                    retRegs.Insert(0, regNext);
                }
                var seq = new SequenceStorage(retRegs.ToArray());
                ccr.SequenceReturn(seq);
            }
            else
            {
                throw new NotImplementedException("Large AVR8 return values not implemented yet.");
            }
        }
Esempio n. 11
0
        public void Generate(ICallingConventionEmitter ccr, DataType?dtRet, DataType?dtThis, List <DataType> dtParams)
        {
            ccr.LowLevelDetails(8, 0x0040);

            int iReg         = 0;
            int iFloat       = 0;
            int iStackOffset = 0;

            var adjusted = PrepadExtendParameters(dtParams);

            foreach (var(dom, bs) in adjusted)
            {
                var byteSize = bs;
                if (dom == Domain.Real)
                {
                    if (dom == Domain.Real && iFloat < floatRegs.Length)
                    {
                        ccr.RegParam(floatRegs[iFloat]);
                        ++iFloat;
                    }
                    else
                    {
                        // HFA / HVA's not supported yet.
                        if (byteSize >= 8)
                        {
                            iStackOffset = AlignUp(iStackOffset, Math.Max(8, byteSize));
                        }
                        if (byteSize < 8)
                        {
                            byteSize = 8;
                        }
                        ccr.StackParam(PrimitiveType.CreateWord(byteSize * 8));
                    }
                }
                else
                {
                    if (byteSize <= 8 && iReg < argRegs.Length)
                    {
                        ccr.RegParam(argRegs[iReg]);
                        ++iReg;
                    }
                    else if (byteSize == 16 && iReg < argRegs.Length - 1 && (iReg & 1) == 1)
                    {
                        ++iReg;
                        if (iReg < argRegs.Length - 1)
                        {
                            ccr.SequenceParam(argRegs[iReg], argRegs[iReg + 1]);
                            iReg += 2;
                        }
                    }
                    else if (byteSize <= (8 - iReg) * 8)
                    {
                        throw new NotImplementedException("Need to allow arbitrary sequences of regs");
                    }
                    else
                    {
                        iReg = 8;
                        if (byteSize >= 8)
                        {
                            iStackOffset = AlignUp(iStackOffset, Math.Max(8, byteSize));
                        }
                        if (byteSize < 8)
                        {
                            byteSize = 8;
                        }
                        ccr.StackParam(PrimitiveType.CreateWord(byteSize * 8));
                    }
                }
            }

            if (dtRet != null)
            {
                if (dtRet is PrimitiveType pt && pt.Domain == Domain.Real)
                {
                    if (pt.Size < 8)
                    {
                        ccr.RegReturn(floatRegs[0]);
                    }
                    else if (pt.Size < 16)
                    {
                        ccr.SequenceReturn(floatRegs[1], floatRegs[0]);
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
                else if (dtRet != null)
                {
                    if (dtRet.Size <= 8)
                    {
                        ccr.RegReturn(argRegs[0]);
                    }
                    else if (dtRet.Size <= 16)
                    {
                        ccr.SequenceReturn(argRegs[1], argRegs[0]);
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
            }
Esempio n. 12
0
 public void SetReturnRegisters(ICallingConventionEmitter ccr, DataType dtRet)
 {
     ccr.RegReturn(arch.GetRegister("r0"));
 }
Esempio n. 13
0
        public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams)
        {
            ccr.LowLevelDetails(arch.WordWidth.Size, 0);
            if (dtRet != null)
            {
                var pt = dtRet as PrimitiveType;
                if (pt != null && pt.Domain == Domain.Real)
                {
                    //$TODO floats > 64 bits
                    ccr.RegReturn(fregs[0]);
                }
                else
                {
                    if (dtRet.Size <= arch.PointerType.Size)
                    {
                        ccr.RegReturn(iregs[0]);
                    }
                    else if (dtRet.Size <= arch.PointerType.Size * 2)
                    {
                        ccr.SequenceReturn(iregs[1], iregs[0]);
                    }
                    else
                    {
                        //$TODO: return values > 128 bits.
                        throw new NotImplementedException();
                    }
                }
            }
            int ir = 0;

            for (int i = 0; i < dtParams.Count; ++i)
            {
                var dtParam = dtParams[i];
                var pt      = dtParam as PrimitiveType;
                if (pt != null && pt.Domain == Domain.Real)
                {
                    if (ir >= fregs.Length)
                    {
                        ccr.StackParam(dtParam);
                    }
                    else
                    {
                        ccr.RegParam(fregs[ir]);
                        ++ir;
                    }
                }
                else if (ir >= iregs.Length)
                {
                    ccr.StackParam(dtParam);
                }
                else if (dtParam.Size <= arch.PointerType.Size)
                {
                    ccr.RegParam(iregs[ir]);
                    ++ir;
                }
                else if (dtParam.Size <= arch.PointerType.Size * 2)
                {
                    if ((ir & 1) != 0)
                    {
                        ++ir;
                    }
                    if (ir >= iregs.Length)
                    {
                        ccr.StackParam(dtParam);
                    }
                    else
                    {
                        ccr.SequenceParam(iregs[ir + 1], iregs[ir]);
                        ir += 2;
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
        }
Esempio n. 14
0
        // https://en.wikipedia.org/wiki/Calling_convention#SuperH
        // https://www.renesas.com/en-eu/doc/products/tool/001/rej10b0152_sh.pdf
        public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams)
        {
            ccr.LowLevelDetails(4, 0x14);
            if (dtRet != null && !(dtRet is VoidType))
            {
                RegisterStorage reg;
                var             pt = dtRet as PrimitiveType;
                if (pt != null && pt.Domain == Domain.Real)
                {
                    if (pt.Size == 4)
                    {
                        reg = arch.GetRegister("fr0");
                    }
                    else
                    {
                        reg = arch.GetRegister("dr0");
                    }
                    ccr.RegReturn(reg);
                }
                else
                {
                    if (dtRet.Size > 4)
                    {
                        throw new NotImplementedException();
                    }
                    else
                    {
                        ccr.RegReturn(arch.GetRegister("r0"));
                    }
                }
            }
            int ir = 0;
            int fr = 0;

            if (dtThis != null)
            {
                ccr.ImplicitThisRegister(iregs[ir]);
                ++ir;
            }
            foreach (var dtParam in dtParams)
            {
                var pt = dtParam as PrimitiveType;
                if (pt != null && pt.Domain == Domain.Real)
                {
                    if (pt.Size == 4)
                    {
                        if (fr < fregs.Length)
                        {
                            ccr.RegParam(fregs[fr]);
                            ++fr;
                        }
                        else
                        {
                            ccr.StackParam(dtParam);
                        }
                    }
                    else
                    {
                        var dr = (fr + 1) >> 1;
                        if (dr < dregs.Length)
                        {
                            ccr.RegParam(dregs[dr]);
                            fr = 2 * (dr + 1);
                        }
                        else
                        {
                            ccr.StackParam(dtParam);
                        }
                    }
                }
                else if (ir >= iregs.Length || dtParam.Size > 4)
                {
                    ccr.StackParam(dtParam);
                }
                else
                {
                    ccr.RegParam(iregs[ir]);
                    ++ir;
                }
            }
        }