## What's the difference between BRCS,BRCC and BRLO, BRSH commands?

32 posts / 0 new
Author
Message

I see that the actions wchich they're doing are same. Only names are different.

Last Edited: Wed. Jun 22, 2022 - 06:44 PM

Why not keep all these questions in just one topic? You run the risk of annoying people with so many posts.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

Yes,  some opcodes are identical.

Normal human beings would use BRCC instead of BRSH.

Choose BRSH if you are not normal.

Sorry, I'm just trying to figure out all commands of the chip and there're questions appear while i learn. I'll try not to make typical questions anylonger

Because I tried to write an AVR CPU simulator in C one time I did an analysis of the entire range of opcode patterns which, in the process identified the opcodes that were synonyms rather than distinct opcodes. Although most AVR datasheet start with a claim about "132..135 powerful RISC instructions" when you analyse it I think there are just a bit over 70. I posted a whole thread about that and a list of the opcdes and the multiple names for single opcode patterns

Not sure how I'd find that thread again though :-(

Anyway, one of the classics is:

Note the sss pattern in the bottom 8 bits? Clearly 3 bits can encode for 8 different possibilities. The "1111 01" at the top of the opcode is what really identifies this as "branch if bit in SREG is clear".

So

BRCC = 000

BRNE = 001

BRPL = 010

BRVC = 011

BRGE = 100

BRHC = 101

BRTC = 110

BRID = 111

are all the same opcode. They are the 8 possible variants of

BRBC = sss

Then there are another eight "S"et rather than "C"lear branches that are all just different names for the same BRBS opcode. So 18 listed in the manual are really just 2 opcodes. They just chose to give each one's 8 possible variants different names to make it easy to use so you don't have to keep 8 entry binary tables in your head (well they are called "mnemonics" which derives from the  ancient greek "of the memory")

Another example are the CL and SE opcodes. If you look at:

and

Then again we have two opcodes here that can each spawn another 8 opcodes each. So all you CLC, SEI, CLI, SEH etc again are not real opcodes. All the CL? opcodes are just BCLR and all the SE? opcodes are just BSET. So again that is another 18 reduced to two.

And so it goes on. See if you can work out what CLR R17 really is! ;-)

PS I can't believe it but Google found the thread I was thinking of:

https://www.avrfreaks.net/forum/...

and the opcode list that I think is useful from that is in this post:

https://www.avrfreaks.net/commen...

Scroll well down through that post until you reach the bit that starts:

Note any "=" signs in that. They are saying that the opcode(s) that follows is not "real" - it's just another name for the one above.

So, for example there is no LSL, it's really just ADD. No ROL, it's just ADC. No TST, it's just AND. No CLR, it's just EOR (which answers the question I posed at the end of the previous post!).

Further down you see:

as well as:

Last Edited: Wed. Jun 22, 2022 - 03:14 PM

Sorry for multiple posts but I guess David has a point. While

```BRBC 5, foo
...
foo:
...```

and

```BRHC foo
...
foo:
...```

are the same thing no normal human being is going to remember that 5="HC" so BRHC is easier to remember and write and easier for the maintainer to understand what's going on.

So maybe it is valid to have all the different BRSH, BRNE, BRHC, etc. spelled out in full? So perhaps the argument goes that there is no real point listing BRBC as no one would ever use it like that?

Equally I guess it is valid for an author to use:

`CLR r17`

rather than having to use:

`EOR r17, r17`

even though it achieves the same thing? (in the past, on other 8 bit using EOR was recognised as the classic way to clear a register)

I think the thing that many object to are those claims of "132+ opcodes" when some mnemonics code to the same bit patterns.

