public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams)
        {
            int stackOffset = 0x40; //$BUG: look this up!

            ccr.LowLevelDetails(arch.WordWidth.Size, stackOffset);
            if (dtRet != null)
            {
                SetReturnRegister(ccr, dtRet);
            }

            int fr = 0;
            int gr = 0;

            for (int i = 0; i < dtParams.Count; ++i)
            {
                var dtArg = dtParams[i];
                var prim  = dtArg as PrimitiveType;
                if (prim != null && prim.Domain == Domain.Real)
                {
                    if (fr > 8)
                    {
                        ccr.StackParam(dtArg);
                    }
                    else
                    {
                        ccr.RegParam(fregs[fr]);
                        ++fr;
                    }
                }
                else if (dtArg.Size <= 4)
                {
                    if (gr >= iregs.Length)
                    {
                        ccr.StackParam(dtArg);
                    }
                    else
                    {
                        ccr.RegParam(iregs[gr]);
                        ++gr;
                    }
                }
                else if (dtArg.Size <= 8)
                {
                    if (gr >= iregs.Length - 1)
                    {
                        ccr.StackParam(dtArg);
                    }
                    else
                    {
                        if ((gr & 1) == 1)
                        {
                            ++gr;
                        }
                        ccr.SequenceParam(iregs[gr], iregs[gr + 1]);
                        gr += 2;
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
        }
Example #2
0
 public void SetReturnRegisters(ICallingConventionEmitter ccr, DataType dtRet)
 {
     //$TODO: use dtRet?
     ccr.RegReturn(arch.GetRegister("r0") !);
 }
Example #3
0
        public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams)
        {
            /*
             * To find the register where a function argument is passed, initialize the register number
             * Rn with R26 and follow this procedure:
             *
             * If the argument size is an odd number of bytes, round up the size to the next even number.
             * Subtract the rounded size from the register number Rn.
             *
             * If the new Rn is at least R8 and the size of the object is non-zero, then the low-byte of
             * the argument is passed in Rn. Subsequent bytes of the argument are passed in the subsequent
             * registers, i.e. in increasing register numbers.
             *
             * If the new register number Rn is smaller than R8 or the size of the argument is zero, the
             * argument will be passed in memory.
             *
             * If the current argument is passed in memory, stop the procedure: All subsequent arguments
             * will also be passed in memory.
             * If there are arguments left, goto 1. and proceed with the next argument.
             *
             * Return values with a size of 1 byte up to and including a size of 8 bytes will be returned
             * in registers. Return values whose size is outside that range will be returned in memory.
             * If a return value cannot be returned in registers, the caller will allocate stack space and
             * pass the address as implicit first pointer argument to the callee. The callee will put the
             * return value into the space provided by the caller.
             *
             * If the return value of a function is returned in registers, the same registers are used as
             * if the value was the first parameter of a non-varargs function. For example, an 8-bit value is returned in R24 and an 32-bit value is returned R22...R25.
             * Arguments of varargs functions are passed on the stack. This applies even to the named arguments.
             */
            ccr.LowLevelDetails(1, 2);

            if (dtRet != null && dtRet != VoidType.Instance)
            {
                GenerateReturnValue(dtRet, ccr);
            }

            int iReg = 26;

            foreach (var dtParam in dtParams)
            {
                int size = dtParam.Size;
                if ((size & 1) != 0) // odd sized register occupies two regs
                {
                    // Round size to even # of bytes.
                    size = dtParam.Size + 1;
                }
                iReg -= size;
                if (iReg >= 8)
                {
                    var reg = argRegs[iReg - 8];
                    if (dtParam.Size == 1)
                    {
                        ccr.RegParam(reg);
                        continue;
                    }

                    SequenceStorage seq = null;
                    for (int r = iReg + 1, i = 1; i < dtParam.Size; ++i, ++r)
                    {
                        var regNext = argRegs[r - 8];
                        if (seq != null)
                        {
                            seq = new SequenceStorage(PrimitiveType.CreateWord(regNext.DataType.BitSize + seq.DataType.BitSize), regNext, seq);
                        }
                        else
                        {
                            seq = new SequenceStorage(PrimitiveType.CreateWord(regNext.DataType.BitSize + reg.DataType.BitSize), regNext, reg);
                        }
                    }
                    ccr.SequenceParam(seq);
                }
                else
                {
                    ccr.StackParam(dtParam);
                }
            }
        }
Example #4
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();
                    }
                }
            }
 public void Setup()
 {
     this.arch = new RiscVArchitecture(new ServiceContainer(), "riscV");
     this.cc   = new RiscVCallingConvention(arch);
     this.ccr  = new CallingConventionEmitter();
 }
Example #6
0
 public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams)
 {
     throw new NotImplementedException();
 }
Example #7
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;
                }
            }
        }
Example #8
0
 public void Generate(ICallingConventionEmitter ccr, DataType?dtRet, DataType?dtThis, List <DataType> dtParams)
 {
     //$TODO: finding it hard to locate information about the calling
     // convention on PowerPC Win32. May have to reverse engineer it.
 }
 private void Given_CallingConvention()
 {
     this.cc  = new Arm32CallingConvention(arch);
     this.ccr = new CallingConventionEmitter();
 }
Example #10
0
        public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams)
        {
            ccr.LowLevelDetails(arch.WordWidth.Size, 0x10);

            if (dtRet != null)
            {
                SetReturnRegister(ccr, dtRet);
            }

            int  ir = 0;
            bool firstArgIntegral = false;

            for (int i = 0; i < dtParams.Count; ++i)
            {
                var dtParam = dtParams[i];
                var prim    = dtParam as PrimitiveType;
                if (prim != null && prim.Domain == Domain.Real && !firstArgIntegral)
                {
                    if ((ir % 2) != 0)
                    {
                        ++ir;
                    }
                    if (ir >= fregs.Length)
                    {
                        ccr.StackParam(dtParam);
                    }
                    else
                    {
                        if (prim.Size == 4)
                        {
                            ccr.RegParam(fregs[ir]);
                            ir += 1;
                        }
                        else if (prim.Size == 8)
                        {
                            ccr.SequenceParam(fregs[ir], fregs[ir + 1]);
                            ir += 2;
                        }
                        else
                        {
                            throw new NotSupportedException(string.Format("Real type of size {0} not supported.", prim.Size));
                        }
                    }
                }
                else
                {
                    if (ir == 0)
                    {
                        firstArgIntegral = true;
                    }
                    if (dtParam.Size <= 4)
                    {
                        if (ir >= 4)
                        {
                            ccr.StackParam(dtParam);
                        }
                        else
                        {
                            ccr.RegParam(iregs[ir]);
                            ++ir;
                        }
                    }
                    else if (dtParam.Size <= 8)
                    {
                        if ((ir & 1) != 0)
                        {
                            ++ir;
                        }
                        if (ir >= 4)
                        {
                            ccr.StackParam(dtParam);
                        }
                        else
                        {
                            ccr.SequenceParam(iregs[ir], iregs[ir + 1]);
                            ir += 2;
                        }
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }
                }
            }
        }
 public void Setup()
 {
     this.cc  = new X86_64CallingConvention();
     this.ccr = new CallingConventionEmitter();
 }
Example #12
0
 public void Generate(ICallingConventionEmitter ccr, DataType dtRet, DataType dtThis, List <DataType> dtParams)
 {
     //$TODO: make this happen
 }
Example #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();
                }
            }
        }