Shop OBEX P1 Docs P2 Docs Learn Events
Alternative "rep" syntax? - Page 2 — Parallax Forums

Alternative "rep" syntax?

2

Comments

  • jmgjmg Posts: 15,171
    edited 2015-10-19 02:49
    cgracey wrote: »
    ...... The @ could become some other character for this use case.

    My personal preference is to have no special char prefixes on any labels, when used as labels (aka code destinations), as that is what every other assembler I use does.

    I know the old P1 assembler was different, but it is not hard to support the wider use, and deprecate the older form - Older code can be supported with a Assembler switch,

    Removing label prefixes also allows Assemblers like gas, yasm et al ( & Maybe PNUT?) to segment check for illegal destinations.
    Coding in (some) ASM on P2 is going to be common, so safety nets matter.

  • potatoheadpotatohead Posts: 10,261
    edited 2015-10-19 03:14
    It's a backward reference label. Every other label is a forward reference label. That is what is special about it.

    The "exit" bit was just misunderstanding.

    As for hard edits, every other label works in the same way, meaning people are generally going to put them on the same line as the target, and or operate with the forward reference assumption. (which isn't an entirely safe assumption)

    Would be nice to make sure an unambiguous use were permitted though. (label on line) Guess I'll be using line count and indent.

    No worries. If it remains backward reference, people will ask why, and I'm perfectly happy to explain all of it to them.

    :P

    Edit: Just saw this on Peter's Tachyon thread:
    	rep	@.L0,tos1
    	wfbyte	tos
    .L0    	jmp	#DROP3
    
    

    I'm NOT happy. That's a backward reference. Every other reference is a forward one. Not cool.
  • jmgjmg Posts: 15,171
    potatohead wrote: »
    Edit: Just saw this on Peter's Tachyon thread:
    	rep	@.L0,tos1
    	wfbyte	tos
    .L0    	jmp	#DROP3
    
    

    I'm happy. That's a best practice being demonstrated. As long as we can do that, I'm good on the rest of it.

    That's exactly what I've been trying to say, if you are happy now, that's great :)


  • potatoheadpotatohead Posts: 10,261
    edited 2015-10-19 03:14
    (scratch that)

    See? I misread that one, why?

    Because every other freaking label is a forward reference and now we have a backwards one.

    Not happy, and I'll edit the above.





  • jmgjmg Posts: 15,171
    edited 2015-10-19 03:51
    potatohead wrote: »
    Actually, you didn't.

    Your examples had the label AFTER the code they reference, and on a line by themselves too. Both of which complicate how Propeller labels behave.

    ?? read them more carefully.
    To me, Peter's code is fine, exactly as I expected from Chip's comments.

    As too, is this code-style alternative - identical binary.
    	rep	@.L0,tos1
    	wfbyte	tos
    .L0    	
            jmp	#DROP3
    
  • potatoheadpotatohead Posts: 10,261
    edited 2015-10-19 03:18
    We are behind one another in edits.

    Yeah, your post right above mine sucks. It's a backward reference. Literally every other label in Propeller land is a forward reference. And to make things worse, the best practice is to not put labels on a line by themselves in assembly land. Why? For this exact reason. But, if labels are allowed on a line by themselves, they all need to behave the same way. Now they don't.

    Guess I'll call those the jmg labels. I'll bookmark this for later. It's stupid. A lot of P1 users will misread these.
  • jmgjmg Posts: 15,171
    edited 2015-10-19 03:51
    I'm still not following, nothing is 'backwards'

    This is all the same code to any Assembler
    	rep	@.L0,tos1
    	wfbyte	tos
    .L0    	jmp	#DROP3
    
    	rep	@.L0,tos1
    	wfbyte	tos
    .L0    	
            jmp	#DROP3
    
    	rep	@.L0,tos1
    	wfbyte	tos
    ' Comment can go here 
    .L0   ' Comment can go here 
    'Comment can go here   	
            jmp	#DROP3
    
  • jmgjmg Posts: 15,171
    potatohead wrote: »
    Because every other freaking label is a forward reference and now we have a backwards one.

    I'm lost, how is it backwards ? - it is just a label.

    The assembler takes the code the user has written, and creates the binary needed for the opcode.
    Chip has this working fine now.

    Peter coded fine, and I can read his intent exactly.

  • potatoheadpotatohead Posts: 10,261
    edited 2015-10-19 03:35
    No it's not actually.

    The first one is a forward reference in that the label references the next eligible item. It being on the same line makes that unambiguous, and that idea goes way back in assembly land. I learned about it all in the early 80's. And in a packed code listing, that forward reference idea is the only idea that makes any sense. Who wants to think about a label referencing the line above? It's confusing, which is why it's not done the very vast majority of the time.

    The second one, given an assembler that treats labels as a forward reference, will include jmp in the rep loop. But, we've now carved out an exception to label handling. So this label would reference the thing preceding it. And that's not necessarily "any assembler" at all. Maybe some you have used, but I'll bet a cookie they are filled with a bunch of other difficult to think about stuff.

    Principle of least surprise here too:

    [Here is how labels work. simple forward reference rule]

    Student: Ok, so it's the next thing. Got it. Cool. Next. (that's literally all they need to know)

    [example of rep shown]

    Student: But why is that one backward?

    [but see? It's easy to read...]

    Student: But it doesn't work the same. Can't I just always put a label on a line and know it will work every single time?

    [discussion on sadly, no because....]

    Now there is a more complicated discussion on references, the concept of a block, etc... And the end result really doesn't add any more value, and will actually confuse existing PASM users, who until now could operate with a simple, global forward reference rule.

    The third one is a cluster**** and isn't really worth any discussion, save to say it's technically no different than the second one, due to comments being transparent.

    As for "any assembler" the P1 tools would get those label references wrong, as would the P2 tools, because the standard in Propeller land is to always forward reference labels. Now it's that, except for this thing.

  • I almost always put labels on lines by themselves. To me it is easier to edit and since i've been doing it so long, it reads correctly. Currently, my P2 code is a mess of begged, borrowed, stolen and patched up stuff. Once i'm back in rhythm it should look better.

    Historically, I do it because of punched cards. It's much easier to edit card decks if your label is on its own card.

    The current implementation makes sense to me so far as i've used it.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-10-19 03:37
    Hmmmm, what's the problem? I didn't see any problem in coding and it didn't confuse me either. In all assembly I've ever done that I jump to a label then that label is not the instruction itself, just the address of the instruction, it still has to be executed. So if I rep to a label then it's to an address, not an "instruction". Labels only resolve to addresses, not instructions.
  • potatoheadpotatohead Posts: 10,261
    edited 2015-10-19 03:41
    And! There is more.

    Chip mentioned two modes, reading and writing and the possibility of a label that moves! That's even worse! Now stuff isn't where a person puts it, and we now have to talk about modes and states...

    By contrast, the simple forward reference label rule takes about two seconds, and the person is done with understanding labels, until they are ready for local labels, which they will be after writing a little code filled with loop1, loop2, etc... or they want to make pre-written snippets, etc... And if they learn that rule and apply it, they get it right nearly all the time with about zero effort.

    Except for rep. See how that all works?

    The bizarre thing is I agree with you on a label case, and I agree in that it avoids line counting too. All good.

    Hosing up labels wasn't worth that though. It's not worth it, because the most obvious use, that will occur to people when they learn about labels is the one people actually can't use because one of us thought a backward reference was a good idea for one case.




  • jmgjmg Posts: 15,171
    potatohead wrote: »
    Who wants to think about a label referencing the line above?

    None of the assemblers I use do that, and I have no idea why you think this somehow happens here.
    potatohead wrote: »
    The second one, given an assembler that treats labels as a forward reference, will include jmp in the rep loop.
    ?? Why do you imagine that ??
    It is the same code as Peter's which does not include JMP in the rep loop.

    The address of the label in the MAP file is identical in both cases.

    LOTS of P1 code uses labels on their own lines, some uses same-line labels. Adding CrLf does not break any code.
  • TorTor Posts: 2,010
    edited 2015-10-19 03:43
    I'm not sure what the problem really is. To me there is only one sane way for labels to behave:
    label    instr
             next_instr   
    
    *must* behave the same as
    label    
             instr
             next_instr
    
    As for forward/backward, I don't think it's right to think about two kinds of labels. REP is a bit special as far as instructions go, but I don't see any problem understanding the code, *if* the label behaves as above. Which, if I have not misunderstood, is what jmg wants.

  • jmgjmg Posts: 15,171
    mindrobots wrote: »
    I almost always put labels on lines by themselves. To me it is easier to edit and since i've been doing it so long, it reads correctly.

    Yup, I tend to place major branch labels on their own lines, (often with a comment) and sometimes I'll place local short labels, on the same line as an ASM statement.

    HLL generated code tends to use own-line-labels.
    HLL example 1
    	jmp	#.L2
    .L6
    	shl	r6, #1
    	mov	r7, CNT
    	or	r6, r1
    	add	r7, r0
    .L5
    

    HLL example 2
                      add           __temp2,par                 
    __L0004                                                     
                      rdbyte        __temp3, __temp2 WZ         
                      wrbyte        __temp3, __temp1            
                      add           __temp1,#1                  
                      add           __temp2,#1                  
        IF_NZ         jmp           #__L0004                    
    
                      mov           __temp1,par                  
    
    
  • potatoheadpotatohead Posts: 10,261
    edited 2015-10-19 03:55
    Well, maybe this helps to understand where the friction is.

    $0000 nop
    $0004 label 'forward reference rule applied. A backward reference would be label address $0000
    $0004 add

    As far as I can recall, I've not seen any PASM anywhere that references the thing before the address of a label. (programmer can make expression for that, if they want) It's always the thing AT or CONTAINED in the address assigned to the label, which in text, visual form, is the forward reference rule.

    Rep will use the address before, and I suppose this is just like the count from 0 inherent in the rep instruction. Both are similar ambiguities. It's the only thing that uses the address before the label, as it stands right now too.

    If I perform a jmp to label above, I land on the add instruction. It's contained in the memory at address $0004. If I do a rep targeting the label above, I get the nop instruction as the end of the loop, which is not contained by the memory at the address assigned to the label.

    Every other label use will reference the add, except for REP.

    In very simple terms, if I want to reference something except for REP as it stands now, I can apply the same rule. Put that thing and it's label on the same line and it's gonna work. Seems to me the best case is to keep that rule consistent. Which means labeling the end of the loop, not the thing after the end of the loop.

    Doing that makes as much sense as counting the number of instructions to loop from 0. And the goal of it all was to make more sense.

    Seems to me, one "doesn't make sense" was seen as a potential source of ambiguity, and rightfully so, only to be replaced with another one.

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-10-19 03:55
    Put it this way. END goes at the END, not before the end.

    END: still working!

    -OR -
    done what I need to do
    END

    REP is only concerned about an END as it may never get there anyway in an infinite loop.
  • jmgjmg Posts: 15,171
    edited 2015-10-19 04:06
    potatohead wrote: »
    Rep will use the address before,
    So your confusion is only for the REP opcode ?

    Users do not care what the binary level opcode is, and REP simply and clearly uses the label as the place it goes when done.

    Implicit in that is that yes, rep includes the line above that label in the loop, the label is an exit location, which is what labels commonly are.
    Destinations to jump to.

    There is nothing special in the REP label use here, unless you expect REP to operate differently.
    potatohead wrote: »
    Every other label use will reference the add, except for REP.

    Nope, REP also references the add just fine, but treats it as a destination when done, the add is not included inside the REP loop, as it comes after the Label.
  • potatoheadpotatohead Posts: 10,261
    edited 2015-10-19 04:38
    (scratch the other comments. Rep is just going to be odd)

    @jmg, in every one of those examples, the label address contains the item following the text of the label in the assembly file. In fact, that's the case for everything but REP.

    Oh well. We've got much better things to do.

    Seriously. "exit location" or "when REP is done, you will be here" both will work to resolve the question, and that's better than "jmg label" :) I'll take it, but I don't like it. Seems like we didn't have this issue with REP on the "hot" design pass...

    Re: Labels on individual lines. Yes! Given the behavior is consistent, it's all good. I suppose I just see REP differently, and that's making the label no-conforming to me. I really do see that as a backward reference, as in the pointer to the last instruction in the REP loop. If one is doing the line count, the count has nothing to do with anything beyond the intended series of instructions for REP to operate on.

    Edit: Yes. that's it exactly.

    It's the difference between:

    "put the label on the instruction you want to execute after REP is done" as opposed to, "put the label on the last instruction in the set to be repeated"

    Another way to think of it, "repeat these" as opposed to "go here after repeating these..."

    I'm good now. Thanks. Most all of you are seeing it as the next thing to do. I really didn't see it that way at all.

    I for sure don't want the label that moves... ugh!

  • potatohead wrote: »
    Oh well. We've got much better things to do.

    Yep, I'm busy doing it and that way you either get used to something, or you like it or you hate it. Either way it shouldn't stop you from doing something. Personally I'm happy with the way REP has turned out, both with the count=count plus the end=end :)

  • jmgjmg Posts: 15,171
    potatohead wrote: »
    I'm good now. Thanks. Most all of you are seeing it as the next thing to do. I really didn't see it that way at all.
    Cool.
    Yes, the label used in REP is the next thing to do, aka the REP-exit location.

  • cgraceycgracey Posts: 14,134
    So, it is okay, as it stands?
  • jmgjmg Posts: 15,171
    Personally I'm happy with the way REP has turned out, both with the count=count plus the end=end :)

    Yes, and the old leading dummy opcode that was not-actually-loop-executed is also gone too, so the new REP is much more user friendly and less error prone. It's a cool opcode :)

    Personally I'd use
    REP LabelWhenDoneName,Count
    and dispense with the @, as a cleaner version, but that's a minor detail.
    0=forever is also nice to have.
    There are test & generate cases where you may want a COG to simply loop-forever with minimal overhead.


  • ElectrodudeElectrodude Posts: 1,653
    edited 2015-10-19 04:56
    Doesn't @ now mean address-of, like it does on the P1, and not offset-to as it did for a time? Or did you not release that version yet? (I don't have an FPGA, so I don't remember what the latest released version is like) What's a REP look like now?
  • potatoheadpotatohead Posts: 10,261
    edited 2015-10-19 05:03
    I'm good. Please don't futz with it on my account Chip. How it is right now works.

    So we have two cases:

    REP [number of instructions to repeat - 1], [number of iterations]


    , and

    REP [@label of instruction executed immediately after operation complete], [number of iterations]


    And I think we need to wordsmith that second case some when we get closer to that stage in the process.

    I got seriously hung up on the idea of the label pointing to the loop instructions directly, rather than it being implied by the one to get executed next. It really did seem like a backward reference, and I really was not OK with that idea at all.

    It's kind of amazing how a perception or expectation difference can alter things! We are very right to hash out syntax, etc... Getting after that is going to pay dividends. I believe that completely, and it's those dividends I want.

    On this one, I was totally experiencing very genuine concern over what appeared to be a matter of genuine ambiguity, and I got snarky. Could not believe no one saw it. --which is always a clue, but one that can be difficult for the one having the struggle to see.

    (which I find humorous after it's all said and done, jmg :) If we can't laugh at ourselves, things get kind of ugly. So, I'm laughing! )

    This: Yes, and the old leading dummy opcode that was not-actually-loop-executed is also gone too

    Totally. That's a P1 thing many have found difficult. Stuffing things into unused "slots" Most common was making the most of the HUB access. Big win here with REP.

  • jmgjmg Posts: 15,171
    cgracey wrote: »
    So, it is okay, as it stands?
    Yup. REP is fine :)
    '@' prefix could be looked at, but that's not urgent.
    If # means (LinesofLongs-1), then LabelName (no @) has no parsing ambiguity ?

  • potatoheadpotatohead Posts: 10,261
    edited 2015-10-19 05:21
    Maybe. One could supply a COG register there too. (D/#) Can't just put label name there, because that means "Destination value sourced in COG register at address of label"
    CCCC 1100110 1LI DDDDDDDDD SSSSSSSSS        REP     D/#,S/#
    

    One could have a short and long rep loop, and specify that difference with a COG register. That seems an odd case though, it might make sense for some kind of self-generating / modifying routine or other, running in a COG for speed. Seems a bit crazy. I'm curious what any of you would have in mind for that use case.

    "REP D/#, S/#" doesn't allow for a label, given "#" is the line count; thus, "@" at present.

    I don't care how we resolve this, or if we do. It's enough to get past the label trouble as far as I'm concerned, but it is an exception to the addressing scheme.



  • Cluso99Cluso99 Posts: 18,069
    I wondered if the operands should have been swapped to
    REP [#]count, [next]/[#instructions-1]

    My reasoning is that the DJNZ counter, next
    and JMPRET returnaddr, next

    In each case, "next" is the next instruction to be executed (ie a goto)
    and the "count/return-address" is the "operation".

    Now, the "next" part of the REP instruction would be the goto address after the loop is done.

  • jmgjmg Posts: 15,171
    Cluso99 wrote: »
    My reasoning is that the DJNZ counter, next
    and JMPRET returnaddr, next

    Yes, either works, easily changed.

  • Cluso99 wrote: »
    I wondered if the operands should have been swapped to
    REP [#]count, [next]/[#instructions-1]

    My reasoning is that the DJNZ counter, next
    and JMPRET returnaddr, next

    In each case, "next" is the next instruction to be executed (ie a goto)
    and the "count/return-address" is the "operation".

    Now, the "next" part of the REP instruction would be the goto address after the loop is done.

    :lol: If you really want to take this further, move REP to the end of the block and have the label refer to the beginning of the block. The assembler can then insert the REP in the proper location (at the beginning) in the compiled code. That way, the REP will look like all of the other branch instructions and the label discussion will be moot.
Sign In or Register to comment.