r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[rebcode] Rebcode discussion

BrianH
29-Oct-2005
[1015x2]
How would you do it, like this?

cmp.i: ["Sets a variable to -1,0,1 if two values are <,=,>" word! 
word! | integer! word! | integer!]

cmp.d: ["Sets a variable to -1,0,1 if two values are <,=,>" word! 
word! | decimal! word! | decimal!]
; And then use it like this:
cmp.i t a b
brab [leq lgt] t
; Less than
label leq
; Equal
label lgt
; Greater than
Volker
29-Oct-2005
[1017x2]
No, i thought about a branch with 3 targets. misunderstanding, not 
cmp then.
sub left-elem right-elem
bra3 to-lesser to-higher left-elem
; here they are same
BrianH
29-Oct-2005
[1019]
Well, brab has three targets in the example above: 0, 1 and default.
Volker
29-Oct-2005
[1020x2]
yes, but bra3 has -infinite..-1, 0, 1..infinite
which is supported by cpu-flagwords.
BrianH
29-Oct-2005
[1022x2]
Then you are thinking like this?

cmp.i: ["Do one of three blocks based on if two values are <,=,>" 
word! | integer! word! | integer! block! block! block!]

cmp.d: ["Do one of three blocks based on if two values are <,=,>" 
word! | decimal! word! | decimal! block! block! block!]
; And then use it like this:
cmp.i a b [
    ; Less than
] [
    ; Equal
] [
    ; Greater than
]
Volker
29-Oct-2005
[1024]
something like this. But imho it does to much. and it should work 
with gotos, is it possible to jump out of a blick?
BrianH
29-Oct-2005
[1025]
No. That is why I prefer my first suggestion.
Volker
29-Oct-2005
[1026x2]
that would be slower.
the typical thing is that you really subtract (or compare) and follow 
that by two conditional branches. no lookup like with brab needed.
BrianH
29-Oct-2005
[1028]
Not much slower, really. If you specify a literal branch target block, 
both my suggestions would be translated to the same machine code 
by a JIT.
Volker
29-Oct-2005
[1029x4]
next s1 next s2
seti char s1  sub char s2
bra3 to-equal to-higher
; we are lesser here
label to-eqaul
next s1 next s2 ; check length..
bra loop
label to-higher ; we are higher here
It was you who claimed a little extra add is to slow.
The jit has to realize that your compare results in -1, 0, 1, that 
you add 1, and then that you brab. Possible, but needs more insights.
which bloats jit.
BrianH
29-Oct-2005
[1033]
That would require a 3-valued comparison flag to be set inside the 
interpreter. Right now there is only a true/false flag.
Volker
29-Oct-2005
[1034]
No, the bra3 takes a variable with the result of a 'sub. with jit 
that is a very small peephole, easy to detect.
BrianH
29-Oct-2005
[1035x2]
A JIT would know that a cmp would only set t to -1, 0 or 1, and then 
know what to translate a following brab on it to.
Your example bra3 there didn't act that way - the result of a sub 
isn't referenced. Do you want to fix your example?
Volker
29-Oct-2005
[1037x2]
You cant do a brab on a -1.
So you have to track three statements. And to give always that order 
or the jit needs to look even deeper.
BrianH
29-Oct-2005
[1039]
Sure you can, it'll just treat it as a deafult and move on to the 
next instruction without branching.
Volker
29-Oct-2005
[1040x3]
right, i forgot that.
which involves another thing, a range-check. not with smart jit, 
but with interpreter.
my solution is simply simpler IMHO.
BrianH
29-Oct-2005
[1043x2]
But what does it do? This?

bras: ["Branches based on the sign of a value" word! | integer! word! 
| integer! word!]
; Used like this:
sub a b
bras lneg lpos a
; a = 0
label lneg
; a < 0
label lpos
; a > 0
Volker
29-Oct-2005
[1045]
yes.
BrianH
29-Oct-2005
[1046]
That would be faster.
Volker
29-Oct-2005
[1047x4]
but i guess 0 should not be default. probability for one of the others 
is higher, 0 be the last check.
or? when comparing strings, 0 is the most probable results, for all 
chars except list. makes a good default.
list -> last
with binary search it is not.
BrianH
29-Oct-2005
[1051]
The only advantage to a cmp/brab is that you would need only one 
branch added. This would really be:

bras.i: ["Branches based on the sign of a value" word! | integer! 
word! | integer! word!]

bras.d: ["Branches based on the sign of a value" word! | decimal! 
word! | decimal! word!]
Volker
29-Oct-2005
[1052]
the advantage is that brab does a lot of work under the hood.
BrianH
29-Oct-2005
[1053]
Also, if you just had a general CMP, you might be able to compare 
strings too. That may be too high-level for rebcode though.
Volker
29-Oct-2005
[1054x2]
My suggestion is exactly to compare strings fast.
and a general compare is as heavy as a bras. and makes most sense 
with a brab immediate following IMHO.
BrianH
29-Oct-2005
[1056x2]
Sorry, I forgot that the integer above was an offset. Ignore bras.i/bras.d
So, string (series?) CMP (perform integer or decimal CMP with SUB), 
plus BRAS that takes integer or decimal:

cmp: ["Sets a variable to -1,0,1 if two values are <,=,>" word! word! 
| any-string! word | any-string!]

bras: ["Branches based on the sign of a value" word! | integer! word! 
| integer! word!]
Volker
29-Oct-2005
[1058]
i do not know if we really need cmp, because you can just store the 
result of sub. but could be cleaner. i agree.
BrianH
29-Oct-2005
[1059]
You can't sub a string. That's why I added the CMP above. Less than 
or greater than doesn't make sense for blocks.
Volker
29-Oct-2005
[1060x2]
Ah, get it. i thought compare takes two chars, and we have to loop. 
as a loop returning -1,0,1 it makes sense.
but i am not sure about this special case. sometimes i want to know 
where the difference occoured  and such things. So i prefer a selfmade 
loop, with rebcode. Except it turns out string-comparisons are very 
common.
BrianH
29-Oct-2005
[1062]
If you expect the comparison to be common, why not make a subroutine 
and apply it or compose it in when needed? Not everything has to 
be an opcode, and the difference will be slight after the JIT is 
implemented.
Volker
29-Oct-2005
[1063x2]
because it is common in small loops: string-comparison, binary search. 
adds overhead in interpreter. is hard to detect for jit (its jit, 
not a heavy global optimizer).
the jit sees two comparisons and two branches. needs smartness to 
detect that this two comparisons can be folded in one because of 
cpu-flagword.