Re: [Tack-devel] ACK compiles on NetBSD-macppc, sort of...
Moved to https://github.com/davidgiven/ack
Brought to you by:
dtrg
From: Gregory T. (t. K. <gt...@di...> - 2006-07-23 11:04:11
|
Hi All, (After a brief discussion with David I decided to remain with the list.) I can confirm that ACK builds on NetBSD/macppc. I'm going to do a build on OpenBSD/macppc as soon as possible. If I'm still displaying long lines, I apologize. When I do word/line wrapping it comes out badly on other email clients that automatically handle wrapping. >[...] >> It's occured to me that the em virtual machine needs to be rewritten, too, >> to use an infinite number of registers (as per W. L. Van der Poel's dictum >> referenced in the em documentation). This would make RISC assemblers much >> easier to write and schedule with full consideration of pipelining. > >You may have trouble. em doesn't use registers at all --- it's entirely stack >based. The optimisers can provide register hinting, but it's the backend >itself that does all the register allocation. Yes, I understand this. If instead of em using an infinitely deep stack it used an infinite number of registers for local variables and parameters, I theorize that em's operational outcomes would be the same with only minor changes to the logic. Consider the em output of the count function. One of the steps necessary for the stack based operation was to restore the value of max to the stack each pass, since comparing the current value of i to max consumed both i and max. The ARM code reproduced this behavior, when it should have stuck max into a register and then kept comparing that. I recognize that some of ARM's output comes from the the assembler being coded to a stack instead of registers, but it does hint towards deeper problems getting an assembler to order code efficiently when building line by line. >I suspect that it may be easiest to implement the pipelining system as a >separate stage after code generation; top, the target optimiser, already >features a peephole optimisation system. It may be possible to extend this to >reorder instructions to take account of pipelining. The scheduling in the assembler will have to handle the pipelining, in order to be most accurate. Originally I thought getting pipelining hints from em would be very helpful, but now I realize that it should be treated like a one cycle-one instruction RISC engine and let a global optimizer in the target assembler deal with pipelining. The biggest help would be for em to use registers instead of a stack so that the target assembler could "look ahead" to see how soon the register or branch conditional is needed. It seems to me that looking ahead on a stack based single line code rule structure is difficult. >I also have a nasty feeling that the ACK really, really likes to pass >parameters on the stack, rather than in registers, and I'm not sure if this >can be changed. Certainly, this C code: > >arg0(); >arg1(1); >arg2(1,2); > >...turns into this em code: > >cal $arg0 >loc 1 >cal $arg1 >loc 2 >loc 1 >cal $arg2 > >I don't think the backend knows how many parameters a call takes, and >therefore it doesn't know how many to load into registers... that said, the >ncg manual *does* have an example rule that ensures that top-of-stack always >lives in a register; it might be possible to extend this concept. But it may >not be possible to make ACK code conform to a register-centric ABI without >passing through interface layers. I'll definately take a look at the ncg document. My thought regarding altering em to be register-centric would be along the lines of r0 being reserved, volatile registers be r1 -> r` (where ` stands for infinity), and -r1 -> -r` (negative numbered registers) are non-volatile. If the backend isn't forced to know the number of parameters (which are passed in volatile registers), this would leave open a path for function overloading. The particular function gets tied after the message tokens are delivered. Functions that call additional functions save its local variables to non-volatile registers, which are always restored before returning from a function call (by the called function). Always assume the volatile registers are destroyed after a function call and the non-volatile registers are intact. Non-volatile registers are saved to a stack and restored from it, just like in the real world. The assembler would then be responsible for tying the virtual registers to real ones. It might be necessary to define "real" registers for stack pointer, link register, count register, and perhaps a few others, but that's not difficult. tim Gregory T. (tim) Kelly Owner Dialectronics.com P.O. Box 606 Newberry, SC 29108 "Anything war can do, peace can do better." -- Bishop Desmond Tutu |