Subject: egcs 1.1.1 assembler output for 2.2. kernel compilation.

From: Nicholas Clark <[email-masked]>
Date: Fri, 5 Mar 1999 00:17:20 +0000 (GMT)

Russel has suggested that I compile the kernel decompression code without
optimistation. For some reason changing the top level CFLAGS (was this the
wrong place to do it) has resulted in the makefile deciding to recompile
everything. Howver, it's spitting out warnings like

gcc -D__KERNEL__ -I/usr/src/linux/include  -mapcs-32 -mshort-load-bytes -mcpu=strongarm110 -Wall -Wstrict-prototypes  -pipe   -DEXPORT_SYMTAB -c console.c
{standard input}: Assembler messages:
{standard input}:11238: Warning: destination register same as write-back base

left, right and centre. Such lines look like this:

	1:	ldrbt	r6,[r6],#0

	1:	ldrbt	r4,[r4],#0

I don't recognise the t flag, and I can't remeber what happens with ldr
(ldm, IIRC, does the writeback after the first register load, but all that
might have changed/become undefined with StrongARM) but the instruction as
shown looks very odd - is it a very expensive No-op? Or is it doing something
cunning? Should the #0 be pre-increment instead?
(b.t.w. I get no warnings with -O2, which was what I was using)

Nick
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Philip Blundell <[email-masked]>
Date: Fri, 05 Mar 1999 09:51:05 +0000

>everything.

That's deliberate.  The makefile tracks the flags for each source file and 
recompiles any whose flags have changed.

>(b.t.w. I get no warnings with -O2, which was what I was using)

What the instruction is trying to do is load the word pointed to by R6 and 
store the result back in that same register.  It's not a no-op.  The T flag 
means to do the access as if from user mode; this is probably a get_user call.

Technically the results are UNPREDICTABLE if the two registers are the same.  
I guess get_user needs to tell gcc that the input and output regs mustn't 
overlap.  If you send me a fragment of code that exhibits the problem I'll 
cook up a fix.

p.

---

From: Russell King <[email-masked]>
Date: Fri, 5 Mar 1999 14:05:19 +0000 (GMT)

> overlap.  If you send me a fragment of code that exhibits the problem I'll 

This is not illegal, nor unpredictable.  The documentation says that a
post indexed ldr instruction must not have rd the same as rn, except in
one case where it is permitted.  The above is an example of the exact
case when it is allowed.

Hence, it's a bug in binutils to be warning this instruction.

--
Russell King ([email-masked])

---

From: Philip Blundell <[email-masked]>
Date: Fri, 05 Mar 1999 14:10:11 +0000

>one case where it is permitted.  The above is an example of the exact

Where is this documented?  The ARM says of LDRBT simply:

Notes	
	Register Rn: 
	Specifies the base register used by <post_indexed_addressing_mode>.
	
	Operand restrictions:
	If the same register is specified for Rd and Rn the results are
	UNPREDICTABLE.

This is on page 3-46.

p.

---

From: Nicholas Clark <[email-masked]>
Date: Fri, 5 Mar 1999 14:37:50 +0000 (GMT)

> 	If the same register is specified for Rd and Rn the results are

It would seem sane for what Russell writes to be true, as I did find some
documentation of the T flag, and it says it only applies for post indexed
addressing (presumably there are 2 bits to encode 4 states:
pre indexed, pre indexed with writeback, post indexed, post indexed with 
address translation) hence post index of 0 is otherwise meaningless.

However, I'm no expert, and even with -O1 can't get an inflatable kernel
(Phil predicted correctly that -O0 doesn't inline functions, hence I got >
1024 lines of link errors)

Nick

---

From: Russell King <[email-masked]>
Date: Fri, 5 Mar 1999 15:07:58 +0000 (GMT)

> 	If the same register is specified for Rd and Rn the results are

Well, It'll have to wait until tonight - but I'm sure that there is a
comment in there somewhere, it's just not obvious where.

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Fri, 5 Mar 1999 21:03:10 +0000 (GMT)

> 	If the same register is specified for Rd and Rn the results are

Well, indeed the ARM ARM does seem to imply this.  If this is the case, then
IMHO that's another error in the ARM ARM (the ARM ARM has on average one
error per page), since it means any code using this could break between ARM2
or ARM3 processors and ARM6+.  The ARM2 data book says:

'In the case of post-indexed addressing, the write back bit is redundant,
since the old base value can be retained by setting the offset to zero.'

Hence, when specifing an offset of zero, since no writeback is performed,
the result is predictable.  However, the question now is, does this apply
to the later processors?  Have ARM updated their ARM to include this?
Did they purposely remove this?  Or what?
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.linux.org.uk/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Philip Blundell <[email-masked]>
Date: Fri, 05 Mar 1999 22:37:50 +0000

>or ARM3 processors and ARM6+.  The ARM2 data book says:

OK.  It wouldn't be the first time that code sequences that were allowed or
even advised in ARM2 times have subsequently been declared to be verboten, of 
course -- the NV condition is an obvious example.  Judging by the fact that 
nobody has reported a problem I assume that current silicon does actually 
execute such an LDRBT as expected even if it isn't required to by the 
architecture specification.

>since the old base value can be retained by setting the offset to zero.'

Does it explicitly say that no writeback takes place?  In terms of processor 
architecture it is very different to say that an offset of zero results in no 
writeback, as opposed to that an offset of zero results in the original value 
being written back unchanged.  From the perspective of the system architect I 
can well imagine that making this behaviour unpredictable would be an 
attractive idea.

>Did they purposely remove this?  Or what?

Would you like to talk to ARM Ltd and find out?  I would do so myself but I'm 
out of the country for the next week.  Once we have a definitive answer we can 
fix the kernel or the assembler as appropriate.

p.

---

From: Nicholas Clark <[email-masked]>
Date: Sat, 6 Mar 1999 23:07:41 +0000 (GMT)

Russell spotted why I can't gunzip() my compressed kernel - I'm
configured for strongarm, which causes gcc to generate LDRH and STRH
instructions, which the RiscPC hardware can't cope with.

So I tried building for 710, (and 610, and 610 with 
no-short-byte-loads) to no avail. I've unplugged my EtherH card, but
that didn't help either.

Apart from LDRH/STRH is there anything that egcs will do that the ART
StrongARM card won't like?

(I had a look at arm.c and arm.h in gcc - erk, it's complex. Am I
right in thinking that currently gcc doesn't attempt to reoder LDR
instructions to try to ensure that the loaded data is not required
next instruction, and hence save a clock cycle on a StrongARM?)

Nick