Reputation: 35
Basically the title. I have a negative number in MIPS ISA and I want to make it positive - what is the best way to achieve it? Do I change the sign bit or something? Not entirely sure which route to take here.
For context, I'm trying to divide by 2 to get the number down to just 1, but this isn't possible if the nubmer is negative so I want to make it positive first in order to achieve this.
Upvotes: 2
Views: 10118
Reputation: 18503
I'd like to give some additional information (because Jester already gave the correct answer):
Do I change the sign bit or something?
There are different ways how negative numbers are stored:
Two's complement
This is the most common way integer numbers are stored because on most CPUs (including MIPS) integer operations (like addition, subtraction) will automatically give the correct result when using two's complement.
One's complement
This way of storing numbers is often used in the checksum calculation rules for internet protocols (IPv4, TCP, UDP...)
Absolute value and sign bit
Floating point numbers are typically stored this way.
Of course what you have to do depends on what kind of numbers you are processing.
How to make a negative number positive in MIPS?
Negative numbers are stored as two's complement (most likely for integers):
As Jester already wrote: Calculate 0-x
with subu $v0, $zero, $a0
.
You are calculating checksums for the internet (one's complement):
In this case you have to invert all bits. The best option on MIPS is nor $v0, $zero, $a0
.
You could instead x xor (-1)
or (-1)-x
. On MIPS CPUs, the value (-1) can be generated by one subiu
instruction. (But xori
uses an unsigned 0..65535 immediate.)
You are processing floating point numbers by using integer instructions and want to invert the sign:
In this case you have to change the sign bit.
This is done using x xor 0x80000000
.
On MIPS CPUs, you can generate the constant 0x80000000 using one lui
instruction.
(You would do this if you have a CPU without floating-point support and you have to emulate floating-point operations using integer operations. If you have a CPU with floating-point support, you would normally not do this. However, you could also do this if you first copy the floating-point register to an integer register using mfc1
and after the operation you copy the value back using mtc1
. Thanks @Alain Merigot for the annotation.)
You have a MIPS CPU or a MIPS emulator with floating-point support and want to negate a floating-point number:
You can use the instructions neg.s
(32-bit floating point) or neg.d
(64-bit floating point) to negate a number.
See what MIPS GCC does for all 3 of these, for integer inputs: https://godbolt.org/z/ca2nUE.
Upvotes: 2