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")); } }
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)); } }
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); }
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]); }
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; } }
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."); } }
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); } } }
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); }
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."); } }
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 SetReturnRegisters(ICallingConventionEmitter ccr, DataType dtRet) { ccr.RegReturn(arch.GetRegister("r0")); }
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(); } } }
// 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; } } }