[mips][msa] Fix issue with immediate fields of LD/ST instructions

not being correctly encoded/decoded.
In more detail, immediate fields of LD/ST instructions should be
divided/multiplied by the size of the data format before encoding and
after decoding, respectively.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196494 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Matheus Almeida
2013-12-05 11:06:22 +00:00
parent 52123d1842
commit 4faa2b38fb
6 changed files with 173 additions and 29 deletions

View File

@ -565,7 +565,37 @@ static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
Inst.addOperand(MCOperand::CreateReg(Reg));
Inst.addOperand(MCOperand::CreateReg(Base));
Inst.addOperand(MCOperand::CreateImm(Offset));
// The immediate field of an LD/ST instruction is scaled which means it must
// be multiplied (when decoding) by the size (in bytes) of the instructions'
// data format.
// .b - 1 byte
// .h - 2 bytes
// .w - 4 bytes
// .d - 8 bytes
switch(Inst.getOpcode())
{
default:
assert (0 && "Unexpected instruction");
return MCDisassembler::Fail;
break;
case Mips::LD_B:
case Mips::ST_B:
Inst.addOperand(MCOperand::CreateImm(Offset));
break;
case Mips::LD_H:
case Mips::ST_H:
Inst.addOperand(MCOperand::CreateImm(Offset << 1));
break;
case Mips::LD_W:
case Mips::ST_W:
Inst.addOperand(MCOperand::CreateImm(Offset << 2));
break;
case Mips::LD_D:
case Mips::ST_D:
Inst.addOperand(MCOperand::CreateImm(Offset << 3));
break;
}
return MCDisassembler::Success;
}