public void Generate(ICallingConventionEmitter ccr, DataType?dtRet, DataType?dtThis, List <DataType> dtParams) { ccr.LowLevelDetails(stackAlignment, retAddressOnStack); SetReturnStorage(ccr, dtRet, stackAlignment); if (dtThis != null) { ccr.ImplicitThisStack(dtThis); } if (reverseArguments) { for (int i = dtParams.Count - 1; i >= 0; --i) { ccr.StackParam(dtParams[i]); } ccr.ReverseParameters(); } else { for (int i = 0; i < dtParams.Count; ++i) { ccr.StackParam(dtParams[i]); } } if (callerCleanup) { ccr.CallerCleanup(retAddressOnStack); } else { ccr.CalleeCleanup(); } }
public void Generate(ICallingConventionEmitter ccr, DataType?dtRet, DataType?dtThis, List <DataType> dtParams) { ccr.LowLevelDetails(stackAlignment, retSizeOnStack); ccr.CallerCleanup(retSizeOnStack); int iReg = 0; if (dtThis != null) { ccr.ImplicitThisRegister(iArgs[iReg++]); } foreach (var dtParam in dtParams) { if (iReg < iArgs.Length) { ccr.RegParam(iArgs[iReg++]); } else { ccr.StackParam(dtParam); } } if (dtRet != null) { ccr.RegReturn(Registers.eax); } }
public void Generate(ICallingConventionEmitter ccr, DataType?dtRet, DataType?dtThis, List <DataType> dtParams) { ccr.LowLevelDetails(4, 4); if (dtRet != null) { if (dtRet is PrimitiveType pt && pt.Domain == Domain.Real) { ccr.RegReturn(fp0); } if (dtRet.BitSize > 64) { 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(arch.PointerType.Size, 0x0008); if (dtRet != null) { SetReturnRegister(ccr, dtRet); } int fr = 0; int ir = 0; // The SysV calling convention specifies that there is no // "reserved slot" prior to the return address on the stack, in // contrast with Windows where 4*8 bytes are allocated for // space for the four registers foreach (var dtParam in dtParams) { var prim = dtParam as PrimitiveType; if (prim != null && prim.Domain == Domain.Real) { if (fr >= fregs.Length) { ccr.StackParam(dtParam); } else { ccr.RegParam(fregs[fr]); ++fr; } } else if (dtParam.Size <= 8) { if (ir >= iregs.Length) { ccr.StackParam(dtParam); } else { ccr.RegParam(iregs[ir]); ++ir; } } else { int regsNeeded = (dtParam.Size + 7) / 8; if (regsNeeded > 4 || ir + regsNeeded >= iregs.Length) { ccr.StackParam(dtParam); } else { throw new NotImplementedException(); } } } ccr.CallerCleanup(arch.PointerType.Size); }
public void Generate(ICallingConventionEmitter ccr, DataType?dtRet, DataType?dtThis, List <DataType> dtParams) { ccr.LowLevelDetails(8, 0x0028); if (dtRet != null) { if (dtRet.Size > 8) { throw new NotImplementedException(); } var pt = dtRet as PrimitiveType; if (pt != null && pt.Domain == Domain.Real) { ccr.RegReturn(Registers.xmm0); } else if (dtRet.Size <= 1) { ccr.RegReturn(Registers.al); } else if (dtRet.Size <= 2) { ccr.RegReturn(Registers.ax); } else if (dtRet.Size <= 4) { ccr.RegReturn(Registers.eax); } else { ccr.RegReturn(Registers.rax); } } for (int i = 0; i < dtParams.Count; ++i) { var dt = dtParams[i]; if (dt.Size > 8) { throw new NotImplementedException(); } var pt = dt as PrimitiveType; if (pt != null && pt.Domain == Domain.Real && i < fRegs.Length) { ccr.RegParam(fRegs[i]); } else if (i < iRegs.Length) { ccr.RegParam(iRegs[i]); } else { ccr.StackParam(dt); } } ccr.CallerCleanup(8); }
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) { ccr.LowLevelDetails(2, 2); if (dtRet != null) { SetReturnRegisters(ccr, dtRet); } int gr = 0; for (int iArg = 0; iArg < dtParams.Count; ++iArg) { var arg = arch.GetRegister("r" + gr) !; ++gr; ccr.RegParam(arg); } ccr.CallerCleanup(arch.PointerType.Size); }
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); }