* Clarification Req: Regarding "+m" constraints in inline asm @ 2004-03-03 14:44 Ashok.A 2004-03-04 20:45 ` Jim Wilson 0 siblings, 1 reply; 9+ messages in thread From: Ashok.A @ 2004-03-03 14:44 UTC (permalink / raw) To: gcc; +Cc: ashok_kumar_ak [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain; charset=us-ascii, Size: 911 bytes --] Hi All, I need clarification regarding the "+m" constraints. I heard that "+m" constraints cannot be used in "inline asm". Is it true? Example: ---------- int temp; asm ("lw %0,%1 \n\t" "addu %0,%0,1 \n\t" "sw %0,%1" : "=r" (temp), "=m" (data) /* outputs */ : "1" (data)); /* inputs */ ---------- Can I use the following instead of the above? Will it be exactly same as above? ---------- int temp; asm ("lw %0,%1 \n\t" "addu %0,%0,1 \n\t" "sw %0,%1" : "=r" (temp), "+m" (data) /* outputs */ ---------- I believe "+m" constraint is processor independent. Anyhow, I need clarification for MIPS processor. It would be great help if you can clarify this issue. Thanks in advance. Thanks, Ashok __________________________________ Do you Yahoo!? Yahoo! Search - Find what youre looking for faster http://search.yahoo.com ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Clarification Req: Regarding "+m" constraints in inline asm 2004-03-03 14:44 Clarification Req: Regarding "+m" constraints in inline asm Ashok.A @ 2004-03-04 20:45 ` Jim Wilson 2004-03-26 13:34 ` Clarification Req: Regarding "memory" clobber for cache operation is required (?) Ashok.A 0 siblings, 1 reply; 9+ messages in thread From: Jim Wilson @ 2004-03-04 20:45 UTC (permalink / raw) To: Ashok.A; +Cc: gcc Ashok.A wrote: > I need clarification regarding the "+m" constraints. > I heard that "+m" constraints cannot be used > in "inline asm". Is it true? Current sources will give a warning for both of your examples. Neither read-write "+" or matching "1" constraints should be used with mems in an asm. These both require that the operands are the same, but the compiler is not able to guarantee this for mems. We can only make this work for register constraints. Try changing the lw to use %2 instead of %1, and then use "m" for the second operand. I think this is the way it is supposed to work nowadays. -- Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com ^ permalink raw reply [flat|nested] 9+ messages in thread
* Clarification Req: Regarding "memory" clobber for cache operation is required (?) 2004-03-04 20:45 ` Jim Wilson @ 2004-03-26 13:34 ` Ashok.A 2004-03-27 19:54 ` Ashok.A 2004-03-30 0:38 ` Jim Wilson 0 siblings, 2 replies; 9+ messages in thread From: Ashok.A @ 2004-03-26 13:34 UTC (permalink / raw) To: gcc, Jim Wilson; +Cc: ashok_kumar_ak Hello, Need one clarification regarding the issue given below. Could you please clarify it? To invalidate a cache line, do we really need to use "memory" clobber in inline asm? Example: (for MIPS-III architecture) asm ("cache 17, 0(%0)" : /* no outputs */ : "r"(ptr)); Where, 'ptr' (pointer to unsigned char type) points to base address of cache to be invalidated. For this case, do we need "memory" clobber in the inline asm? Or, anyway to specifiy appropriate memory constraints? Expecting for yours response ... Thanks, Ashok P.S: I have checked the linux source. Looks neither "memory" clobber nor any memory constraint is specified in inline asm for similar operations in linux source. --- Jim Wilson <wilson@specifixinc.com> wrote: > Ashok.A wrote: > > I need clarification regarding the "+m" > constraints. > > I heard that "+m" constraints cannot be used > > in "inline asm". Is it true? > > Current sources will give a warning for both of your > examples. Neither > read-write "+" or matching "1" constraints should be > used with mems in > an asm. These both require that the operands are > the same, but the > compiler is not able to guarantee this for mems. We > can only make this > work for register constraints. > > Try changing the lw to use %2 instead of %1, and > then use "m" for the > second operand. I think this is the way it is > supposed to work nowadays. > -- > Jim Wilson, GNU Tools Support, > http://www.SpecifixInc.com > __________________________________ Do you Yahoo!? Yahoo! Finance Tax Center - File online. File on time. http://taxes.yahoo.com/filing.html ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Clarification Req: Regarding "memory" clobber for cache operation is required (?) 2004-03-26 13:34 ` Clarification Req: Regarding "memory" clobber for cache operation is required (?) Ashok.A @ 2004-03-27 19:54 ` Ashok.A 2004-03-30 0:38 ` Jim Wilson 1 sibling, 0 replies; 9+ messages in thread From: Ashok.A @ 2004-03-27 19:54 UTC (permalink / raw) To: gcc, Jim Wilson; +Cc: ashok_kumar_ak --- "Ashok.A" <ashok_kumar_ak@yahoo.com> wrote: > Hello, > > Need one clarification regarding the issue given > below. Could you please clarify it? > > To invalidate a cache line, do we really need to > use "memory" clobber in inline asm? > > Example: (for MIPS-III architecture) > > asm ("cache 17, 0(%0)" > : /* no outputs */ > : "r"(ptr)); > > Where, 'ptr' (pointer to unsigned char type) points > to base address of cache to be invalidated. > > For this case, do we need "memory" clobber in the > inline asm? Or, anyway to specifiy appropriate > memory constraints? > > Expecting for yours response ... > > Thanks, > Ashok > > P.S: I have checked the linux source. Looks neither > "memory" clobber nor any memory constraint is > specified in inline asm for similar operations > in linux source. > > > --- Jim Wilson <wilson@specifixinc.com> wrote: > > Ashok.A wrote: > > > I need clarification regarding the "+m" > > constraints. > > > I heard that "+m" constraints cannot be used > > > in "inline asm". Is it true? > > > > Current sources will give a warning for both of > your > > examples. Neither > > read-write "+" or matching "1" constraints should > be > > used with mems in > > an asm. These both require that the operands are > > the same, but the > > compiler is not able to guarantee this for mems. > We > > can only make this > > work for register constraints. > > > > Try changing the lw to use %2 instead of %1, and > > then use "m" for the > > second operand. I think this is the way it is > > supposed to work nowadays. > > -- > > Jim Wilson, GNU Tools Support, > > http://www.SpecifixInc.com > > > > > __________________________________ > Do you Yahoo!? > Yahoo! Finance Tax Center - File online. File on > time. > http://taxes.yahoo.com/filing.html __________________________________ Do you Yahoo!? Yahoo! Finance Tax Center - File online. File on time. http://taxes.yahoo.com/filing.html ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Clarification Req: Regarding "memory" clobber for cache operation is required (?) 2004-03-26 13:34 ` Clarification Req: Regarding "memory" clobber for cache operation is required (?) Ashok.A 2004-03-27 19:54 ` Ashok.A @ 2004-03-30 0:38 ` Jim Wilson 2004-03-30 21:26 ` Ashok.A 2004-03-31 1:45 ` Richard Henderson 1 sibling, 2 replies; 9+ messages in thread From: Jim Wilson @ 2004-03-30 0:38 UTC (permalink / raw) To: Ashok.A; +Cc: gcc On Thu, 2004-03-25 at 22:34, Ashok.A wrote: > To invalidate a cache line, do we really need to > use "memory" clobber in inline asm? This is a difficult question to answer. If it does not work without the memory clobber, then obviously you need it. If it does appear to work without the memory clobber, then whether you need it depends on the context and how the asm is written, and possibly on what gcc versions you have and what compiler optimizations are enabled. There is no simple answer here, other than to say that you are safer with a memory clobber than without one. You don't need the memory clobber if you use an alternative method for describing the dependencies. For instance, if you make the asm volatile. Or if you have memory input(s) with size and address that covers the cache line being invalidated. You don't need the memory clobber if you are sure that the function that contains the asm will never contain any memory references that will conflict with the cache line that is being invalidated. (And the function is not marked inline or you are not compiling with -finline-functions, etc.) Personally, I would include the clobber, or better yet, make the asm volatile. > P.S: I have checked the linux source. Looks neither > "memory" clobber nor any memory constraint is > specified in inline asm for similar operations > in linux source. It looks like the linux sources use volatile instead of memory clobbers. Volatile is a stronger statement than a memory clobber. -- Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Clarification Req: Regarding "memory" clobber for cache operation is required (?) 2004-03-30 0:38 ` Jim Wilson @ 2004-03-30 21:26 ` Ashok.A 2004-03-30 22:02 ` Paul Koning 2004-03-31 1:45 ` Richard Henderson 1 sibling, 1 reply; 9+ messages in thread From: Ashok.A @ 2004-03-30 21:26 UTC (permalink / raw) To: Jim Wilson; +Cc: gcc, ashok_kumar_ak Hello, Thanks a lot for your clarification! (and your time) I have a doubt in the following response. ------- > > P.S: I have checked the linux source. Looks neither > > "memory" clobber nor any memory constraint is > > specified in inline asm for similar operations > > in linux source. > > It looks like the linux sources use volatile instead > of memory clobbers. Volatile is a stronger > statement than a memory clobber. ------- Looks the "volatile" doesn't fullfil the purpose of "memory" clobber and memory constraint. It looks like just avoid reordering the inline asm instructions, as part of optimization (please correct me if I am wrong) I have tested it with a small testcase (given below). <<<<< START copy.c >>>>> static inline void copy_inline(char *dst, char *src, int size) { char temp; asm volatile ("0: subu %3,%3,1 \n" " bltz %3, end \n" " lbu %0, 0(%2) \n" " sb %0, 0(%1) \n" " b 0b \n" "end:" : "=&r" (temp) : "r" (dst), "r" (src), "r" (size)); /* NOTE: "memory" clobber is not used here, but supposed to be used eventhough "volatile" is specified (?). */ } int test () { char source[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; char dest[10] = { 0 }; char *ptr = &dest[9]; /* 'ptr' points to last element of 'dest[]' */ *ptr = 0; copy_inline (dest, source, 10); if (*ptr != 9) return 0; /* Failure */ return 1; } <<<<< END copy.c >>>>> Generated .s file (given below) for the above testcase with the following options Options : -O2 -S Compiler Version : 2.95.3 (for mips-III arch) <<<<< START copy.s (comments inlined) >>>>> <snipped> .globl test .text .ent test test: .frame $sp,88,$31 # vars= 32, regs= 3/0, # args= 32, extra=0 .mask 0x80030000,-8 .fmask 0x00000000,0 subu $sp,$sp,88 lui $2,%hi($LC0) # high sd $17,72($sp) addu $17,$sp,32 sd $16,64($sp) addu $16,$sp,48 sd $31,80($sp) addiu $6,$2,%lo($LC0) ldl $3,0($6) ldr $3,7($6) lb $4,8($6) lb $5,9($6) sdl $3,32($sp) sdr $3,39($sp) sb $4,40($sp) sb $5,41($sp) move $4,$16 move $5,$0 .set noreorder .set nomacro jal memset li $6,10 # 0xa .set macro .set reorder li $2,10 # 0xa sb $0,57($sp) #APP 0: subu $2,$2,1 bltz $2, end lbu $3, 0($17) sb $3, 0($16) b 0b end: #NO_APP ld $31,80($sp) ld $17,72($sp) ld $16,64($sp) move $2,$0 ==> Always returns 0. Expected behaviour is, *ptr should not be cached (or assumed as 0) as it is being changed in copy_inline(). If "memory" clobber is used in the inline asm, then it loads the *ptr from memory just before this line and compares it with '9' as expected. .set noreorder .set nomacro j $31 addu $sp,$sp,88 .set macro .set reorder .end test <<<<< END copy.s >>>>> Another question is, can we use the following like constraints instead of using more costlier "memory" clobber? ---------- typedef char helper [DCACHE_LINE_SIZE]; ... ... inline void invalidate_cache_line(void *ptr) { asm volatile ("cache 17, 0(%1)" : "=m" (*(helper *)ptr) : "r" (ptr)); } Please share your thoughts. Thanks, Ashok --- Jim Wilson <wilson@specifixinc.com> wrote: > On Thu, 2004-03-25 at 22:34, Ashok.A wrote: > > To invalidate a cache line, do we really need to > > use "memory" clobber in inline asm? > > This is a difficult question to answer. > > If it does not work without the memory clobber, then > obviously you need > it. > > If it does appear to work without the memory > clobber, then whether you > need it depends on the context and how the asm is > written, and possibly > on what gcc versions you have and what compiler > optimizations are > enabled. There is no simple answer here, other than > to say that you are > safer with a memory clobber than without one. > > You don't need the memory clobber if you use an > alternative method for > describing the dependencies. For instance, if you > make the asm > volatile. Or if you have memory input(s) with size > and address that > covers the cache line being invalidated. > > You don't need the memory clobber if you are sure > that the function that > contains the asm will never contain any memory > references that will > conflict with the cache line that is being > invalidated. (And the > function is not marked inline or you are not > compiling with > -finline-functions, etc.) > > Personally, I would include the clobber, or better > yet, make the asm > volatile. > > > P.S: I have checked the linux source. Looks > neither > > "memory" clobber nor any memory constraint is > > specified in inline asm for similar > operations > > in linux source. > > It looks like the linux sources use volatile instead > of memory > clobbers. Volatile is a stronger statement than a > memory clobber. > -- > Jim Wilson, GNU Tools Support, > http://www.SpecifixInc.com > __________________________________ Do you Yahoo!? Yahoo! Finance Tax Center - File online. File on time. http://taxes.yahoo.com/filing.html ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Clarification Req: Regarding "memory" clobber for cache operation is required (?) 2004-03-30 21:26 ` Ashok.A @ 2004-03-30 22:02 ` Paul Koning 2004-03-31 9:40 ` Ashok.A 0 siblings, 1 reply; 9+ messages in thread From: Paul Koning @ 2004-03-30 22:02 UTC (permalink / raw) To: ashok_kumar_ak; +Cc: wilson, gcc >>>>> "Ashok" == Ashok A <Ashok.A> writes: Ashok> Another question is, can we use the following like constraints Ashok> instead of using more costlier "memory" clobber? Ashok> ---------- typedef char helper [DCACHE_LINE_SIZE]; ... ... Ashok> inline void invalidate_cache_line(void *ptr) { asm volatile Ashok> ("cache 17, 0(%1)" : "=m" (*(helper *)ptr) : "r" (ptr)); } In an earlier discussion (about atomicity) it was pointed out that this doesn't work -- you can't make use of operands to asm that aren't actually used in the asm text. There are no references to %0, so the "=m" operand doesn't have any effect. The way to look at whether you need "memory" clobber, or volatile (or neither) is to look at what the asm statement does. Take the specific example of a cache invalidate. If the compiler had generated a load before the invalidate, that value is no longer valid afterwards -- if you did another load, you might get a different answer. So "clobber memory" is the safe thing to do here. If you don't have any loads or stores to the affected memory in the source text before the invalidate, but you do have some after it, then "volatile" would be sufficient (it keeys the compiler from moving things before the asm). Conversely, if the asm was a cache flush rather than a cache invalidate, that doesn't make loads or stores invalid. (It affects physical memory, but it doesn't affect the view of memory that software has). So a flush wouldn't need a memory clobber. It may need "volatile", to make sure that externally visible memory operations happen in the order intended by the program. paul ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Clarification Req: Regarding "memory" clobber for cache operation is required (?) 2004-03-30 22:02 ` Paul Koning @ 2004-03-31 9:40 ` Ashok.A 0 siblings, 0 replies; 9+ messages in thread From: Ashok.A @ 2004-03-31 9:40 UTC (permalink / raw) To: Paul Koning; +Cc: wilson, gcc, ashok_kumar_ak Hello Paul, Thanks for your response! I am not clear about the statement "you can't make use of operands to asm that aren't actually used in the asm text". As you said, I have gone through the thread about "locking problem with mips atomicity". From the thread, I could noticed the following: ---------------------- > - : "m" (*__mem), "r"(__val)); > + : "m" (*__mem), "r"(__val), "r"(__mem)); In addition to just adding the new argument, you have to actually use it in the assembly. ----------------------- Seems the '"r" (__mem)' is supposed to be used in the above case (not for all the cases, given one example below). That's what suggested to use that constraint in asm template. From my understanding, we *can use unused constraint* in input/output section of the extend inline asm to inform GCC that corresponding input/output is being read/written in this inline asm. So GCC won't cache the corresponding memory value in register before inline asm. Please correct me if I am wrong, with some explaination. Example: <<<<< START >>>>> test.c static inline void add_inline(int a, int b, int *c) { int res; asm ("addu %0,%2,%3 \n\t" "sw %0,0(%4)" : "=&r" (res), "=m"(*c) : "r" (a), "r" (b), "r"(c)); } int test(int a, int b) { int c = 0; add_inline(a, b, &c); if (c != a + b) return 0; /* Failure */ return 1; } <<<<< END >>>>> test.c If we remove the *unused* constraint '"=m" (*c)' in the above example, GCC generates wrong assembly. It proves that "unused constraint is also significant" in inline asm. Please find the difference between specifying unused constraint and not specifying unused constraint, in the generate .s file, below. <<<<< START >>>>> test.s.diff *************** *** 7,29 **** .text .ent test test: ! .frame $sp,8,$31 # vars= 8, regs= 0/0, # args= 0, extra= 0 .mask 0x00000000,0 .fmask 0x00000000,0 ! subu $sp,$sp,8 ! sw $0,0($sp) ! #APP ! addu $2,$4,$5 ! sw $2,0($sp) ! #NO_APP ! lw $2,0($sp) ! addu $4,$4,$5 ! xor $2,$2,$4 ! sltu $2,$2,1 .set noreorder .set nomacro --- 7,20 ---- .text .ent test test: ! .frame $sp,0,$31 # vars= 0, regs= 0/0, # args= 0, extra= 0 .mask 0x00000000,0 .fmask 0x00000000,0 ! addu $2,$4,$5 .set noreorder .set nomacro j $31 ! sltu $2,$2,1 .set macro .set reorder <<<<< END >>>>> test.s.diff The .s file generated for the testcase which hasn't use the "unused constraint" generates the wrong code (i.e the function 'test' always return 0). Please share your thoughts! Expecting for yours response.... (Sorry for this long mail :) Thanks, Ashok --- Paul Koning <pkoning@equallogic.com> wrote: > >>>>> "Ashok" == Ashok A <Ashok.A> writes: > > Ashok> Another question is, can we use the > following like constraints > Ashok> instead of using more costlier "memory" > clobber? > > Ashok> ---------- typedef char helper > [DCACHE_LINE_SIZE]; ... ... > > Ashok> inline void invalidate_cache_line(void *ptr) > { asm volatile > Ashok> ("cache 17, 0(%1)" : "=m" (*(helper *)ptr) : > "r" (ptr)); } > > In an earlier discussion (about atomicity) it was > pointed out that > this doesn't work -- you can't make use of operands > to asm that aren't > actually used in the asm text. There are no > references to %0, so the > "=m" operand doesn't have any effect. > > The way to look at whether you need "memory" > clobber, or volatile (or > neither) is to look at what the asm statement does. > > Take the specific example of a cache invalidate. If > the compiler had > generated a load before the invalidate, that value > is no longer valid > afterwards -- if you did another load, you might get > a different > answer. So "clobber memory" is the safe thing to do > here. > > If you don't have any loads or stores to the > affected memory in the > source text before the invalidate, but you do have > some after it, then > "volatile" would be sufficient (it keeys the > compiler from moving > things before the asm). > > Conversely, if the asm was a cache flush rather than > a cache > invalidate, that doesn't make loads or stores > invalid. (It affects > physical memory, but it doesn't affect the view of > memory that > software has). So a flush wouldn't need a memory > clobber. It may > need "volatile", to make sure that externally > visible memory > operations happen in the order intended by the > program. > > paul > > __________________________________ Do you Yahoo!? Yahoo! Finance Tax Center - File online. File on time. http://taxes.yahoo.com/filing.html ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Clarification Req: Regarding "memory" clobber for cache operation is required (?) 2004-03-30 0:38 ` Jim Wilson 2004-03-30 21:26 ` Ashok.A @ 2004-03-31 1:45 ` Richard Henderson 1 sibling, 0 replies; 9+ messages in thread From: Richard Henderson @ 2004-03-31 1:45 UTC (permalink / raw) To: Jim Wilson; +Cc: Ashok.A, gcc On Mon, Mar 29, 2004 at 03:01:35PM -0800, Jim Wilson wrote: > It looks like the linux sources use volatile instead of memory > clobbers. Volatile is a stronger statement than a memory clobber. No, it makes a completely different statement. r~ ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2004-03-31 7:43 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2004-03-03 14:44 Clarification Req: Regarding "+m" constraints in inline asm Ashok.A 2004-03-04 20:45 ` Jim Wilson 2004-03-26 13:34 ` Clarification Req: Regarding "memory" clobber for cache operation is required (?) Ashok.A 2004-03-27 19:54 ` Ashok.A 2004-03-30 0:38 ` Jim Wilson 2004-03-30 21:26 ` Ashok.A 2004-03-30 22:02 ` Paul Koning 2004-03-31 9:40 ` Ashok.A 2004-03-31 1:45 ` Richard Henderson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).