EmbeddedRelated.com
Forums

Assembler BIS instruction and register indirect as destination - can't assemble this line of code

Started by David Feldman August 7, 2012
I am doing some programmed bit-serial I/O using MSP430 assembly language and would like to improve execution speed. My target device is MSP430G2553.

My code includes a number of source lines all very similar (but obviously not identical) to this:

bis.b #4, &P2OUT ; Original code
bis.b #4, &P2OUT ; Original code
bis.b #4, &P2OUT ; Original code
bis.b #4, &P2OUT ; Original code

As CPU cycles are very valuable in this part of my code, I tried replacing &P2OUT with an indirect register reference.

I tried this as an example:

mov.b P2OUT, R12 ; Put the address of P2OUT into a register
bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles

and the MSP430 FET assembler gives me this error message:

Error[0]: Invalid syntax (file name) (line number)

Is there a different way to express the failing line above so that I can use R12 as short-hand to reach P2OUT?

Thanks very much,

Dave

Beginning Microcontrollers with the MSP430

(re-posting to fix minor typos)

I am doing some programmed bit-serial I/O using MSP430 assembly language and would like to improve execution speed. My target device is MSP430G2553.

My code includes a number of source lines all very similar (but obviously not identical) to this:

bis.b #4, &P2OUT ; Original code
bis.b #4, &P2OUT ; Original code
bis.b #4, &P2OUT ; Original code
bis.b #4, &P2OUT ; Original code

As CPU cycles are very valuable in this part of my code, I tried replacing &P2OUT with an indirect register reference.

I tried this as an example:

mov.b #P2OUT, R12 ; Put the address of P2OUT into a register
bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles

and the MSP430 FET assembler gives me this error message -->on the lines containing the bis.b #4, @R12 instruction<--

Error[0]: Invalid syntax (file name) (line number)

Is there a different way to express the failing line above so that I can use R12 as short-hand to reach P2OUT?

Thanks very much,

Dave
You can not use the @R12 as the destination address.
Use 0(R12) instead.

Blakely

--- In m..., David Feldman wrote:
> (re-posting to fix minor typos)
>
> I am doing some programmed bit-serial I/O using MSP430 assembly language and would like to improve execution speed. My target device is MSP430G2553.
>
> My code includes a number of source lines all very similar (but obviously not identical) to this:
>
> bis.b #4, &P2OUT ; Original code
> bis.b #4, &P2OUT ; Original code
> bis.b #4, &P2OUT ; Original code
> bis.b #4, &P2OUT ; Original code
>
> As CPU cycles are very valuable in this part of my code, I tried replacing &P2OUT with an indirect register reference.
>
> I tried this as an example:
>
> mov.b #P2OUT, R12 ; Put the address of P2OUT into a register
> bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
> bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
> bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
> bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
>
> and the MSP430 FET assembler gives me this error message -->on the lines containing the bis.b #4, @R12 instruction<--
>
> Error[0]: Invalid syntax (file name) (line number)
>
> Is there a different way to express the failing line above so that I can use R12 as short-hand to reach P2OUT?
>
> Thanks very much,
>
> Dave
>

On Tue, 7 Aug 2012 14:10:43 -0700 (PDT), you wrote:

>(re-posting to fix minor typos)
>
>I am doing some programmed bit-serial I/O using MSP430 assembly language and would like to improve execution speed. My target device is MSP430G2553.
>
>My code includes a number of source lines all very similar (but obviously not identical) to this:
>
>bis.b #4, &P2OUT ; Original code
>bis.b #4, &P2OUT ; Original code
>bis.b #4, &P2OUT ; Original code
>bis.b #4, &P2OUT ; Original code
>
>As CPU cycles are very valuable in this part of my code, I tried replacing &P2OUT with an indirect register reference.
>
>I tried this as an example:
>
>mov.b #P2OUT, R12 ; Put the address of P2OUT into a register
>bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
>bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
>bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
>bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
>
>and the MSP430 FET assembler gives me this error message -->on the lines containing the bis.b #4, @R12 instruction<--
>
>Error[0]: Invalid syntax (file name) (line number)
>
>Is there a different way to express the failing line above so that I can use R12 as short-hand to reach P2OUT?
>
>Thanks very much,
>
>Dave

Read this link of mine:
http://www.infinitefactors.org/jonk/msp430.html
Look for "Appendix" then read down.

