RetroForum Welcome, Guest. Please login or register.
September 07, 2010, 05:51:00 AM
Home Help Search Calendar Login Register

RetroForth Discussion  |  Older Boards  |  Development  |  Topic: Making sense of conditionals « previous next »
Pages: 1 Go Down Print
Author Topic: Making sense of conditionals  (Read 2313 times)
Chuck Adams
Contributor
Jr. Member
***

Karma: +0/-0
Offline Offline

Posts: 24


View Profile
Making sense of conditionals
« on: November 12, 2005, 06:16:17 PM »

I'm puzzled by the weird logic in the conditional words that looks reversed for some and looks like the "wrong" ops for others.

Code:
: (if) $063b 2, $adad 2, 1, here 0 1, ;

First off, I can't really figure out what that's doing, which probably explains my confusion for the next words.

[code]
: <>if $74 x: (if) ;
Logged
Chuck Adams
Contributor
Jr. Member
***

Karma: +0/-0
Offline Offline

Posts: 24


View Profile
Re: Making sense of conditionals
« Reply #1 on: November 12, 2005, 06:31:34 PM »

Also, these appear to be the short jump forms of the conditionals, which I understand have problems with longer words where the branch target is too far away ... I looked in reva and it was using the long forms (basically adding $10 to each and prepending a $of byte).  I remember this coming up a while back, and am wondering if the compiler somehow backpatches conditionals if the branch target is too far removed?

Just want to figure out the basics first tho Smiley
Logged
Charles Childers
Administrator
Sr. Member
*****

Karma: +2/-0
Offline Offline

Posts: 745


View Profile WWW
Re: Making sense of conditionals
« Reply #2 on: November 12, 2005, 06:56:55 PM »

Quote
: (if) $063b 2, $adad 2, 1, here 0 1, ;

First off, I can't really figure out what that's doing, which probably explains my confusion for the next words.

This compiles the following code into the definition:

Code:
cmp eax, [esi]
lodsd   ; drop
lodsd   ; drop

This is followed by the conditional jump opcode (passed on the stack.) The here 0 1, leaves the address of the jump offset on the stack and allocates space for it. then will replace the contents of the offset with the correct value.

Basically, it's just a factored out word shared by the common conditionals.

Quote
: <if  $7e x: (if) ;       : >if  $7d x: (if) ;

This is what confuses me.  $7E is JLE and $7D is JGE.  Not reversed, so I must assume it's subtracting them in the reverse order I was thinking.  I sort of figured this out while writing this.  But what I don't really get then is why it's JLE/JGE and not JL/JG? 

Here's an example of why this was done:

Code:
: foo <if ." true" cr ;then ." false" cr ;
1 2 foo
2 1 foo
1 1 foo

Compare the results with these (using JL/JG):

Code:
macro
: <if $7c x: (if) ;
: >if $7f x: (if) ;
forth
: foo <if ." true" cr ;then ." false" cr ;
1 2 foo
2 1 foo
1 1 foo

For 1 1 foo it should display false since 1 is obviously not less than itself.

Quote
: ?if  $72 1, here 0 1, ; 

$72 is JC, makes perfect sense.  Again the here 0 1, construct ... I don't quite understand.

As before, this inlines to:

Code:
jc <offset>

The address (here) is passed on the stack to then to fix up.

Quote
: then dup here swap - 1- swap c! $90 1, ;

if is perfectly straightforward, and more asm in then.
I kind of lack the ASM debugging skill to see how it works .. consequence of being a perl/python/lisp hacker for so long.  I know most of the inlined asm is documented somewhere here...

then has the job of patching up the offsets provided by the various conditionals. It determines the current address in the heap, then the difference between the two. I don't recall exactly why the 1- was needed offhand. I'll check up on that again. The assembly $90 1, compiles in a nop at the then point to make sure that tail call elimination is handled properly (forces a compile of a ret instruction if no calls follow the then). It's easily the most complex word in the conditionals.

Quote
could it perhaps be merged into some comments in core.f?

Would including the assembly listings in the glossary file be enough? I'm quite willing to do that.
Logged
Charles Childers
Administrator
Sr. Member
*****

Karma: +2/-0
Offline Offline

Posts: 745


View Profile WWW
Re: Making sense of conditionals
« Reply #3 on: November 12, 2005, 07:02:30 PM »

Quote
Also, these appear to be the short jump forms of the conditionals, which I understand have problems with longer words where the branch target is too far away ...

True. If the difference is more than 127 bytes, it won't work. I am considering switching to the long form in 8.3, but haven't made up my mind yet.  (I've never run into a problem with the short forms, but I have seen code written for other forths that would have problems if run in RetroForth). (the 127 bytes is enough for about 25 words CALLed words or 14 numbers. Inlining makes this harder to estimate accurately)

The other option that I see is to have the optimizer library compile replace the original conditionals with "intelligent" ones. Compiling a long form by default, and changing to short forms (padded with nop's) if possible.
Logged
Chuck Adams
Contributor
Jr. Member
***

Karma: +0/-0
Offline Offline

Posts: 24


View Profile
Re: Making sense of conditionals
« Reply #4 on: November 12, 2005, 08:01:13 PM »

Aha, it makes sense now ..
Logged
Charles Childers
Administrator
Sr. Member
*****

Karma: +2/-0
Offline Offline

Posts: 745


View Profile WWW
Re: Making sense of conditionals
« Reply #5 on: November 12, 2005, 10:44:54 PM »

Rx (and therefore 8.3) now have the longer jumps in the conditionals. The code is:

Code:
: (if) $063b 2, $adad 2, 2, here 0 , ;
: <>if $840f x: (if) ;
: =if  $850f x: (if) ;
: <if  $8e0f x: (if) ;
: >if  $8d0f x: (if) ;
: if   0 x: literal x: <>if ;
: then dup here swap - 4 - swap ! $90 1, ;
: ;then x: ;; x: then ;
: if; x: if x: ;then ;

Later I'll see if having the optimizer convert to the short form actually has any impact on overall performance.
Logged
Pages: 1 Go Up Print 
RetroForth Discussion  |  Older Boards  |  Development  |  Topic: Making sense of conditionals « previous next »
Jump to:  


Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1 RC2 | SMF © 2001-2005, Lewis Media Valid XHTML 1.0! Valid CSS!