点击(此处)折叠或打开
- /*
- * atomic_add - add integer to atomic variable
- * @i: integer value to add
- * @v: pointer of type atomic_t
- *
- * Atomically adds @i to @v.
- */
- static __inline__ void atomic_add(int i, atomic_t * v)
- {
- if (cpu_has_llsc && R10000_LLSC_WAR) {
- int temp;
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: ll %0, %1 # atomic_add \n"
- " addu %0, %2 \n"
- " sc %0, %1 \n"
- " beqzl %0, 1b \n"
- " .set mips0 \n"
- : "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter));
- } else if (cpu_has_llsc) {
- int temp;
- __asm__ __volatile__(
- " .set mips3 \n"
- "1: ll %0, %1 # atomic_add \n"
- " addu %0, %2 \n"
- " sc %0, %1 \n"
- " beqz %0, 2f \n"
- " .subsection 2 \n"
- "2: b 1b \n"
- " .previous \n"
- " .set mips0 \n"
- : "=&r" (temp), "=m" (v->counter)
- : "Ir" (i), "m" (v->counter));
- } else {
- unsigned long flags;
- raw_local_irq_save(flags);
- v->counter += i;
- raw_local_irq_restore(flags);
- }
- }
- mips架构下C语言内嵌汇编语言的格式;
- mips下ll和sc指令的用法;
- .subsection和.previous指令的用法。
下面分别介绍相关的知识:
- mips架构下C语言内嵌汇编语言的格式
gcc内嵌汇编扩展格式如上所示,依次分别为汇编代码,输出参数列表,输入参数列表,被改变的操作列表。所有项目都是可选的(汇编代码为空的例子:barrier指令),atomic_add函数没有最后一项,最后一项的意思是告诉gcc,在汇编代码中除了可能会修改输入和输出参数,还会修改其他参数,以免gcc误判。asm ("assembly code": output_operand /* 输出参数列表 */: input_operand /* 输入参数列表 */: clobbered_operand /* 被改变的操作对象列表 */);
汇编代码中的%0,%1,%2表示从输出参数开始,按顺序给所有参数的标号,这里temp就是%0, v->counter为%1, i为%2。另外还有很多符号,r表示寄存器(temp经过r修饰,存入寄存器中),m表示内存,=,&等在 http://wenku.baidu.com/view/c395bcec172ded630b1cb65c.html都有描述。
- mips下ll和sc指令的用法
- .subsection和.previous指令的用法