Hello list,
I have a question that is probably silly, but I couldn't find anything on the internet that answered it exactly. I am looking at a register machine version of Squeak, and one thought I had to make the number of operations per method even less was that the send opcode would put the location that the result should be stored into a variable in the new active context. My question was, in some cases I would like this to be a literal hardware, but is that even possible? Do all register names have to already be in code or can a memory location refer to a register and the CPU use it (e.g. x86store_op [some memory location that points to a register] ; double indirection)? Thanks, Jason PC Magazine’s 2007 editors’ choice for best web mail—award-winning Windows Live Hotmail. Check it out! _______________________________________________ Exupery mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery |
On 24/07/07, J J <[hidden email]> wrote:
> > Hello list, > > I have a question that is probably silly, but I couldn't find anything on > the internet that answered it exactly. > > I am looking at a register machine version of Squeak, and one thought I had > to make the number of operations per method even less was that the send > opcode would put the location that the result should be stored into a > variable in the new active context. > > My question was, in some cases I would like this to be a literal hardware, > but is that even possible? Do all register names have to already be in code > or can a memory location refer to a register and the CPU use it (e.g. > x86store_op [some memory location that points to a register] ; double > indirection)? #result register. this simply reduces a stack operations by a half maybe. as i understood, you want to do similar by telling a send oop, where to store a result. well, you may point to stack index, or point to address of memory with given stack index. but i'm unsure, is stack in squeak are subject for GC relocations. if so, then better use index rather than pointers. > > Thanks, > Jason > > ________________________________ > PC Magazine's 2007 editors' choice for best web mail—award-winning Windows > Live Hotmail. Check it out! > _______________________________________________ > Exupery mailing list > [hidden email] > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery > > -- Best regards, Igor Stasenko AKA sig. _______________________________________________ Exupery mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery |
In reply to this post by J J-6
> Date: Tue, 24 Jul 2007 20:37:12 +0300
> From: [hidden email] > To: [hidden email] > Subject: Re: Dynamically choosing a register > > as i understood, you want to do similar by telling a send oop, where > to store a result. > well, you may point to stack index, or point to address of memory with > given stack index. > but i'm unsure, is stack in squeak are subject for GC relocations. if > so, then better use index rather than pointers. Ok, I sent this mail in a rush because I didn't want to still be on the train when it left my station, so I figured it wouldn't end up making sense. :) What I mean is, right now MethodConext's have various fields in them (BlockContexts as well, but they point to MethodContexts for most information). What I was thinking of doing was adding an addition field "returnLocation". This way the compiler can simply ensure the value that is to be returned stores it's value to that area directly. Example (I means instance variable location, O means Object for the general purpose registers, S is a special and L is the literal frame): center ^ origin + corner / 2 might be translated to: send2 #+ I1 I2 O1 ; Send the message #+ with the first instance slot as the receiver (first object) and the second instance slot as the argument. Store results in GP register O1 send2 #/ O1 S(2) RET ; Send #/ with O1 as the receiver and the special number 2 as the argument. store the result into what ever place *our caller* expects it to be stored ret ; Destroy this context and reactivate the previous one So note above that when the receiver in O1 receives the #/ message the RET field in *his* activation context will be the same as *ours (i.e. center's)*. So when he stores the answer we don't have to do anything, as it is in the right place already. The complexity comes from the fact that RET might be an instance variable, a temp variable location, a GP register *or* it may be an actual hardware register. But I'm not sure if that's even doable without making self-modifying code, which lead to my question: Can I have some value that I pass around dynamically that "points" to a hardware register? I can easily have a special encoding that says "the 3rd general purpose hardware register" or even the literal x86 value that maps to e.g. "eax", but how would one use this value at runtime? C, et al don't have this problem because the compiler explicitly states what values are going into which registers at build time. I have never heard of passing around a register "address". Of course I could do something like (note: the following pseudo code is intended to be a low level lisp-like language that compiles directly to machine code): (def store-to-register (reg val) (cond (reg) ((number-that-means-eax) (store eax val) ..... But if it's going to be the expensive I may as well just store into memory. I was hoping I could do something like (example in pseudo assembly this time): movRegAt %ebx, $val ; the ebx register somehow has a reference to another register and stores $val there instead of ebx or memory or anywhere else. I suppose, since I have to have different functions for each addressing mode anyway, I can just have the routine that detects the type overwrite the register in the register store routine directly every time. :) Hopefully that makes a little more sense. :) Thanks, Jason Don't get caught with egg on your face. Play Chicktionary! _______________________________________________ Exupery mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery |
On 25/07/07, J J <[hidden email]> wrote:
> > > Date: Tue, 24 Jul 2007 20:37:12 +0300 > > From: [hidden email] > > To: [hidden email] > > Subject: Re: Dynamically choosing a register > > > > as i understood, you want to do similar by telling a send oop, where > > to store a result. > > well, you may point to stack index, or point to address of memory with > > given stack index. > > but i'm unsure, is stack in squeak are subject for GC relocations. if > > so, then better use index rather than pointers. > > Ok, I sent this mail in a rush because I didn't want to still be on the > train when it left my station, so I figured it wouldn't end up making sense. > :) > > What I mean is, right now MethodConext's have various fields in them > (BlockContexts as well, but they point to MethodContexts for most > information). What I was thinking of doing was adding an addition field > "returnLocation". This way the compiler can simply ensure the value that is > to be returned stores it's value to that area directly. > > Example (I means instance variable location, O means Object for the general > purpose registers, S is a special and L is the literal frame): > > center > ^ origin + corner / 2 > > might be translated to: > > send2 #+ I1 I2 O1 ; Send the message #+ with the first instance slot > as the receiver (first object) and the second instance slot as the argument. > Store results in GP register O1 > send2 #/ O1 S(2) RET ; Send #/ with O1 as the receiver and the special > number 2 as the argument. store the result into what ever place *our > caller* expects it to be stored > ret ; Destroy this context > and reactivate the previous one > Assuming that any message always puts evaluation result into this register (not stack) we have: push I1 (origin) push I2 (corner) send #+ push #result (after message sent, we have result in #result register) push S(2) send #/ ret (after #/ message sent, we have result in #result register, since its already there, all we need is just return) same as yours, but not caring about letting message know, where to store result, because messages always store it in same register (#result). It can be a simple global memory location or, if you insist, it can be always an eax register on x86 architecture :) > So note above that when the receiver in O1 receives the #/ message the RET > field in *his* activation context will be the same as *ours (i.e. > center's)*. So when he stores the answer we don't have to do anything, as > it is in the right place already. > > The complexity comes from the fact that RET might be an instance variable, a > temp variable location, a GP register *or* it may be an actual hardware > register. But I'm not sure if that's even doable without making > self-modifying code, which lead to my question: Can I have some value that > I pass around dynamically that "points" to a hardware register? > > I can easily have a special encoding that says "the 3rd general purpose > hardware register" or even the literal x86 value that maps to e.g. "eax", > but how would one use this value at runtime? C, et al don't have this > problem because the compiler explicitly states what values are going into > which registers at build time. I have never heard of passing around a > register "address". > > Of course I could do something like (note: the following pseudo code is > intended to be a low level lisp-like language that compiles directly to > machine code): > > (def store-to-register (reg val) > (cond (reg) > ((number-that-means-eax) (store eax val) > ..... > > But if it's going to be the expensive I may as well just store into memory. > I was hoping I could do something like (example in pseudo assembly this > time): > Yes, in this case, you need a self-modifying code, so you need to write something to some memory location, before CPU gets to that code. Then this is not faster than simply writing result to some well known memory location rather than modifying code to store result into particular machine register and executing it. Also, consider that writing to code location invalidates a CPU instruction cache for this location and forces it to reread instructions from memory. > movRegAt %ebx, $val ; the ebx register somehow has a reference to another > register and stores $val there instead of ebx or memory or anywhere else. > > I suppose, since I have to have different functions for each addressing mode > anyway, I can just have the routine that detects the type overwrite the > register in the register store routine directly every time. :) > > Hopefully that makes a little more sense. :) > I see, you want to make bytecode to use as many registers as it can to reduce stack usage, so unary or binary send can be sent using machine registers.. Well, you putting in RET some code , indicating where to store result. What prevents you to translate it like bytecode? You can build a jump table and perform different operations depending of RET code for storing result at pointed place. So, you can divide RET byte in two hexes, lower will indicate an index, higher - place to store. (00 << 4) + x - store result in machine register , x - register index. (01 << 4) + x - store result to ivar of receiver of parent context, x - ivar index .... e.t.c > Thanks, > Jason > > ________________________________ > Don't get caught with egg on your face. Play Chicktionary! > _______________________________________________ > Exupery mailing list > [hidden email] > http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery > > -- Best regards, Igor Stasenko AKA sig. _______________________________________________ Exupery mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery |
In reply to this post by J J-6
Do you mean for the cond to be evaluated at compile time in the following? (def store-to-register (reg val) (cond (reg) ((number-that-means-eax) (store eax val) If so you could just generate: (mov t1 eax) Then the register allocator will try to allocate t1 in eax and remove that move. Bryce _______________________________________________ Exupery mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery |
In reply to this post by J J-6
> From: [hidden email]
> Date: Thu, 26 Jul 2007 11:43:43 +0100 > To: [hidden email] > Subject: RE: Dynamically choosing a register > > > Do you mean for the cond to be evaluated at compile time in the > following? > > (def store-to-register (reg val) > (cond (reg) > ((number-that-means-eax) (store eax val) No, it can't be compile time since val will live in a field in instances of MethodContext. I can't know what val is until runtime. What I really want is a way to store in memory or another register some kind of reference to a register so that I would have the option in my VM that a caller can request the answer put right into the literal register of his choice. > If so you could just generate: > (mov t1 eax) > > Then the register allocator will try to allocate t1 in eax > and remove that move. > > Bryce Is there any documentation on your mid and low level code generator? I would like to make a lisp-like language that targets it. This way I wouldn't have to make a compiler for every processor type, but I would have full power of the CPU and no dependencies on C. See what you’re getting into…before you go there. Check it out! _______________________________________________ Exupery mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery |
On Thu, 26 Jul 2007 20:24:06 +0200, J J wrote:
> >> From: [hidden email]> Date: Thu, 26 Jul 2007 11:43:43 +0100> >> To: [hidden email]> Subject: RE: Dynamically >> choosing a register> > > Do you mean for the cond to be evaluated at >> compile time in the> following?> > (def store-to-register (reg >> val)> (cond (reg)> ((number-that-means-eax) (store eax val) > No, it can't be compile time since val will live in a field in instances > of MethodContext. I can't know what val is until runtime. What I > really want is a way to store in memory or another register some kind of > reference to a register so that I would have the option in my VM that a > caller can request the answer put right into the literal register of his > choice. If you use some form of the traditional call/return sequence, have the caller reserve a #return slot at a fixed location (offset). There the callee can store its return value (you mentioned a way to store in memory). Then the caller can pop/move the value into any register it likes, dynamically and independent of the callee. Cheers Klaus >> If so you could just generate:> (mov t1 eax)> > Then the register >> allocator will try to allocate t1 in eax> and remove that move.> > >> BryceIs there any documentation on your mid and low level code >> generator? I would like to make a lisp-like language that targets it. >> This way I wouldn't have to make a compiler for every processor type, >> but I would have full power of the CPU and no dependencies on C. > _________________________________________________________________ > See what you’re getting into…before you go there. > http://newlivehotmail.com _______________________________________________ Exupery mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery |
In reply to this post by J J-6
J J writes:
> > > From: [hidden email]> Date: Thu, 26 Jul 2007 11:43:43 +0100> To: [hidden email]> Subject: RE: Dynamically choosing a register> > > Do you mean for the cond to be evaluated at compile time in the> following?> > (def store-to-register (reg val)> (cond (reg)> ((number-that-means-eax) (store eax val)No, it can't be compile time since val will live in a field in instances of MethodContext. I can't know what val is until runtime. What I really want is a way to store in memory or another register some kind of reference to a register so that I would have the option in my VM that a caller can request the answer put right into the literal register of his choice.> If so you could just generate:> (mov t1 eax)> > Then the register allocator will try to allocate t1 in eax> and remove that move.> > BryceIs there any documentation on your mid and low level code generator? I would like to make a lisp-like language that targets it. This way I wouldn't have to make a compiler for every processor type, but I would have full power of the CPU and no dependencies on C. > _________________________________________________________________ The best documentation about Exupery's internals is: http://www.kampjes.demon.co.uk/articles/exuperyDesign.pdf Beyond that you're best looking at the source. If you're planning on running your Lisp inside Squeak then I'd probably subclass and adapt IntermediateSimplifier as it contains useful code to access the object memory. I'd also recommend writing test first using the Mocks provided, the learning curve will be a little steeper initially but testing pays of surprising quickly. Bryce _______________________________________________ Exupery mailing list [hidden email] http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery |
Free forum by Nabble | Edit this page |