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

**posted on**

July 25, 2008, 11:46 pm

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

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?

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

[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

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

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?

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

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?

... snip ...

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

[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

[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?

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:

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.

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

- » Unable to boot Kernel on ARM after Memory Remap
- — Next thread in » Embedded Programming

- » New Yahoo Group for Blackfin DSP/MCU
- — Previous thread in » Embedded Programming

- » [AVR] What assembler to use?
- — Newest thread in » Embedded Programming

- » Serial EEPROM or Serial Flash?
- — Last Updated thread in » Embedded Programming

- » Ping Win Hill; X Chapters
- — The site's Newest Thread. Posted in » Electronics Design

- » Sanity check for a cheap DVM
- — The site's Last Updated Thread. Posted in » Hobby Electronics Basics