The MSP430, terribly sadly to my mind, sacrified addressing
modes in order to get 16 registers. In the case of two
operand instructions, they have 2 bits for source operand and
1 bit for destination. Your source value is #4. Which is
fine. This gets coded as mode 2, register R2. But your
destination mode doesn't exist (it does, in source mode.) You
only have two destination modes -- register direct and
register offset indirect (and two special cases, only one of
which you should ever use -- absolute indirect. the other is
the constant 1 -- which you shouldn't ever use.)

You are hosed.

Jon
On Tue, 07 Aug 2012 14:39:57 -0700, you wrote:

>You are hosed.

By this I mean you are stuck adding a word of 0, which costs
cycle time.

Jon
On 07/08/2012 23:10, David Feldman wrote:
>
> (re-posting to fix minor typos)
>
> I am doing some programmed bit-serial I/O using MSP430 assembly language
> and would like to improve execution speed. My target device is MSP430G2553.
>
> My code includes a number of source lines all very similar (but
> obviously not identical) to this:
>
> bis.b #4, &P2OUT ; Original code
> bis.b #4, &P2OUT ; Original code
> bis.b #4, &P2OUT ; Original code
> bis.b #4, &P2OUT ; Original code
>
> As CPU cycles are very valuable in this part of my code, I tried
> replacing &P2OUT with an indirect register reference.
>
> I tried this as an example:
>
> mov.b #P2OUT, R12 ; Put the address of P2OUT into a register
> bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
> bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
> bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
> bis.b #4, @R12 ; Now use register-indirect, with idea to save CPU cycles
>
> and the MSP430 FET assembler gives me this error message -->on the lines
> containing the bis.b #4, @R12 instruction<--
>
> Error[0]: Invalid syntax (file name) (line number)
>
> Is there a different way to express the failing line above so that I can
> use R12 as short-hand to reach P2OUT?
>
> Thanks very much,
>
> Dave

As Jon said, I don't think you will be able to save any cycles this way.

However, if your original code contains constants other than #4, you
might be able to save time by putting the constant into a register. The
msp430 has special addressing modes to generate constants 0, 1, 2, 8 and
-1 quickly - but other constants are fastest from a register.

On Wed, 08 Aug 2012 08:30:17 +0200, David wrote:

>As Jon said, I don't think you will be able to save any cycles this way.

Probably not.

>However, if your original code contains constants other than #4, you
>might be able to save time by putting the constant into a register. The
>msp430 has special addressing modes to generate constants 0, 1, 2, 8 and
>-1 quickly - but other constants are fastest from a register.

As you sugggest, the constant generator is just as fast as a
register. So there is nothing to actually speed up code which
already uses the constant generator values, given what was
done to this instruction set design by its (misguided)
designers.

As you also say, consuming a register would be faster than
having an immediate mode constant used inline. But this
brings up another interesting point. Dave (Feldman) is using
the constant #4. He's also using the MSP430G2553. If he now
takes a look at the errata sheet for it:

http://www.ti.com/lit/er/slaz075/slaz075.pdf

He would see that it possesses the CPU4 bug. (TI NEVER FIXES
AN ERRATA and won't fix them on newer processor designs,
either, it seems.) The CPU4 bug means that the constants +4
and +8 DON'T WORK!!! So the assembler nicely, and without any
warning, stuffs the constant inline.

So. Your point is even BETTER than you may have imagined,
David. Dave Feldman might actually be able to improve the
response by using that register you just mentioned.

... TI's willingness to propagate the CPU4 bug forever almost
annoys me as much as the misguided German instruction set
designers did. But not quite as much.

Jon
On Wed, 08 Aug 2012 00:30:20 -0700, I wrote:

>

>He would see that it possesses the CPU4 bug. (TI NEVER FIXES
>AN ERRATA and won't fix them on newer processor designs,
>either, it seems.) The CPU4 bug means that the constants +4
>and +8 DON'T WORK!!! So the assembler nicely, and without any
>warning, stuffs the constant inline.
>
>So. Your point is even BETTER than you may have imagined,
>David. Dave Feldman might actually be able to improve the
>response by using that register you just mentioned.

>

Shucks. It is definitely too late at night for me! This
affects the PUSH (which I ran into some time back.) But not
the BIS or BIC, so far as I'm aware. My mistake!! So there is
nothing to be done about cycles in this case. Oh, well.

Jon
On 08/08/2012 09:33, Jon Kirwan wrote:
> On Wed, 08 Aug 2012 00:30:20 -0700, I wrote:
>
> > >He would see that it possesses the CPU4 bug. (TI NEVER FIXES
> >AN ERRATA and won't fix them on newer processor designs,
> >either, it seems.) The CPU4 bug means that the constants +4
> >and +8 DON'T WORK!!! So the assembler nicely, and without any
> >warning, stuffs the constant inline.
> >
> >So. Your point is even BETTER than you may have imagined,
> >David. Dave Feldman might actually be able to improve the
> >response by using that register you just mentioned.
>
> > Shucks. It is definitely too late at night for me! This
> affects the PUSH (which I ran into some time back.) But not
> the BIS or BIC, so far as I'm aware. My mistake!! So there is
> nothing to be done about cycles in this case. Oh, well.
>

That's what I thought (and your web page confirms it - that's a nice
feature summary for the msp430).

