Re: MIPS - Making a 64 bit number when you only have 32 bit register support

In summary, The user is having trouble finding a way to output a 64 bit number when adding two 32 bit numbers together. They have tried using various methods such as using an overflow register, allocating memory in the heap, and using shift operations, but have encountered difficulties with each approach. They are now considering using a divide method, with the help of an expert, to get the desired result.
  • #1
Kerren
9
0
Hey guys I've been working on this program for just over a week now and I just can't seem to find any way around my problem. The problem I'm having is:

I'm trying to add 32 bit numbers together and if there is an overflow then I'd like to find a way to output the result as a 64 bit number.

I had a couple of ideas (as of yet, none of them have worked :biggrin:) so here they are:

  1. My first bright idea :biggrin:
    I tried to add numbers together and when there was an overflow I'd increment another register (lets call it the "overflow" register). Once the calculation was done I would just output the overflow register next to the other register to make a "64 bit" number :smile: In theory this would work IF we were working in decimal (base 10) because when there is an overflow a digit is added to the front of the result, however, in binary there is not always a whole new digit added to the front of the result so this didn't work for me and I got some pretty funny answers :smile:!
  2. The second idea
    I tried to allocate 8 bytes in the heap memory block and just save the result to that. The problem I had is that I can't dereference that allocated memory in the actual add function. This means that I have to use an intermediate register for calculating the result and then I would copy this intermediate register to the allocated memory. This defeats the point of the allocated memory because the intermediate register is only 32 bits :smile:
  3. The third (untested) idea
    I want to read in an actual binary input and then I can shift the bits and if there is an overflow I add them to a new binary number (the overflow register) and then output both the overflow register and the result register together to form a 64 bit number. The problem I'm having is that I don't actually know how to make a binary variable (is there even such a thing as a "binary variable" :biggrin:??)
  4. The fourth idea
    I tried to use the $f register because it looks to me like they are 64 bit registers but it seems like they are private registers that I cannot access. Does anyone know any way around this?
  5. Other thoughts
    Is there any way to link registers together so that they can form virtual 64 bit ones (I know that's a really hopeful thought :smile:)?

    Also does anyone have any other ideas on how to make a 64 bit system using only 32 bit registers?

Thanks guys!

*** Edit ***
I originally posted this to the Electrical Engineering forum by mistake so I just copied it here :smile: 12/08/2012
 
Last edited:
Physics news on Phys.org
  • #2
MIPS doesn't have borrow or carry bits, so you have to code around this. If an 32 bit unsigned add would produce a carry, then the 32 bit lower sum will be less than either of the 32 lower order addends (input). You can use SLTU to take advantage of this fact. For subtract, you can use SLTU to check for a borrow condition in the low order registers. You'll want to use the unsigned add and subract instructions. For signed numbers you'll need to do an overflow check on the high order operation.
 
Last edited:
  • #3
Awesome thanks for the reply rcgldr :smile:! If I do take the overflow into account and add it to a new registry, is there even a way to correctly output the 64 bit number?

As in:

If I have two registers, a high and a low, and whenever there is an overflow then I increment the high register, is there a way to get the actual decimal result between these two registers?

Thanks :smile:!
 
  • #4
Kerren said:
If I do take the overflow into account
Overflow is only used for signed math, and for extended precision numbers would only be used for the most significant portion of signed numbers.

Kerren said:
Is there a way to get the actual decimal result between these two registers?
That would be more difficult. You would need to implement an extended divide operation. One way to implement this would be to split up a 64 bit number into four 16 bit numbers using the lower 16 bits of registers. After each divide step, the remainder is used as the upper 16 bits for the next divide step (for the first step, the upper 16 bits would be zero). An alternative would be to have a large table of 64 bit numbers that represent powers of ten and do repetitive subtractions.
 
  • #5
Awesome! I'm going to try dividing the number into 4X16 bit registers and see if I can make it work :smile:! Thanks so much for the help rcgldr :smile:!
 
  • #6
Kerren said:
Awesome! I'm going to try dividing the number into 4X16 bit registers and see if I can make it work.
Note, the simplified method I described only works when dividing the large number (64 bits in this case) by a number 16 bits or less in size. Since you want to convert the number to decimal, you could divide by 10 to get one digit at a time or divide by 10,000 to get 4 digits at a time (using the regular instructions to break up each set of 4 digits). Both 10 and 10,000 are less than 16 bit in size, so the simplified method will work.

Otherwise, to divide large numbers by large numbers, you'd need something like long hand division, where you make a "guess" at the quotient, and do a multiply and subtract step, iterating 2 or 3 times for each "word" of quotient. For really big numbers, there are complex algorithms based on Fourier Transforms, finite field (modulo) math, ..., to speed up the process, but I doubt you'd need any of this stuff for what you're doing with the MIPS projects.
 
Last edited:
  • #7
Hi rcgldr thanks so much for the help! Unfortunately I couldn't get the output to work so I switched to a different approach, I also made it a multiply instead of just an add function:

I made my result hi and result low registers the same as the mult hi and low registers.

In case anyone ever needs to know how here's a short explanation:

If we are to multiply 2 numbers in binary form there are many ways to do it without the mult function. Firstly if you want to do something like 8x5 you could add 8 to a result 5 times ie 8x5 = 8 + 8 + 8 + 8 + 8. Another way to do it is to loop through the binary representation of the number and every time you go through the loop - shift the multiplicand by one bit, now look at the multiplier, if the multiplier bit is 1 then add it to the result otherwise skip the add and continue the loop. Example:

13t7_c3e_uveb.jpg


So this is all great and it works like a charm!... for small numbers, but what happens when you shift a binary number 30 times or more??

What you need is a high register for your multiplicand, when you shift it too high you need to shift it into this high register. You can actually add this high register to the result high register right from the start of the loop because at the start this "multiplicand high register" will be zero so you will effectively be adding nothing.

That takes care of the multiplicand being shifted too much, another problem can occur when the result register actually has a carry bit. In this case you just add 1 to the result high register. Why? Because you need to add a bit to the high register and one bit is [itex]2^0 = 1[/itex].

A couple of the functions used are:
addu $lowReg, $lowReg, $multiplicandReg Add the shifted multiplicand to the low register
sll $multiplicandReg, 1 This shifts the multiplicand left by 1 bit
and $t0, $multiplier, 1 Check if the least significant bit is a 1
srl $multiplier, 1 Once you've checked if it's a 1 or 0 you can shift that bit off the register

There are a couple of others but those are the main ones that should allow for 2 numbers that are pretty small to easily multiply.
 
  • #8
Kerren said:
when the result register actually has a carry bit.
This gets back to the issue that the MIPS doesn't have a carry (or borrow if subtract) bit. You need to use the method I mentioned in my first reply to work around this.

If you store large integers using only 16 bits of each 32 bit register, you can use the multiply instruction to do multiplies. The method is similar to doing long hand multiplication. After a multiply step to produce a set of intermediate product terms, the upper 16 bits of a low order word get added to the lower 16 bits of the next higher order word (then those upper 16 bits in the low order word are zeroed out), looping through all the words used to hold the product.
 
Last edited:

1. How do you make a 64 bit number with only 32 bit register support?

To make a 64 bit number with only 32 bit register support, you can use a technique called "register pair" or "double register". This involves using two 32 bit registers to store the upper and lower halves of the 64 bit number. By combining the values in these two registers, you can create a 64 bit number.

2. What is the purpose of having 32 bit register support?

32 bit register support is typically used in computer processors to store and manipulate data. It allows for faster processing and more efficient use of memory. It is also a common standard in many computer architectures.

3. Can 64 bit numbers be stored in a single 32 bit register?

No, a single 32 bit register can only hold numbers up to 2^32-1, which is approximately 4.3 billion. 64 bit numbers are much larger than this and require 64 bit register support or a combination of two 32 bit registers.

4. Are there any limitations to using register pair to make a 64 bit number?

There are some limitations to using register pair to make a 64 bit number. One limitation is that it requires extra instructions and processing time to combine the values in the two registers. Additionally, if the processor does not support register pair, alternative methods must be used.

5. Can a 64 bit number be stored in a 32 bit computer?

No, a 64 bit number cannot be stored in a 32 bit computer as it exceeds the maximum value that can be stored in a 32 bit register. However, some computer architectures have the ability to use multiple 32 bit registers to store and manipulate 64 bit numbers.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
4
Views
3K
Replies
1
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
6K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
1K
  • Programming and Computer Science
Replies
30
Views
4K
  • Engineering and Comp Sci Homework Help
Replies
7
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
13
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
6K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
2K
  • Sticky
  • Programming and Computer Science
Replies
13
Views
4K
Back
Top