(it does make writing simulators (and assemblers and disassemblers) a bit easier as you don't have 132 different code paths but just 70+ to be handled)

clawson wrote:
Although most AVR datasheet start with a claim about "132..135 powerful RISC instructions" when you analyse it I think there are just a bit over 70.

There should be a ASM cheat sheet for this kind of stuff, it would be really helpful.

“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?” - Brian W. Kernighan
“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.” - Antoine de Saint-Exupery

Apropos brsh (which is normal for normal people):

Here is how to jump on various r16, if you not mind for values 0 and 1, or more than 3:

andi  r16, 3

cpi   r16, 2

breq  jValue2

brsh  jValue3

Heisen wrote:

There should be a ASM cheat sheet for this kind of stuff, it would be really helpful.

If you search this forum you will find several (many?) threads where this information has been distilled and summarized.

I'm still wondering what Vladimir101 is up to.  At first I thought trolling, but as this thread shows there is indeed follow-up investigation going on.

I think there should be at least a bit more thought about "if I were designing an instruction set, these are the primitives that I would need for the variety of possible signed and unsigned comparisons.  And the primitives I need for sighed and unsigned and mixed arithmetic, including multi-byte arguments."

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Why do you need a list of redundant commands? They don't make your code bigger or slow it down. They DO help with readability because they show what you really are trying to do. Those all add up to no cost, which is at least some benefit. Isn't that what most of us are after?

Jim

Until Black Lives Matter, we do not have "All Lives Matter"!

Last Edited: Thu. Jun 23, 2022 - 12:02 AM

(But it's FUNNY how some vendors will include such aliases to make their instruction set look "more complete" and other vendors will explicitly omit them to make their instruction set look "simpler" (or "more RISC")
"NOP" on older RISC processors was something like "mov r6,r6."
TI's MSP430 documentation is very explicit about "basic instructions" and "emulated instructions."

One has to pay attention to things like the status flags - on some chips, "dec" will decrement a value without setting any flags, or only setting the Zero flag.  But if it's a synonym for "sub r, #1", it's likely to set ALL the flags (carry, overflow, etc.)

To some extent, having aliases at the core level is due to having a less developed assembly language ecosystem.  In the old days, you might see only the core instructions documented, but everyone would be expected to do "#include <coreMacros.h>" (or similar) to get the more convenient and understandable aliases.

(I'm not really enthusiastic about "bset r,b" being an alias for "ori r, 1<<b", but having to use "brbc 1,xx" instead of "brne xx" would be annoying.)

My point is: as long as all of the operations supported by the assembler are listed somewhere, what difference does it make that some are aliases? Sure, it matters for the (dis)assembler writer but for we mere mortals, does it really make any difference that BRSH and BRCC are the same op code? Nothing is gained with that knowledge and you would not write your assembly program any differently, I hope!

Jim

Until Black Lives Matter, we do not have "All Lives Matter"!

Jim is right; the presence of aliases is entirely a matter for the assembly code writer. It might be simpler - clearer - to deal with a 'greater than' in some cases, and to explicitly look at the state of the carry flag in others.

Working with assembly is both precise and confusing - it is *much* easier to write spaghetti code in assembly than almost any other option and it is very easy to have unexpected and unwanted side effects. But with alias instructions you have the ability to choose the more semantically relevant instruction in your source code, *even though* that instruction is an alias. This makes life simpler for you at a later date, and for any other reviewer of your code.

You should also note that things differ between processors and processor families. Cliff's example of ROL being the same instruction as ADD may be true for the AVR, but on other processors (e.g. most things from Intel since 1974) they are different instructions which merely happen to be implemented the same way internally - you don't need shift left logic in the ALU, because you can add something to itself. One might of course ask why the ROL instruction is implemented at all... I suspect the answer is 'because there's a hole in the instruction set without it'.

Neil

it is *much* easier to write spaghetti code in assembly than almost any other option

You just need a fancier package of assembly macros.  Like https://github.com/WestfW/struct...

```   cpi r16, 'a'
_if e
call sub_for_a
_elseif <cpi r16, 'b'>, e
call sub_for_b
_elseif <cpi r16, 'c'>, e
call sub_for_c
_else
_endif```

Not that I'm sure it's useful in the real world.  I mean, I used a similar package back in my mainframe assembler days, but it was more widely standardized.

Using a "strange" macro package, even if it provides "structure", is just likely to annoy anyone else who looks at your code. :-(

barnacle wrote:
what difference does it make that some are aliases?
Nothing really if it weren't for:

The question is whether there really are 131 or is this just marketing hype? It possibly leads the reader to believe that, for example, CLR and EOR must be different operations and leads to confusion when they find the encoded bit patterns are actually the same. There's possibly even more confusion when using disassemblers. The user writes "CLR r17" then disassembles the code only to find that they've apparently got "EOR r17,r17" etc. For example it seems Studio favours CLR over EOR in fact:

from:

barnacle wrote:
they are different instructions which merely happen to be implemented the same way internally
Doesn't that strike anyone as odd - a bit like trying to squeeze a lot of components on to a packed PCB the design of CPUs is about making the most efficient use of the smallest area of silicon possible (ultimately chips are costed according to their silicon area). Having avoidable duplication then just seems a little bit mad - their might have been room for that extra LDIR (my second favourite Z80 opcode!) on there or something !

There are 131 instructions but a smaller number of opcodes.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

Heisen wrote:

clawson wrote:

Although most AVR datasheet start with a claim about "132..135 powerful RISC instructions" when you analyse it I think there are just a bit over 70.

There should be a ASM cheat sheet for this kind of stuff, it would be really helpful.

Many of the links are gathered here:

https://www.avrfreaks.net/commen...

(indeed, Jeremy Brandon's list -- I'd forgotten that)

sparrow2 wrote:
If an instruction is an alias then the instruction manual will tell you that.(under the upcode).

Other times from the past (might be included in the links in the above):

https://www.avrfreaks.net/forum/...

https://www.avrfreaks.net/forum/...

Let's think about the birth of the AVR, a "new" processor.  Gotta have an assembler for the new beast.  Let's name the op codes.  "Hmmm--our target market contains x51 and x86 and Moto and etc. experts -- better make the nomenclature that they recognize/expect."

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

clawson wrote:

barnacle wrote:

they are different instructions which merely happen to be implemented the same way internally

Doesn't that strike anyone as odd - a bit like trying to squeeze a lot of components on to a packed PCB the design of CPUs is about making the most efficient use of the smallest area of silicon possible (ultimately chips are costed according to their silicon area). Having avoidable duplication then just seems a little bit mad - their might have been room for that extra LDIR (my second favourite Z80 opcode!) on there or something !

It's hard to tell from fifty years, but my understanding is that the 8080 was a 'logical development' of the 8008 which was itself intended to match an existing discrete minicomputer - basically the 8080 was largely source code compatible with the 8008 but not opcode compatible. (I may have got things mixed around there!)

I suspect that the original instruction set included those shift-left and right instructions (there are two in each direction and the difference is whether the rotation is *past* the carry or *through* it - eight bit rotates vs nine bits. They're incorporated in the ALU and left-shifts are implemented as ADC instructions but there's no way to implement the right shifts without dedicated hardware - essentially an extra buffer and a single-bit multiplexor. So they're matching an external requirement - the opcode - with reduced internal hardware. Which is nice, because their biggest problem was getting the die small enough to have a usable yield on the wafer.

Equally, there are loads of mov a,a mov b,b etc instructions which could be implemented as NOPs but instead use the same selection mechanisms as the other mov instructions - so presumably it was simpler in terms of the logic to do it that way.

Neil

barnacle wrote:
8008 which was itself intended to match an existing discrete minicomputer

Not an 8-bit one, but INTEL 4004 was the first to do computing.

don't forget:

The Motorola MC14500B is a single chip, one-bit static CMOS processor optimized for decision-oriented tasks. The processor is housed jn a 16-pin package and features 16-four-bit instructions. The instructions perform logical operations on data appearing on a one-bit bidirectional data line and data in a one-bit accumulating Result Register within the lCU. All operations are performed at the bit level.

http://www.bitsavers.org/compone...

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Thu. Jun 23, 2022 - 08:15 PM

I can remember Intel making a presentation on the, then, brand new 4004 before a packed auditorium of Tektronix engineers. Wikipedia says that was in 1971 and that the IC cost \$60USD. At that point, Tek was using some bit-slice (TTL?) ALUs in what were relatively (for the time) smart terminals. These terminals used Tek-made flat screen CRTs and were "optimized" for various computer languages of the time. I don't remember whether or not Tek actually used the 4004.

One such language, APL maybe, used a large set of somewhat bizarre symbols not found on any normal typewriter or TTY terminal. What was effectively a small mini-computer in the terminal managed character display and communications, as i recall.

At that time, there was not yet any real standardization on word size, either. I suspect that the 8008 went a long ways toward standardizing thinking in terms of multiples of 8-bit bytes.

Jim

Until Black Lives Matter, we do not have "All Lives Matter"!

it is *much* easier to write spaghetti code in assembly

Thatza why I love ASM.......try to write any pasta code in any other language.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

david.prentice wrote:

Yes,  some opcodes are identical.

Normal human beings would use BRCC instead of BRSH.

Choose BRSH if you are not normal.

I might use BRSH if I'm comparing 2 unsigned values to make the intent clear. (The Motorola 68k had similar pairs of equivalent conditional branch instructions, e.g., BCC/BHS which are analogous to AVR's BRCC/BRSH.)

js wrote:

it is *much* easier to write spaghetti code in assembly

Thatza why I love ASM.......try to write any pasta code in any other language.

It's easy to write lasagna code in C++... layers and layers of pasta.

grohote wrote:

barnacle wrote:
8008 which was itself intended to match an existing discrete minicomputer

Not an 8-bit one, but INTEL 4004 was the first to do computing.

Yes, but the 4004 doesn't have any relationship to the 8008 or 8080 other than being made by the same company. The 8008 name was - I think - chosen to capitalise on the 4004, but the 4004 was designed to be a calculator core, not a general purpose processor (though of course, with sufficient memory and time, any Turing complete processor can simulate/emulate any other...)

Neil

barnacle wrote:
4004 doesn't have any relationship to the 8008 or 8080

To young AVRFreaks: all these chips were rather current-consuming, up to 200mA... without PowerDown option... without Program memory, without Memory/EE ...  without any I/O, ADC/Timers/Clocks... but they were the first.

grohote wrote:
To young AVRFreaks:

Good to hear, I might be the youngest active user here, at 27 years old.

“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?” - Brian W. Kernighan
“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.” - Antoine de Saint-Exupery

Just take a step back and look what the branch instructions do.

There are 16 branch combinations

That is branch on any bit in SREG is set or cleared.

So all branch instructions are covered with the BRBC and BRBS instruction. the rest is extra to just to make it more readable.

It's the same as all the 16 instructions that set or clear a bit in SREG is covered with the BSET and BCLR instructions.

About the CLR instruction one need to know which instruction it's a macro/alias for.

If I want to clear R17 there are different ways to do that, and they will have different side effects:

LDI R17,0 no flags are changed (if you have a zero register then a MOV R17,ZERO will do the same (also work for low registers))

EOR R17,R17  the flags Z N V and S cleared

SUB R17,R17 also H and C is cleared

they all take the same time and have the same instruction size.

Edit Z should be set.

Last Edited: Fri. Jun 24, 2022 - 11:20 AM

sparrow2 wrote:
EOR R17,R17  the flags Z N V and S cleared

From the instruction set:

So Z is set not cleared.

sparrow2 wrote:
MOV R17,ZERO

Half of my projects does have ro (rONE), it is also very handy. I also tried rff in some projects.

We are talking about assembler projects, of course. C-lovers can just imagine any benefits.

Last Edited: Fri. Jun 24, 2022 - 11:10 AM