0

I try to do a simple example to insert, into a C code, a piece of Sparc assembly 32 bits; this little code performs an incrementation on the variable "sum".

The code is :

#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>

int n;
int sum;

int main ()
{
  n = 100;
  sum = 0;

  struct timeval tv1, tv2;
  long long diff;

  gettimeofday (&tv1, NULL);

  asm volatile ("set sum, %g1\n\t" \
                "set n, %g3\n" \
                "loop:\n\t" \
                "add %g1, 1, %g2\n\t" \
                "sub %g3, 1, %g4\n\t" \
                "bne loop\n\t" \
                "nop\n\t" \
                : "=r" (sum)
                : "r" (n)
                );

  gettimeofday (&tv2, NULL);

  diff = (tv2.tv_sec - tv1.tv_sec) * 1000000L + (tv2.tv_usec - tv1.tv_usec);
  printf ("Elapsed time = %d usec\n", diff);

  printf ("Sum = %d\n", sum);

  return 0;

}

Unfortunately, compilation with gcc4.1.2 produces the following errors :

loop_dev_for-assembly_code.c: In function #main#:
loop_dev_for-assembly_code.c:18: error: invalid 'asm': invalid operand output code
loop_dev_for-assembly_code.c:18: error: invalid 'asm': operand number out of range
loop_dev_for-assembly_code.c:18: error: invalid 'asm': invalid operand output code
loop_dev_for-assembly_code.c:18: error: invalid 'asm': operand number out of range
loop_dev_for-assembly_code.c:18: error: invalid 'asm': operand number out of range
loop_dev_for-assembly_code.c:18: error: invalid 'asm': operand number out of range

It seems the line 18 corresponds to "asm volatile ("set sum, %g1\n\t" \ ...".

But I don't know how to circumvent these errors. It may come from the variable sum which is set to %g1 register.

About the links between variable belonging to C code and variable localted in Assembly code part. I have also seen, for inputs and outputs parameters, the syntax "=g" (output paramter ??), "g" (input parameter) : I think that it corresponds to different registers between the 2 syntax.

if someone could give to me some clues to understand this link and debug my little code which does a simple loop to increment variable sum.

Thanks for your help, regards.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • 2
    Have you tried reading the manual? You made so many mistakes it's hard to count. Anyway, avoid inline asm if possible and use separate asm file. – Jester May 18 '17 at 23:29
  • -@Jester Sorry, it has been a long time ago that I didn't practise Sparc Assembly and especially Inline Assembly. If you could give some big errors in the little inline code. –  May 19 '17 at 00:16
  • are you using a sparc targeted gcc or is this an x86 gcc you are feeding sparc for example? first and foremost remove the asm into its own file and call gcc or as to assemble it, then wrap it with a label and return and call it from C. – old_timer May 19 '17 at 00:21
  • I compile from a Sparc version of Debian Etch (Sparc 32 bits) and this Sparc version is running thanks to QEMU with qemu-system-sparc command in host of QEMU and with also an image of Debian Etch. If you could tell me the main mistakes of inline code, this would be fine. Regards –  May 19 '17 at 00:31
  • http://www.tldp.org/HOWTO/html_single/Assembly-HOWTO/ – Cody Gray - on strike May 19 '17 at 06:56

1 Answers1

0

As somebody else said, there are many errors and misconceptions in your inline assembly code. Here are just a few things. First, in extended asm syntax, you must escape all the '%' symbols with another '%', so for example you need to put '%%g1' instead of '%g1' and do this for all the registers you access. Second, you can't use 'set' for either of the variables n or sum, since they are both stack variables, not globals. You have already declared these variables as positional parameters in your asm statement, so sum is parameter %0 and n is %1. Your add instruction puts the result in %g2, which is never initialized or used anywhere.

I think the entire sequence could be rendered much more simply like this (not tested):

 asm volatile ("clr %%g1\n" \
            "loop:\n\t" \
            "add %%g1, 1, %%g1\n\t" \
            "subcc %1, 1, %1\n\t" \
            "bne loop\n\t" \
            "nop\n\t" \
            "mov %%g1, %0\n" \
            : "=r" (sum)
            : "r" (n)
            : "g1" );
Rob Gardner
  • 201
  • 1
  • 4