As for the CPU4 bug, I can imagine that if TI /did/ fix it, it could
cause plenty of confusion as to which chips can use the constant
generator for push #4 and push #8, and which can't. Since all tools
take the issue into account, the only cost of the bug is an extra word
and an extra couple of cycles on the rare occasion when this instruction
could be used. Is fixing it worth the effort needed by tool vendors
adding extra flags and code (since the workaround will still be needed
for existing devices), and worth the effort needed by developers (who
need to use the extra compiler/assembler flags, and need to track which
chips can safely use the instructions)? I think not.

It might have made sense to fix it for the newer cores, given that there
are other significant changes there (20-bit support). But not for the
existing cores.

What TI /should/ do is change the documentation - it's not a bug, it's a
"previously undocumented feature". Simply change the documentation for
the constant generator addressing mode to make it clear which
instructions and address mode combinations are valid.

Of course, it would make sense for TI to fix the hardware too. But I
think it is perfectly reasonable to make a working push #4 and push #8
into an undocumented feature. That would give the least chance of
errors if someone accidentally used the instructions, while giving the
least chance of problems caused by tools generating the instructions on
code for existing devices. After all, reducing the chance of errors is
vastly more important than allowing a tiny speed increase in rare
circumstances.

On Wed, 08 Aug 2012 10:39:10 +0200, you wrote:

>On 08/08/2012 09:33, Jon Kirwan wrote:
>> On Wed, 08 Aug 2012 00:30:20 -0700, I wrote:
>>
>> >
>>
>> >He would see that it possesses the CPU4 bug. (TI NEVER FIXES
>> >AN ERRATA and won't fix them on newer processor designs,
>> >either, it seems.) The CPU4 bug means that the constants +4
>> >and +8 DON'T WORK!!! So the assembler nicely, and without any
>> >warning, stuffs the constant inline.
>> >
>> >So. Your point is even BETTER than you may have imagined,
>> >David. Dave Feldman might actually be able to improve the
>> >response by using that register you just mentioned.
>>
>> >
>>
>> Shucks. It is definitely too late at night for me! This
>> affects the PUSH (which I ran into some time back.) But not
>> the BIS or BIC, so far as I'm aware. My mistake!! So there is
>> nothing to be done about cycles in this case. Oh, well.
>>That's what I thought (and your web page confirms it - that's a nice
>feature summary for the msp430).

Thanks. I wrote it within a few months of first seeing the
MSP430, I think. Quite a long time ago, now. First
impressions and all that.

>As for the CPU4 bug, I can imagine that if TI /did/ fix it, it could
>cause plenty of confusion as to which chips can use the constant
>generator for push #4 and push #8, and which can't.
>

Every other company DOES fix them. Mostly. Intel -- yes.
Microchip -- yes. Energy Micro -- yes. And so on.

It's not as though the idea is novel with me, David. People
do fix things. And other people get used to that, too, and
know where to look (the errata.) In fact, that is why you go
to the errata. To see if your stepping has certain bugs. If
it is NEVER fixed, then it is a feature and it should be
documented in the Family Manual, permanently and forever. But
TI chooses not to fix things, but to keep them in the errata
anyway. Weird. Actually, I don't know of another company that
doesn't ever fix this kind of errata (that TI doesn't own in
some way.)

TI does fix errata that would mean they couldn't sell chips
at all. But then, who wouldn't?

I see TI as standing unique, here. My other experience with
other companies has consistently been otherwise.

Anyway, per your point -- IT IS HANDLED IN THE DARNED
ASSEMBLER for gosh sake. Since it knows what chip you are
working on... guess what? It can pick and choose and generate
appropriately. It's doing that kind of thing now.

I really don't think there is any justifiable barrier here.

Jon