# arm9e: how do I invert sign of a halfword?

#### Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

•  Subject
• Author
• Posted on
Hi,

suppose I have two 16bit coefficients (c1=0x11, c2=0x22) packed in one
register, r0 = 0x00110022. Now I only want to invert the sign of the
top halfword so that r0 = 0xFFEF0022.

Is there an way to do this?

I guess I can do something like
------------------
qadd16 r1, r0, r0 @r0 *= 2
movt r1, #0
qsub16 r0, r1, r0
------------------
but this looks stupid.

Thanks
syl

Re: arm9e: how do I invert sign of a halfword?

u32 foo = 0x00110022;
u32 bar = (foo ^ 0xFFFF0000) + 0x0001000;

DSP and Mixed Signal Design Consultant
http://www.abvolt.com

Re: arm9e: how do I invert sign of a halfword?

Well, if you change 0x0001000 to 0x00010000, and assume you want
2's complement, and assume that the systems doesn't detect
arithmetic overflows, and that it does wrapping in 2's complement
for such overflows, then it will maybe work.

Meanwhile I suggest you at least annotate your code to describe the
non-standard performance you require.

Oh yes - somebody decide if you are packing 8 bits into 16, or 16
bits into 32.  It will make a difference.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net
We've slightly trimmed the long signature. Click to see the full one.
Re: arm9e: how do I invert sign of a halfword?

Name me an ARM that is ones-complement or implements signed overflow, or
for that matter any CPU in existence. Note Vlad's code uses unsigned anyway...

A simpler method uses -x = (x - x * 2) to get it in 2 instructions:

bar = foo - (((int32)foo >> 16) << 17);

ASR r1,r0,#16
SUB r0,r0,r1,LSL #17

Wilco

Re: arm9e: how do I invert sign of a halfword?

The old CDC and Univac mainframes were ones-complement.  I don't
know of any micro that uses ones-complement.

There's no end-around carry/borrow in twos-complement.

VV's (corrected) solution works in all cases.  Wilco's
is suspect for large values (>0x40000000), but I haven't
investigated the boundary cases.

BTW:  SYL's problem description is misleading in that the
illustration is taking the twos-complement of the upper
halfword of the register, not "inverting the sign".

Re: arm9e: how do I invert sign of a halfword?

It works for values > 0x3fff, because it doesn't matter that the LSL #17
shift operation shifts the highest bit out of the 32 bit register, because
subtracting 0x10000 from any 16 bit word results still in the same 16 bit
word, only the upper (not present) bits are switched all to 1. Nice
solution!

--
Frank Buss, fb@frank-buss.de
http://www.frank-buss.de , http://www.it4-systems.de

Re: arm9e: how do I invert sign of a halfword?

This is correct if 0x0001000 is changed to 0x00010000.  You can also
invert the order of operations:

u32 foo = 0x00110022;
u32 bar = (foo + 0x00010000) ^ 0xFFFF0000;

Scott
--
Scott Hemphill     snipped-for-privacy@alumni.caltech.edu
"This isn't flying.  This is falling, with style."  -- Buzz Lightyear

Re: arm9e: how do I invert sign of a halfword?

That should be:

u32 bar = (foo - 0x00010000) ^ 0xFFFF0000;

Wilco

Re: arm9e: how do I invert sign of a halfword?

Right, thanks!

Scott
--
Scott Hemphill     snipped-for-privacy@alumni.caltech.edu
"This isn't flying.  This is falling, with style."  -- Buzz Lightyear

Re: arm9e: how do I invert sign of a halfword?

u32 foo2 = 0x00000022;
u32 fubar = ?????;

Re: arm9e: how do I invert sign of a halfword?

Are you sure that you can use qadd16 and qsub16? These are ARMv6
instructions, but I think the arm9e supports ARMv5, only. And even if you
can use it, I don't think that your code works.

This code should work:

mvn  r1, #0
eors r0, r0, r1, lsl #16

--
Frank Buss, fb@frank-buss.de
http://www.frank-buss.de , http://www.it4-systems.de

