bra #label 'relative branch
jmp #label 'absolute branch
I think having a separate opcode name for relative / absolute branches would make the difference a little clearer, and it would also simplify the assembler syntax for tools that need to parse it. It might also save some headaches for those porting self-modifying code over from the P1 -- modifying the source field of a jmp instruction is probably a bad idea if the jmp is relative!
bra #label 'relative branch
jmp #label 'absolute branch
Smarter still, is to drag PASM into 2017+ and support what just about every other assembler does.... No hash on label names.
Hash usually means immediate/absolute value, so somewhat contradicts a RJMP, not not mention adds 'char chaff clutter'.
bra #label 'relative branch
jmp #label 'absolute branch
Smarter still, is to drag PASM into 2017+ and support what just about every other assembler does.... No hash on label names.
Hash usually means immediate/absolute value, so somewhat contradicts a RJMP, not not mention adds 'char chaff clutter'.
Usually RJMPs have more limited reach, and you do not want to be editing code just because you added lines....
Actually I've grown to like the way hashes are done in PASM; at least it's consistent (jmp #label jumps to the label, jmp label uses the contents of label, just like any other instruction). But that's a slightly different can of worms from the one I was opening .
Also, for PASM the "smallest form" issue doesn't really apply since the whole address space can be reached in one instruction. So we just need "absolute jump" and "relative jump" instruction forms. I think making them different instruction mnemonics rather than marking them on the operand makes it easier to read.
We have been over this how many times? The hash on jmp is correct and consistent with how the chip works.
A P2 is a memory to memory design in the COG, not a load, store design.
I'm in favor of BRA to differentiate relative jumps, and would prefer it to the slash.
I am opposed to removing the hash, because it would then be inconsistent with every other use, which we have been through a bunch of times already.
The PC is not directly addressable on a Prop, and people just have to understand that. Once they do, it makes a ton of sense, as will how COG addressing works compared to hub addressing.
This isn't an assembler problem. It is all due to the Prop being fundamentally different from most everything else out there.
The way it works now is super simple. Use a hash when you want the number contained in the instruction to be the operand. Don't use one when you want the number contained in the instruction to be the address in memory containing the operand.
The minute that is understood, jmp #target makes perfect sense.
It's address as value moved to the PC, which it should be for non indirect jumps, either relative or absolute.
Adding BRA as a relative jmp helps to clarify absolute vs relative. I like that a lot.
Because the P2, like P1 is a memory to memory design, not a load store one, most instructions will not need hashes. It's contents of to contents of.
The way it works now is super simple. Use a hash when you want the number contained in the instruction to be the operand. Don't use one when you want the number contained in the instruction to be the address in memory containing the operand.
The minute that is understood, jmp #target makes perfect sense.
It's address as value moved to the PC, which it should be for non indirect jumps, either relative or absolute.
Adding BRA as a relative jmp helps to clarify absolute vs relative. I like that a lot.
Please don't remove the # and change the meaning of @. I don't think I could handle another change in syntax. OK, I probably could handle it, but I like the syntax the way it is now.
Please don't remove the # and change the meaning of @. I don't think I could handle another change in syntax. OK, I probably could handle it, but I like the syntax the way it is now.
I agree. I don't think PASM should go the way of @ for indirection. I was simply pointing out that other assemblers use that notation. Like Eric, I've gotten used to the # notation and it makes perfect sense.
I think making them different instruction mnemonics rather than marking them on the operand makes it easier to read.
Certainly, reducing char chaff clutter is a good idea. Different mnemonics is a common solution.
Here are are some quick google examples of how the rest of the industry, manages label references, in there Assembler Code :
~~~~~~ AVR Assembler ~~~~~~~~~~~~
RCALL Somewhat ; Jump to the label somewhat
[...] here we continue with the program.
Here the jump to the label somewhat somewhere in the program code,
Somewhat: ; this is the jump address
[...] Here we do something, when we are finished and want to jump back to the calling location:
RET
~~~~~~~~ MicroChip Assembler ~~~~~~~~~~~
CALL DELAY
...
DELAY:
~~~~~~~~~~ Intel x86 Assembler ~~~~~~~~~~~~
Here is a simple infinite loop:
top: incl %ecx
jmp top
~~~~~~~~~~ 8051 Assembler ~~~~~~~~~~~~
Loop: inc Reg8 ; increment reg
jmp Loop
~~~~~~~~~~~ STM8 Assembler Example ~~~~~~~~~~~
blink_once
ldw X,#$FFFF
loop_delay
ldw Y,#$0050
loop_inner_delay
decw Y
jrne loop_inner_delay
decw X
jrne loop_delay
bcpl PD_ODR,#0
ret
; main program loop
loop_forever
call blink_once
jra loop_forever
~~~~~~~~~~~ PIC32 Assembler ~~~~~~~~~~~
/* endless loop */
endless:
j endless
nop
Spot what they ALL have in common ?
See the absence of char chaff clutter, and how the common simplest syntax means all can be quickly scanned ?
Seriously, the current syntax makes sense. If it were easy to change it up and make as much sense, it would have happened one of the many times it was discussed.
Of course, you could show us that simple assembler. If it's compelling...
I think most other processors are a bit different from the P2. They can't load programs into their registers and execute them. So the notion of jumping to a register doesn't make sense in a lot of other processors. Running programs loaded in registers, and jumping to registers is the normal mode for the P2. If we use the syntax of "jmp @register" then we need a new way to designate the location of the register in it's hub image.
I like the consistency of the # notation. It has essentially the same meaning as the non-jmp instructions.
I think consistency is a very important factor. Changing the jmp instructions would make things a mess, unless you also changed the non-jmp ones to be consistent. I do not like that idea at all.
I think most other processors are a bit different from the P2. They can't load programs into their registers and execute them. So the notion of jumping to a register doesn't make sense in a lot of other processors. Running programs loaded in registers, and jumping to registers is the normal mode for the P2.
That was true for P1, but not so true anymore for P2, because you can now execute just fine from LUT and HUB - the notion of jumping to a register doesn't make sense there either.
That means on P2, that code labels are simply labels, not always register aliases.
I just wish you'd get a warning if the "#" is missing...
Seems that half my bugs turn out to be a missing #.
I think jmg is right and that direct calls are much more common.
If I were doing this from scratch, definitely drop the #...
Anyway, best if the normal usage is the simplest...
I just wish you'd get a warning if the "#" is missing...
Seems that half my bugs turn out to be a missing #.
I think jmg is right and that direct calls are much more common.
If I were doing this from scratch, definitely drop the #...
Anyway, best if the normal usage is the simplest...
There will still be plenty of cases where it makes sense to run code from cog memory where execution speed is important. Also, there is only one data streamer, so if you want to stream data in or out it has to be done from cog memory. It will be quite common for code executing from hub memory to call routines in cog memory.
Chip has recently done a great job cleaning up Spin2, to cut down the errors dogging even experienced programmers..., and make it easier for those moving to Spin2 from any other language.
I just wish you'd get a warning if the "#" is missing...
Seems that half my bugs turn out to be a missing #.
I think jmg is right and that direct calls are much more common.
If I were doing this from scratch, definitely drop the #...
Anyway, best if the normal usage is the simplest...
Yes, having taken the step to clean up Spin2, it now makes sense to do the same clean up pass for P2ASM....
The fact that sometimes code might land on a Register, is a red herring, it is the most common code usage that should determine best design.( litmus test via numbers : in P2 99.902% of possible landing addresses are NOT registers. If P2 is one quarter full, that is still 99.610%)
In all the assemblers I quoted above, names are always labels, and understood to be destination addresses. No # clutter or confusion.
Indirect usage is relatively rare, and handled a few different ways. Easy enough to pick one compatible with P2.
People just need to take a moment and understand this:
The way it works now is super simple. Use a hash when you want the number contained in the instruction to be the operand. Don't use one when you want the number contained in the instruction to be the address in memory containing the operand.
And that is cake easy! Universal. Anything else gets harder, creates exceptions.
Most common code will be COG code, by a mile. People will write PASM to get at advanced features and we are designing that right in with reserved COG space for it to happen too.
The majority of HUB code will be compiled. And SPIN is being made to help that all along. C will work that way by default.
Many won't need more than PASM snippets, by intent and design, if we get this right.
Those able to and desiring to write HUB code won't have trouble.
I'm done on this topic now. Sheesh.
I really like using BRA for relative and JMP for absolute though. I hope we do it.
Comments
Eric
Smarter still, is to drag PASM into 2017+ and support what just about every other assembler does.... No hash on label names.
Hash usually means immediate/absolute value, so somewhat contradicts a RJMP, not not mention adds 'char chaff clutter'.
Usually RJMPs have more limited reach, and you do not want to be editing code just because you added lines....
Actually I've grown to like the way hashes are done in PASM; at least it's consistent (jmp #label jumps to the label, jmp label uses the contents of label, just like any other instruction). But that's a slightly different can of worms from the one I was opening .
Also, for PASM the "smallest form" issue doesn't really apply since the whole address space can be reached in one instruction. So we just need "absolute jump" and "relative jump" instruction forms. I think making them different instruction mnemonics rather than marking them on the operand makes it easier to read.
Eric
A P2 is a memory to memory design in the COG, not a load, store design.
I'm in favor of BRA to differentiate relative jumps, and would prefer it to the slash.
I am opposed to removing the hash, because it would then be inconsistent with every other use, which we have been through a bunch of times already.
The PC is not directly addressable on a Prop, and people just have to understand that. Once they do, it makes a ton of sense, as will how COG addressing works compared to hub addressing.
This isn't an assembler problem. It is all due to the Prop being fundamentally different from most everything else out there.
Yup, @Reg32 is commonly used, and there is also in use IJMP Reg32 , ICALL Reg32 for Indirect Jump / Calls
The minute that is understood, jmp #target makes perfect sense.
It's address as value moved to the PC, which it should be for non indirect jumps, either relative or absolute.
Adding BRA as a relative jmp helps to clarify absolute vs relative. I like that a lot.
Because the P2, like P1 is a memory to memory design, not a load store one, most instructions will not need hashes. It's contents of to contents of.
So what ?
Nope, quite the straw man argument.
The Prop has two opcodes, just like all other MCUs.
The difference is merely in how the Assembler chooses to present those opcodes to the user.
Thus it is very much an assembler decision / assembler problem.
It is quite simple to craft an assembler that is 'more normal' in operation, and reduces char chaff clutter.
Simple fact:
Indirect calls are less common in Assembler code, than Label-Derived branches.
Certainly, reducing char chaff clutter is a good idea. Different mnemonics is a common solution.
Here are are some quick google examples of how the rest of the industry, manages label references, in there Assembler Code :
Spot what they ALL have in common ?
See the absence of char chaff clutter, and how the common simplest syntax means all can be quickly scanned ?
See how that works jmg?
Seriously, the current syntax makes sense. If it were easy to change it up and make as much sense, it would have happened one of the many times it was discussed.
Of course, you could show us that simple assembler. If it's compelling...
I think consistency is a very important factor. Changing the jmp instructions would make things a mess, unless you also changed the non-jmp ones to be consistent. I do not like that idea at all.
That means on P2, that code labels are simply labels, not always register aliases.
There is also Indirect jump/call form IJMP/ICALL used by others already, if you want to avoid @ symbol.
Your argument is clear jmg. Well done, but this is a "what is worth what?" scenario, and it's evaluated to "not worth it" a ton of times now.
Seems that half my bugs turn out to be a missing #.
I think jmg is right and that direct calls are much more common.
If I were doing this from scratch, definitely drop the #...
Anyway, best if the normal usage is the simplest...
+ 1
Yes it does. And we will see it used regularly too.
We took explicit steps to insure running COG code mixed with HUB code made sense.
Just saying. It's not one model or the other here.
This problem is exactly the point :
Yes, having taken the step to clean up Spin2, it now makes sense to do the same clean up pass for P2ASM....
The fact that sometimes code might land on a Register, is a red herring, it is the most common code usage that should determine best design. ( litmus test via numbers : in P2 99.902% of possible landing addresses are NOT registers. If P2 is one quarter full, that is still 99.610%)
In all the assemblers I quoted above, names are always labels, and understood to be destination addresses. No # clutter or confusion.
Indirect usage is relatively rare, and handled a few different ways. Easy enough to pick one compatible with P2.
People just need to take a moment and understand this:
And that is cake easy! Universal. Anything else gets harder, creates exceptions.
Most common code will be COG code, by a mile. People will write PASM to get at advanced features and we are designing that right in with reserved COG space for it to happen too.
The majority of HUB code will be compiled. And SPIN is being made to help that all along. C will work that way by default.
Many won't need more than PASM snippets, by intent and design, if we get this right.
Those able to and desiring to write HUB code won't have trouble.
I'm done on this topic now. Sheesh.
I really like using BRA for relative and JMP for absolute though. I hope we do it.
I oppose messing with # again.