0

I'm having an issue implementing Dijkstra's algorithm in MIPS (more specifically what I presume to be MIPS R10000 given that I've been told to use the RSIM built into our servers).

Because this is such an intensive project, I was working both on writing it from scratch in MIPS and writing it in C (much easier). Given that I am essentially having issues putting the finishing touches on the code, I wanted to try and cross-compile my C code into compatible MIPS code to see what it is I'm missing with my calls and algorithm.

When I try and run GCC with the -S flag, it certainly spits back Assembly code (now I know it is x86 per Jester), but not the kind that is readable (not that I expected it to be) or compatible with RSIM and my generic makefile.

I've tried using Compiler Explorer, tweaking all of the possible outputs, so I don't think that will solve my issue (unless I'm missing something obvious), and my GCC does not appear to be compatible with any of the march=mips<X> derivatives.

I have tried poking around Buildroot. However, I can't seem to make heads or tails of how to get it to compile and execute, regardless of whether it is actually compatible with RSIM.

How can I cross-compile such that I can cherry-pick the parts that I want to slot into my current implementation?

C code not working with RSIM:

#include <stdio.h>
int main() {
   printf("Hello, World!");
   return 0;
}

Output of gcc -S dijkstra.c:

    .text
    .section    .rodata
.LC0:
    .string     "Hello, World!"
    .text
    .globl      main
    .type       main, @function
main:
.LFB0:
    .cfi_startproc
    endbr64
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    leaq    .LC0(%rip), %rdi
    movl    $0, %eax
    call    printf@PLT
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0"
    .section    .note.GNU-stack,"",@progbits
    .section    .note.gnu.property,"a"
    .align 8
    .long   1f - 0f
    .long   4f - 1f
    .long   5
0:
    .string     "GNU"
1:
    .align 8
    .long   0xc0000002
    .long   3f - 2f
2:
    .long   0x3
3:
    .align 8
4:

When I run Make

cd ~/Courses/CSCI250/Dijkstras
make

Output:

/home/fac/wrc/bin/rasm -l dijkstra.asm > dijkstra.lst
   2 0000                       .section        .rodata
Info: Unimplemented directive
   4 0000                       .string "Hello, World!"
Error: Syntax error near label field
   7 0000                       .type   main, @function
Error: Syntax error near label field
  10 0000                       .cfi_startproc
Error: Syntax error near label field
  11 0000                       endbr64
Error: Syntax error near label field
  12 0000                       pushq   %rbp
Error: Syntax error near label field
  13 0000                       .cfi_def_cfa_offset 16
Error: Syntax error near label field
  14 0000                       .cfi_offset 6, -16
Error: Syntax error near label field
  15 0000                       movq    %rsp, %rbp
Error: Syntax error near label field
  16 0000                       .cfi_def_cfa_register 6
Error: Syntax error near label field
  17 0000                       leaq    .LC0(%rip), %rdi
Error: Syntax error near label field
  18 0000                       movl    $0, %eax
Error: Syntax error near label field
  19 0000                       call    printf@PLT
Error: Syntax error near label field
  20 0000                       movl    $0, %eax
Error: Syntax error near label field
  21 0000                       popq    %rbp
Error: Syntax error near label field
  22 0000                       .cfi_def_cfa 7, 8
Error: Syntax error near label field
  23 0000                       ret
Error: Syntax error near label field
  24 0000                       .cfi_endproc
Error: Syntax error near label field
  26 0000                       .size   main, .-main
Error: Syntax error near label field
  27 0000                       .ident  "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0"
Error: Syntax error near label field
  28 0000                       .section        .note.GNU-stack,"",@progbits
Info: Unimplemented directive
Error: Syntax error near comment field
  29 0000                       .section        .note.gnu.property,"a"
Info: Unimplemented directive
Error: Syntax error near comment field
  31 0000                       .long    1f - 0f
Error: Syntax error near label field
  32 0000                       .long    4f - 1f
Error: Syntax error near label field
  33 0000                       .long    5
Error: Syntax error near label field
  34 0000               0:
Error: Syntax error near label field
  35 0000                       .string  "GNU"
Error: Syntax error near label field
  36 0000               1:
Error: Syntax error near label field
  38 0000                       .long    0xc0000002
Error: Syntax error near label field
  39 0000                       .long    3f - 2f
Error: Syntax error near label field
  40 0000               2:
Error: Syntax error near label field
  41 0000                       .long    0x3
Error: Syntax error near label field
  42 0000               3:
Error: Syntax error near label field
  44 0000               4:
Error: Syntax error near label field
There were 3 informational messages
There were 33 fatal errors
make: *** [Makefile:20: dijkstra.obj] Error 33

When I try to run a specific march on the gcc, I get the following errors:

cd ~/Courses/CSCI250/Dijkstras
gcc -S -march=mips1 dijkstra.c

Output:

cc1: error: bad value (‘mips1’) for ‘-march=’ switch
cc1: note: valid arguments to ‘-march=’ switch are: nocona core2 nehalem corei7 westmere sandybridge corei7-avx ivybridge core-avx-i haswell core-avx2 broadwell skylake skylake-avx512 cannonlake icelake-client icelake-server cascadelake tigerlake bonnell atom silvermont slm goldmont goldmont-plus tremont knl knm x86-64 eden-x2 nano nano-1000 nano-2000 nano-3000 nano-x2 eden-x4 nano-x4 k8 k8-sse3 opteron opteron-sse3 athlon64 athlon64-sse3 athlon-fx amdfam10 barcelona bdver1 bdver2 bdver3 bdver4 znver1 znver2 btver1 btver2 native
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 2
    You might want to show an example of the code that gcc produces and is not compatible with your RSIM. – Jester Jul 30 '23 at 13:32
  • 1
    Posting long C code to ask question about generated assembly code compatibility makes no sense. Write simple code ( a few lines) and show what is not compatible. As far as I remember is swa using some kind of Sun assemblers not compatible with the gnu family – 0___________ Jul 30 '23 at 13:42
  • Condensed that code, thank you both. I'm not particularly familiar with swa (unless I'm just being obtuse) or Sun Assemblers. – Aidan Mellin Jul 30 '23 at 13:50
  • 6
    _"it certainly spits back MIPS code"_ no it doesn't. What you posted is x86-64 code. Make sure you use the MIPS gcc. Even then you will probably need to fix the directives but that should not be much of an issue. – Jester Jul 30 '23 at 13:55
  • Good to know. I'm clearly not particularly well versed in Assembly, so knowing that it's x86-64 is helpful for further research. I have also edited it to say that it is Assembly code to be more clear. Also when I try to use the gcc march, I get an issue (in an attached edit). This may be a matter of updating my gcc, but advice on that would be appreciated as well. – Aidan Mellin Jul 30 '23 at 13:58
  • 1
    Misp assembly looks like this: https://godbolt.org/z/eo446qxbo – 0___________ Jul 30 '23 at 14:01
  • 5
    You can't use normal GCC to cross compile. You need a special version of GCC that supports cross compilation to mips. – interjay Jul 30 '23 at 14:06
  • What is *"RSIM"*? – Peter Mortensen Jul 30 '23 at 15:23
  • There are many MIPS environments, so you need to figure out the one for you. There are differences in assembly syntax, system calls, the way that global variables are accessed, libraries available, startup sequences, as well as 32-bit and 64-bit versions. – Erik Eidt Jul 30 '23 at 15:26
  • https://godbolt.org/ has MIPS GCC installed as 0___________ mentioned. Also, Clang *does* support multiple targets from the same compiler install, so `clang -O2 -target mips64 -march=mips4` works. https://godbolt.org/z/vehzd5Pcb . But Clang doesn't support `-fno-delayed-branch`, so you should use mips-GCC if you want to make asm that can be assembled without `.set noreorder`, or for a fake MIPS that doesn't have branch-delay slots. – Peter Cordes Jul 30 '23 at 16:59
  • 1
    See also [Is there a way to use gcc to convert C to MIPS?](https://stackoverflow.com/a/63386888) / [Tweak mips-gcc output to work with MARS](https://stackoverflow.com/q/13052444) . (I don't know what kind of environment RSIM emulates, like whether there's a real `printf` function to call, or whether you do I/O using MARS/SPIM style `syscall`s or Linux `syscall`s or what. As Erik said, it can vary. But you could get a compiler to make asm for the computational algorithm part and write the I/O stuff yourself.) – Peter Cordes Jul 30 '23 at 17:02
  • Is "RSIM" the *[Rice Simulator for ILP Multiprocessors](http://sadve.cs.illinois.edu/Publications/computer02.pdf)*? Or something else? – Peter Mortensen Aug 24 '23 at 09:05

1 Answers1

2

This works for me (on Linux). On Windows or Mac, you can also build for MIPS, with very similar commands. Or just download a pre-built for your development system (by far the easiest, especially for MIPS).

I clearly can see you do not have to use this as is. It just gets the files and sets up the two or three commands to build.

You can try to use Buildroot. It will build something that can build Linux. But it is painful to learn to use (although more "support" than support for how to just build the tools).

If you just want to see compiled code then this will work, and if you want to build binaries that run on Linux, you need a different toolchain.

# Set up variables
export TARGET=mips-elf
export PREFIX=/opt/gnu/mips
export PATH=$PATH:$PREFIX/bin
export JN='-j 8'

export GCCVER=12.2.0
export BINUVER=2.39

rm -rf build-*
rm -rf gcc-*
rm -rf binutils-*

# Get archives
wget https://ftp.gnu.org/gnu/binutils/binutils-$BINUVER.tar.gz
wget https://ftp.gnu.org/gnu/gcc/gcc-$GCCVER/gcc-$GCCVER.tar.gz

# Extract archives
tar xf binutils-$BINUVER.tar.gz
tar xf gcc-$GCCVER.tar.gz

# Build binutils
mkdir build-binutils
cd build-binutils
../binutils-$BINUVER/configure --target=$TARGET --prefix=$PREFIX
echo "MAKEINFO = :" >> Makefile
make $JN all
sudo make install

# Build GCC
mkdir ../build-gcc
cd ../build-gcc
../gcc-$GCCVER/configure --target=$TARGET --prefix=$PREFIX --without-headers --with-newlib  --with-gnu-as --with-gnu-ld --enable-languages='c'
make $JN all-gcc
sudo make install-gcc

# Build libgcc.a
make $JN all-target-libgcc CFLAGS_FOR_TARGET="-g -O2"
sudo make install-target-libgcc
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
old_timer
  • 69,149
  • 8
  • 89
  • 168
  • 1
    What does compiler explorer not do for you? You can at least build binutils, which is easier (than gcc), and use the compiler explorer output and feed that to binutils to build binaries for your sim. – old_timer Jul 30 '23 at 15:36
  • assembly language is specific to the tool (assembler) not the target (mips) so if for example your simulator takes assembly language then the gcc output may not work as it is the assembly language for gnu assembler. – old_timer Jul 30 '23 at 15:37
  • you cannot be the first person to use RSIM so this has been solved. – old_timer Jul 30 '23 at 15:38