Re: arm9e: how do I invert sign of a halfword?

The point I was raising was that shifting a value between
0x4000 and 0x7FFF left one place results in a significant
bit being shifted into the sign bit.  There was a question
in my mind as to whether that would work correctly.

I have since run a simulation of the process and find it
works in all cases except the one value of 0x8000.  Of
course, no solution works in this case...

Re: arm9e: how do I invert sign of a halfword?

It uses basic maths: x - x = 0, and 0 - x = -x, so -x = 0 - x =
(x - x) - x = x - (2*x).

Negating the smallest negative number results in itself in two
complement's arithmetic, just like negating zero gives zero.
Both solutions have the same behaviour as a negate instruction.

Wilco

Re: arm9e: how do I invert sign of a halfword?

Nobody is saying that the equation is not mathematically
correct, but as we all know, some arithmetic operations
can have problems when being computed with limited range
operations.

Re: arm9e: how do I invert sign of a halfword?

... snip ...

Why don't you read the standard once in a while?

6.5.7  Bitwise shift operators

Syntax

[#1]
shift-expr:

Constraints

[#2] Each of the operands shall have integer type.

Semantics

[#3] The integer promotions are performed  on  each  of  the
operands.   The  type  of the result is that of the promoted
left operand.  If the value of the right operand is negative
or  is  greater  than  or equal to the width of the promoted
left operand, the behavior is undefined.

[#4] The result of E1  <<  E2  is  E1  left-shifted  E2  bit
positions; vacated bits are filled with zeros.  If E1 has an
unsigned type, the value of the result  is  E1+2E2,  reduced
modulo  one more than the maximum value representable in the
result type.  If E1 has a signed type and nonnegative value,
and E1+2E2 is representable in the result type, then that is
the resulting value; otherwise, the behavior is undefined.

[#5] The result of E1 >>  E2  is  E1  right-shifted  E2  bit
positions.  If E1 has an unsigned type or if E1 has a signed
type and a nonnegative value, the value of the result is the
integral part of the quotient of E1 divided by the quantity,
2 raised to the power E2.  If E1 has a  signed  type  and  a
negative  value,  the  resulting  value  is  implementation-
defined.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net
We've slightly trimmed the long signature. Click to see the full one.
Re: arm9e: how do I invert sign of a halfword?

FYI The standard is actually incorrect here in making all negative left
shifts undefined. Positive leftshifts that overflow are undefined too.
However multiplies of positive and negative numbers are defined if
no overflow occurs, and only implementation defined if they overflow...

But in what way does this help? The answer the standard gives in
most cases is either undefined or implementation defined behaviour.
Given there are lots of similar errors in the standard, nobody cares
which one it is (except for language lawyers).

Wilco

Re: arm9e: how do I invert sign of a halfword?

... snip ...

There is no known error in the portion I quoted (and you snipped).
If you don't pay attention, you will sooner or later have to pay.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net
We've slightly trimmed the long signature. Click to see the full one.
Re: arm9e: how do I invert sign of a halfword?

If you don't think it's an error, maybe you can explain why it is correct?

Wilco

Re: arm9e: how do I invert sign of a halfword?

Just consider the meaning and action on machines using ones
complement or sign-magnitude conventions.  Also the fact that the
occurence of an overflow can cause implementation defined action.
That's why, for safe behaviour, you should restrict shifts to
operating on unsigned quantities.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net
We've slightly trimmed the long signature. Click to see the full one.
Re: arm9e: how do I invert sign of a halfword?

I did consider that and this is exactly why the C standard is incorrect:

(right shift) or LSB (left shift). Sign magnitude only shifts the magnitude
for both left and right shift. This gives the correct arithmetic results, ie.
-0 stays -0, -1 becomes -0 on a right shift, and -2 on a left shift etc.

So given arithmetic shifts are well defined in all 3 representations
why would anyone make left shifts undefined and right shifts
implementation defined? It doesn't make any sense.

No. There is no reason to restrict shifts at all as you get the same
results irrespectively of which representation is used.

Wilco