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

Threaded View
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?



Quoted text here. Click to load it

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


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

Re: arm9e: how do I invert sign of a halfword?
Quoted text here. Click to load it

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?

Quoted text here. Click to load it

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?
Quoted text here. Click to load it

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.

Quoted text here. Click to load it

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?

Quoted text here. Click to load it

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?

Quoted text here. Click to load it

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?

Quoted text here. Click to load it

That should be:

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

Wilco



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

Quoted text here. Click to load it

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?
Quoted text here. Click to load it

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



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

Quoted text here. Click to load it

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
add  r0, #0x10000

--
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?
Quoted text here. Click to load it

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?

Quoted text here. Click to load it

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

Quoted text here. Click to load it

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?
Quoted text here. Click to load it

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.

Quoted text here. Click to load it

Re: arm9e: how do I invert sign of a halfword?
Quoted text here. Click to load it
... snip ...
Quoted text here. Click to load it

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

  6.5.7  Bitwise shift operators

  Syntax

  [#1]
          shift-expr:
                  additive-expr
                  shift-expr << additive-expr
                  shift-expr >> additive-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?

Quoted text here. Click to load it

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?
Quoted text here. Click to load it
... snip ...
Quoted text here. Click to load it

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?

Quoted text here. Click to load it

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?
Quoted text here. Click to load it

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?

Quoted text here. Click to load it

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

Arithmetic one-complement shifts shift the sign into either the MSB
(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.

Quoted text here. Click to load it

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

Wilco



Site Timeline