I have the follow instruction, and I don't understand why the PCSPIM is giving me the following warning:
spim:(parser) immediate value (61440) out of rainge (-32768..32767)
on line 88 of file
addiu $a, $zero, 0xF000
^
I according to the ISA, I should have
Description: Adds a register and a sign-extended immediate value and
stores the result in a register
Operation: $t = $s + imm; advance_pc(4);
Syntax: addiu $t, $s, imm
Encoding: 0010 01ss ssst tttt iiii iiii iiii iiii
If I convert addiu $a0, $zero, 0xF000 into machine code I would have
opcode | rs | rt | imm val
-------+-----+------+--------------------
0010 01|00 00|0 0100| 1111 0000 0000 0000
which should fit the instruction
I assume you meant something like this:
addiu $a0,$zero,0xF000
This is a quirk of spim
because it is not treating this as a pseudo-op. But, given this, it is correct to flag this.
Regardless of whether you use addi
or addiu
they both have the same signed range of -32768 to 32767
. The only difference is whether the instruction will generate an exception on integer overflow. That is, both instructions will do sign extend on the immediate value and not do sign extend for addi
and zero extend for addiu
.
Your value 0xF000
is 61440 [decimal] which is outside the allowable range for the instructions. In both cases, you'll get a sign extended value of 0xFFFFF000
spim
saw the 0xF000
and recognized that you wanted to add 0x0000F000
and not 0xFFFFF000
but wouldn't automatically generate the code because it treated the addiu
as a low level literal instruction.
On the other hand, mars
does treat this as a pseudo-op and generates:
lui $at,0
ori $at,$at,0xF000
addu $a0,$zero,$at
It recognizes that you want an unsigned operation, so it has to generate instructions that produce a true unsigned addition using addu
However, if you rewrite your original as:
addu $a0,$zero,0xF000
Now, spim
will treat this as a pseudo-op and generate:
ori $a0,$zero,-4096
And, mars
is happy with that rewrite as well