3

We all know that usually a program will just return one value, but I have noticed that we have two value returning registers $v0 and $v1 in MIPS. The code I have seen all only have $v0 but $v1, and I haven't found any assembly language example code that uses $v1.

Could anyone tell me why we have two $v registers in MIPS and show me a example of when it could be used?

phuclv
  • 37,963
  • 15
  • 156
  • 475
Hang Chen
  • 549
  • 1
  • 7
  • 18
  • The CPU registers don't just have a single usage. Nearly all of the registers can be used internally by a function for just about any purpose; and the more of them you've got, the better. – Michael Oct 06 '13 at 15:01
  • possible duplicate of [Why MIPS assembler has more that one register for return value?](http://stackoverflow.com/questions/20131986/why-mips-assembler-has-more-that-one-register-for-return-value) – phuclv Jul 19 '15 at 03:17
  • 1
    examples where multiple return registers are used can easily been seen here [About returning more than one value in C/C++/Assembly](https://stackoverflow.com/q/31497152/995714) – phuclv Sep 26 '18 at 02:17

3 Answers3

4

There are lots of uses for that

  • Returning a value twice the length of the register (64-bit values in MIPS32 and 128-bit values in MIPS64) as @Martin Rosenau mentioned

    long long mult(int x, int y) {
        return  (long long)x * y;
    }
    

    Output assembly:

    mult(int, int):
        mult    $4,$5
        mflo    $2
        mfhi    $3
        j       $31
        nop
    
  • Returning structs that fit into 2 registers like these

    typedef struct {
        int a, b;
    } ret_struct2x32;
    
    ret_struct2x32 return_struct2x32() {
        return ret_struct2x32{2, 3};
    }
    
    typedef struct {
        short a, b, c, d;
    } ret_struct4x16;
    
    ret_struct4x16 return_struct4x16() {
        return ret_struct4x16{(short)2, (short)0, (short)3, (short)0};
    }
    

    or returning tuples that appear in some languages like python

    def func(x,y):
        # code to compute x and y
        return x,y
    
    a, b = 1, 2
    u, v = func(a, b)
    

    In C++ we have std::pair and std::tuple

    std::pair<int, int> return_pair()
    {
        return std::make_pair(2, 3);
    }
    
    std::tuple<short, short, short, short> return_tuple()
    {
        return std::make_tuple((short)2, (short)0, (short)3, (short)0);
    }
    

    See the demo on Compiler Explorer. Unfortunately the gcc version for MIPS is too old and can't make use the struct-in-register optimization, so look at the x86 output and you'll see that the whole tuples are returned in only a single instruction

It's similar to the pair (E/R)DX:(E/R)AX in x86 to return a value double the size of the registers

See also

phuclv
  • 37,963
  • 15
  • 156
  • 475
2

Another use case is returning 64-bit numbers on 32-bit MIPS (or 128-bit numbers in 64-bit MIPS).

Martin Rosenau
  • 17,897
  • 3
  • 19
  • 38
1

I can think of plenty of examples, but it's probably just up to your discretion. The best example is probably a function that returns a value in $v0 and may set an error code in $v1.

Konrad Lindenbach
  • 4,911
  • 1
  • 26
  • 28