Are there any GCC flags that will make some of these problems go away?
The short answer is no. MARS uses custom system calls and is very different in calling conventions.
Is there an existing program that will fix up the mips-gcc output so that it will run on Mars?
I don't know of any automated way to convert it. You can do it only manually. I have done it actually.
Roughly, these are the steps I followed:
- Use Godbolt (Compiler Explorer) to get a beatified raw assembly of your code. They don't use specific GCC options to get this beatified view according to this, so I'm not mentioning any GCC command, but you can set up a local copy of it.
- Replace all the system calls and their calling conventions according to SYSCALL functions available in MARS
- Replace/add the required segment labels (such as .text, .data, etc.) along with their required data.
- If you have a main function (label), add j mainafter.text.
- (Optionally, you can rename the registers to be more readable because as Peter Cordes mentioned in the comments, GCC for MIPS doesn't support the argument -mregnames)
This is an example I made. It lacks main, because it was intended as a library:
C code:
#include <stdio.h>
#include <stdlib.h>
typedef struct node Node;
struct node {
    int data;
    struct node *left;
    struct node *right;
};
Node *new_node (int data) {
    Node *ret = malloc (sizeof (Node)); ret->left = NULL;
    ret->data = data;
    ret->left = NULL;
    ret->right = NULL;
return ret; }
void link (Node *parent, Node *left, Node *right) {
    parent->left = left;
    parent->right = right;
}
int depth (Node *root) {
    if (root == NULL) {
        return -1;
    }
    int left = depth (root->left);
    int right = depth (root->right);
    return 1 + (left > right? left : right);
}
int even_level_max (Node *root, int level) {
    if (root == NULL) {
        return 0x80000000;
    }
    int left = even_level_max(root->left, level + 1);
    int right = even_level_max (root->right, level + 1);
    int greater = (left > right) ? left : right;
    if (level % 2 == 0) {
        return (greater > root->data)? greater : root->data;
    } else {
        return greater;
    }
}
Godbolt code:
new_node:
        addiu   $sp,$sp,-40
        sw      $31,36($sp)
        sw      $fp,32($sp)
        move    $fp,$sp
        sw      $4,40($fp)
        li      $4,12                 # 0xc
        jal     malloc
        nop
        sw      $2,24($fp)
        lw      $2,24($fp)
        nop
        sw      $0,4($2)
        lw      $2,24($fp)
        lw      $3,40($fp)
        nop
        sw      $3,0($2)
        lw      $2,24($fp)
        nop
        sw      $0,4($2)
        lw      $2,24($fp)
        nop
        sw      $0,8($2)
        lw      $2,24($fp)
        move    $sp,$fp
        lw      $31,36($sp)
        lw      $fp,32($sp)
        addiu   $sp,$sp,40
        jr      $31
        nop
link:
        addiu   $sp,$sp,-8
        sw      $fp,4($sp)
        move    $fp,$sp
        sw      $4,8($fp)
        sw      $5,12($fp)
        sw      $6,16($fp)
        lw      $2,8($fp)
        lw      $3,12($fp)
        nop
        sw      $3,4($2)
        lw      $2,8($fp)
        lw      $3,16($fp)
        nop
        sw      $3,8($2)
        nop
        move    $sp,$fp
        lw      $fp,4($sp)
        addiu   $sp,$sp,8
        jr      $31
        nop
depth:
        addiu   $sp,$sp,-40
        sw      $31,36($sp)
        sw      $fp,32($sp)
        move    $fp,$sp
        sw      $4,40($fp)
        lw      $2,40($fp)
        nop
        bne     $2,$0,$L5
        nop
        li      $2,-1                 # 0xffffffffffffffff
        b       $L6
        nop
$L5:
        lw      $2,40($fp)
        nop
        lw      $2,4($2)
        nop
        move    $4,$2
        jal     depth
        nop
        sw      $2,24($fp)
        lw      $2,40($fp)
        nop
        lw      $2,8($2)
        nop
        move    $4,$2
        jal     depth
        nop
        sw      $2,28($fp)
        lw      $3,24($fp)
        lw      $2,28($fp)
        nop
        slt     $4,$2,$3
        beq     $4,$0,$L7
        nop
        move    $2,$3
$L7:
        addiu   $2,$2,1
$L6:
        move    $sp,$fp
        lw      $31,36($sp)
        lw      $fp,32($sp)
        addiu   $sp,$sp,40
        jr      $31
        nop
even_level_max:
        addiu   $sp,$sp,-48
        sw      $31,44($sp)
        sw      $fp,40($sp)
        move    $fp,$sp
        sw      $4,48($fp)
        sw      $5,52($fp)
        lw      $2,48($fp)
        nop
        bne     $2,$0,$L9
        nop
        li      $2,-2147483648                  # 0xffffffff80000000
        b       $L10
        nop
$L9:
        lw      $2,48($fp)
        nop
        lw      $3,4($2)
        lw      $2,52($fp)
        nop
        addiu   $2,$2,1
        move    $5,$2
        move    $4,$3
        jal     even_level_max
        nop
        sw      $2,24($fp)
        lw      $2,48($fp)
        nop
        lw      $3,8($2)
        lw      $2,52($fp)
        nop
        addiu   $2,$2,1
        move    $5,$2
        move    $4,$3
        jal     even_level_max
        nop
        sw      $2,28($fp)
        lw      $3,24($fp)
        lw      $2,28($fp)
        nop
        slt     $4,$2,$3
        beq     $4,$0,$L11
        nop
        move    $2,$3
$L11:
        sw      $2,32($fp)
        lw      $2,52($fp)
        nop
        andi    $2,$2,0x1
        bne     $2,$0,$L12
        nop
        lw      $2,48($fp)
        nop
        lw      $3,0($2)
        lw      $2,32($fp)
        nop
        slt     $4,$2,$3
        beq     $4,$0,$L10
        nop
        move    $2,$3
        b       $L10
        nop
$L12:
        lw      $2,32($fp)
$L10:
        move    $sp,$fp
        lw      $31,44($sp)
        lw      $fp,40($sp)
        addiu   $sp,$sp,48
        jr      $31
        nop
Converted Mars code:
# Registers:
# a : store results
# t : temporaries
# s : saved
# k : kernel
.text:
j main
new_node: #Node *new_node (int data)
        # prologue
        addiu   $sp,$sp,-40
        sw      $ra,36($sp)
        sw      $fp,32($sp)
        move    $fp,$sp
        sw      $a0,40($fp) # fp[40] = data
        li      $v0, 9
        li      $a0, 12
        syscall
        sw      $v0,24($fp) # fp[24] = sbrk ( sizeof (Node = 12) )
        lw      $v0,24($fp)
        lw      $v1,40($fp) # data = fp[40]
        sw      $v1,0($v0) # ret[0] = data;
        lw      $v0,24($fp)
        sw      $zero,4($v0) # ret[4] = NULL;
        lw      $v0,24($fp)
        sw      $zero,8($v0) # ret[8] = NULL;
        # epilogue
       lw      $v0,24($fp)
        move    $sp,$fp
        lw      $ra,36($sp)
        lw      $fp,32($sp)
        addiu   $sp,$sp,40
        jr      $ra
        nop
link: # int depth (Node *root)
        # prologue
        addiu   $sp,$sp,-8
        sw      $fp,4($sp)
        move    $fp,$sp
        #store arguments
        sw      $a0,8($fp)
        sw      $a1,12($fp)
        sw      $a2,16($fp)
        #parent -> left = left;
        lw      $v0,8($fp)
        lw      $v1,12($fp)
        sw      $v1,4($v0)
        sw      $a1,4($a0)
        # parent -> right = right
        lw      $v0,8($fp)
        lw      $v1,16($fp)
        sw      $v1,8($v0)
        sw      $a2,8($a0)
        # epilogue
        move    $sp,$fp
        lw      $fp,4($sp)
        addiu   $sp,$sp,8
        jr      $ra
        nop
depth: # int depth (Node *root)
        # prologue
        addiu   $sp,$sp,-40
        sw      $ra,36($sp)
        sw      $fp,32($sp)
        move    $fp,$sp
        sw      $a0,40($fp) # fp[40] = root
        lw      $v0,40($fp)
        bne     $v0,$zero,L5
        li      $v0,-1
        b       L6 #if (root == NULL) return -1;
L5:
        lw      $v0,40($fp)
        lw      $v0,4($v0)
        move    $a0,$v0 # a0 = root -> left
        jal     depth # depth(a0)
        sw      $v0,24($fp) # fp[24] = depth(a0)
        lw      $v0,40($fp)
        lw      $v0,8($v0)
        move    $a0,$v0 # a0 = root -> right
        jal     depth # depth(a0)
        sw      $v0,28($fp) # fp[28] = depth(a0)
        lw      $v1,24($fp) # v0 = right
        lw      $v0,28($fp) # v1 = left
        slt     $a0,$v0,$v1 # a0 = v1 > v0 ? 0 : 1
        beq     $a0,$zero,L7
        move    $v0,$v1 # executed when v1 > v0
L7:
        addiu   $v0,$v0,1 # executed when v0 < v1
L6:
        # epilogue
        move    $sp,$fp
        lw      $ra,36($sp)
        lw      $fp,32($sp)
        addiu   $sp,$sp,40
        jr      $ra
even_level_max:
        # prologue
        addiu   $sp,$sp,-48
        sw      $ra,44($sp)
        sw      $fp,40($sp)
        move    $fp,$sp
        sw      $a0,48($fp) # fp[48] = root
        sw      $a1,52($fp) # fp[52] = level
        lw      $v0,48($fp)
        bne     $v0,$zero,L9
        li      $v0, 0x80000000
        b       L10 # if (root == NULL) return 0x80000000;
L9: # root != NULL
        lw      $v0,48($fp)
        lw      $v1,4($v0) # v1 = root -> left
        lw      $v0,52($fp)
        addiu   $v0,$v0,1 # v0 = level + 1
        move    $a1,$v0
        move    $a0,$v1
        jal     even_level_max
        sw      $v0,24($fp) # fp[24] = left = even_level_max(root -> left, level +1)
        lw      $v0,48($fp)
        lw      $v1,8($v0) # v1 = root -> right
        lw      $v0,52($fp)
        addiu   $v0,$v0,1 # v0 = level + 1
        move    $a1,$v0
        move    $a0,$v1
        jal     even_level_max
        sw      $v0,28($fp) # fp[28] = right = even_level_max(root -> right, level + 1)
        lw      $v1,24($fp) # v1 = right
        lw      $v0,28($fp) # v0 = left
        slt     $a0,$v0,$v1 # a0 = v1 > v0 ? 0 : 1
        beq     $a0,$zero,L11
        move    $v0,$v1
L11:
        sw      $v0,32($fp) # fp[32] = greater
        lw      $v0,52($fp) # v0 = level
        andi    $v0,$v0,0x1 # v0 & 1
        bne     $v0,$zero,L12
        lw      $v0,48($fp) # v0 = root
        lw      $v1,0($v0) # v1 = data
        lw      $v0,32($fp)  # v0 = greater
        slt     $a0,$v0,$v1 # a0 = v1 > v0 ? 0 : 1
        beq     $a0,$zero,L10 # return greater
        move    $v0,$v1 # v0 = data
        b       L10 # return data
L12:
        lw      $v0,32($fp) # return greater
L10:
        # epilogue
        move    $sp,$fp
        lw      $ra,44($sp)
        lw      $fp,40($sp)
        addiu   $sp,$sp,48
        jr      $ra