⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readme.port

📁 system C源码 一种替代verilog的语言
💻 PORT
字号:
Date: Tue, 11 Jan 94 13:23:11 -0800From: "pardo@cs.washington.edu" <pardo@meitner.cs.washington.edu>>[What's needed to get `qt' on an i860-based machine?]Almost certainly "some assembly required" (pun accepted).To write a cswap port, you need to understand the context switchingmodel.  Turn to figure 2 in the QT TR.  Here's about what the assemblycode looks like to implement that:	qt_cswap:		adjust stack pointer		save callee-save registers on to old's stack		argument register <- old sp		sp <- new sp		(*helper)(args...)		restore callee-save registers from new's stack		unadjust stack pointer		returnOnce more in slow motion:	- `old' thread calls context switch routine (new, a0, a1, h)	- cswap routine saves registers that have useful values	- cswap routine switches to new stack	- cswap routine calls helper function (*h)(old, a0, a1)	- when helper returns, cswap routine restores registers	  that were saved the last time `new' was suspended	- cswap routine returns to whatever `new' routine called the	  context switch routineThere's a few tricks here.  First, how do you start a thread runningfor the very first time?  Answer is: fake some stuff on the stackso it *looks* like it was called from the middle of some routine.When the new thread is restarted, it is treated like any otherthread.  It just so happens that it's never really run before, butyou can't tell that because the saved state makes it look like likeit's been run.  The return pc is set to point at a little stub ofassembly code that loads up registers with the right values andthen calls `only'.Second, I advise you to forget about varargs routines (at leastuntil you get single-arg routines up and running).Third, on most machines `qt_abort' is the same as `qt_cswap' exceptthat it need not save any callee-save registers.Fourth, `qt_cswap' needs to save and restore any floating-pointregisters that are callee-save (see your processor handbook).  Onsome machines, *no* floating-point registers are callee-save, so`qt_cswap' is exactly the same as the integer-only cswap routine.I suggest staring at the MIPS code for a few minutes.  It's "mostly"generic RISC code, so it gets a lot of the flavor across withoutgetting too bogged down in little nitty details.Now for a bit more detail:  The stack is laid out to hold callee-saveregisters.  On many machines, I implemented fp cswap as save fpregs, call integer cswap, and when integer cswap returns (when thethread wakes up again), restore fp regs.For thread startup, I figure out some callee-save registers thatI use to hold parameters to the startup routine (`only').  Whenthe thread is being started it doesn't have any saved registersthat need to be restored, but I go ahead and let the integer contextswitch routine restore some registers then "return" to the stubcode.  The stub code then copies the "callee save" registers toargument registers and calls the startup routine.  That keeps thestub code pretty darn simple.For each machine I need to know the machine's procedure callingconvention before I write a port.  I figure out how many callee-saveregisters are there and allocate enough stack space for thoseregisters.  I also figure out how parameters are passed, since Iwill need to call the helper function.  On most RISC machines, Ijust need to put the old sp in the 0'th arg register and then callindirect through the 3rd arg register; the 1st and 2nd arg registersare already set up correctly.  Likewise, I don't touch the returnvalue register between the helper's return and the context switchroutine's return.I have a bunch of macros set up to do the stack initialization.The easiest way to debug this stuff is to go ahead and write a Croutine to do stack initialization.  Once you're happy with it youcan turn it in to a macro.In general there's a lot of ugly macros, but most of them do simplethings like return constants, etc.  Any time you're looking at itand it looks confusing you just need to remember "this is actuallysimple code, the only tricky thing is calling the helper betweenthe stack switch and the new thread's register restore."You will almost certainly need to write the assembly code fragmentthat starts a thread.  You might be able to do a lot of the contextswitch code with `setjmp' and `longjmp', if they *happen* to havethe "right" implementation.  But getting all the details right (thehelper can return a value to the new thread's cswap routine caller)is probaby trickier than writing code that does the minimum andthus doesn't have any extra instructions (or generality) to causeproblems.I don't know of any ports besides those included with the sourcecode distribution.   If you send me a port I will hapily add it tothe distribution.Let me know as you have questions and/or comments.	;-D on  ( Now *that*'s a switch... )  Pardo

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -