> Thanks for the information. I know the symbol should be unique. > Actually, I changed the symbol many time (very unique), but the compiler > still complains the same thing. If I move the same code (such as a > function) to another code file, then everything is fine. I am just > confused...
The problem is that you're copying the compiler *too* closely. It uses symbols of the form "L%u:" itself. If you use "gcc -S" on a source file where you get the error, you'll see it immediately. As Steve recommended, use the "%u:" label feature. That's what it's designed for, and the compiler doesn't use it. For those who aren't familiar, it's a wonderful way to avoid having to think of a uniquie label name for a small jump. You can have many instances of a label such as "1:" in the source file, and you can refer to it with "1b" or "1f". These ("1 backward" and "1 forward") refer to the immediately preceding and following instance of "1:", respectively. (Internally, the assembler keeps a counter per label, and when you define label i, it acts as if you typed printf("$%u$%u:", i, counter[i]++). Then a reference to %ub comes out to ("$%u$%u", i, counter[i]-1) while %uf comes out to ("$%u$%u", i, counter[i]). The magic symbols don't actually involve $ but something really hard to type like control-A, but you get the idea.) As for this example source code: > __asm__ ( > " tst %[x] \n" > " jge 2f \n" > " mov #-1,%[x1] \n" > " jmp 2f \n" > "6: \n" > " add %[x],%A[z] \n" > " addc %[x1],%B[z] \n" > "1: \n" > " rla %[x] \n" > " rlc %[x1] \n" > "2: \n" > " rra %[y] \n" > " jc 5f \n" > " jne 1b \n" > " jmp 4f \n" > "5: \n" > " sub %[x],%A[z] \n" > " subc %[x1],%B[z] \n" > "3: \n" > " rla %[x] \n" > " rlc %[x1] \n" > " rra %[y] \n" > " jnc 6b \n" > " cmp #0xFFFF,%[y] \n" > " jne 3b \n" > "4: \n" > //Shift to Q1.15 format (i.e. the top 16 bits are returned) > " rla %A[z] \n" > " rlc %B[z] \n" > " mov %B[z],%[x1] \n" > : [z] "+r"(z), [x1] "+r"(x1) > : [x] "r"(x), [y] "r"(y)); Note: - You can use asm() rather than __asm__() unless you're compiling with "--ansi". "asm" is a sufficiently popular historical keyword that GCC doesn't mind reserving it. - You're not telling the compiler that you modify x and y. It might get you for that! Better would be to write: : [z] "+r"(z), [x1] "+r"(x1), [x] "+r"(x), [y] "+r"(y)); or perhaps: : [z] "=r"(z), [x1] "=r"(x1), [x] "+r"(x), [y] "+r"(y) : "0" (0), "1" (0)); You could add a "%" annotation to x, since x and y are associative, but that only matters if the inputs have different constraints. I was also trying to come up with a cleverer bit of sign-extension code based on "subc %[x1],%[x1]", but I couldn't figure out how to get the carry flag set appropriately. The closest I could come is bit #0x8000,%[x] xor #1,SR subc %[x1],%[x1] ...but I'm not sure what happens to SR if you write to it with an instruction that sets the status flags. Which takes precedence? And this is 4 cycles, just like the original branch-based code's worst case. Oh! You do a final rla/rlc on %[z] to get it in the right form. How about doing that on %[x]/%[x1] to start instead: (WARNING: untested.) __asm__ ( " rla %[x] \n" " subc %[x1],%[x1] \n" // x1 = carry - 1 " inv %[x1] \n" " jmp 2f \n" "6: \n" " add %[x],%A[z] \n" " addc %[x1],%B[z] \n" "1: \n" " rla %[x] \n" " rlc %[x1] \n" "2: \n" " rra %[y] \n" " jc 5f \n" " jne 1b \n" " jmp 4f \n" "5: \n" " sub %[x],%A[z] \n" " subc %[x1],%B[z] \n" "3: \n" " rla %[x] \n" " rlc %[x1] \n" " rra %[y] \n" " jnc 6b \n" " cmp #0xFFFF,%[y] \n" " jne 3b \n" "4: \n" " mov %B[z],%[x1] \n" : [z] "=r"(z), [x1] "&r"(x1), [x] "+r"(x), [y] "+r"(y) : "0" (0)); (When everything's an output, the "&" on x1 isn't strictly necessary, but it's better to leave it in.)