diff options
| author | Jack Carter <jcarter@mips.com> | 2012-08-31 18:06:48 +0000 |
|---|---|---|
| committer | Jack Carter <jcarter@mips.com> | 2012-08-31 18:06:48 +0000 |
| commit | 3185f9a2ea80afec30064b7cd095f82c31dc154e (patch) | |
| tree | 00e44379ea6fc446b71b0e8fcba494ef4996add7 /lib/Target/Mips/MipsMCInstLower.cpp | |
| parent | e4fb6eae9997e80bfedb251ca3251cbed884d4ff (diff) | |
The instruction DINS may be transformed into DINSU or DEXTM depending
on the size of the extraction and its position in the 64 bit word.
This patch allows support of the dext transformations with mips64 direct
object output.
0 <= msb < 32 0 <= lsb < 32 0 <= pos < 32 1 <= size <= 32
DINS
The field is entirely contained in the right-most word of the doubleword
32 <= msb < 64 0 <= lsb < 32 0 <= pos < 32 2 <= size <= 64
DINSM
The field straddles the words of the doubleword
32 <= msb < 64 32 <= lsb < 64 32 <= pos < 64 1 <= size <= 32
DINSU
The field is entirely contained in the left-most word of the doubleword
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163010 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/Mips/MipsMCInstLower.cpp')
| -rw-r--r-- | lib/Target/Mips/MipsMCInstLower.cpp | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/lib/Target/Mips/MipsMCInstLower.cpp b/lib/Target/Mips/MipsMCInstLower.cpp index d65e74d2c5..674bce30a5 100644 --- a/lib/Target/Mips/MipsMCInstLower.cpp +++ b/lib/Target/Mips/MipsMCInstLower.cpp @@ -11,7 +11,6 @@ // MCInst records. // //===----------------------------------------------------------------------===// - #include "MipsMCInstLower.h" #include "MipsAsmPrinter.h" #include "MipsInstrInfo.h" @@ -190,10 +189,17 @@ void MipsMCInstLower::LowerLargeShift(const MachineInstr *MI, } } -// Pick a DEXT instruction variant based on the pos and size operands -void MipsMCInstLower::LowerDEXT(const MachineInstr *MI, MCInst& Inst) { +// Pick a DEXT or DINS instruction variant based on the pos and size operands +void MipsMCInstLower::LowerDextDins(const MachineInstr *MI, MCInst& Inst) { + int Opcode = MI->getOpcode(); + + if (Opcode == Mips::DEXT) + assert(MI->getNumOperands() == 4 && + "Invalid no. of machine operands for DEXT!"); + else // Only DEXT and DINS are possible + assert(MI->getNumOperands() == 5 && + "Invalid no. of machine operands for DINS!"); - assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands for DEXT!"); assert(MI->getOperand(2).isImm()); int64_t pos = MI->getOperand(2).getImm(); assert(MI->getOperand(3).isImm()); @@ -204,23 +210,21 @@ void MipsMCInstLower::LowerDEXT(const MachineInstr *MI, MCInst& Inst) { // rs Inst.addOperand(LowerOperand(MI->getOperand(1))); - // DEXT - if ((pos < 32) && (size <= 32)) { - Inst.addOperand(MCOperand::CreateImm(pos)); - Inst.addOperand(MCOperand::CreateImm(size)); - Inst.setOpcode(Mips::DEXT); - } - // DEXTU - else if ((pos < 64) && (size <= 32)) { - Inst.addOperand(MCOperand::CreateImm(pos - 32)); - Inst.addOperand(MCOperand::CreateImm(size)); - Inst.setOpcode(Mips::DEXTU); - } - // DEXTM - else { + if (size <= 32) { + if ((pos < 32)) { // DEXT/DINS + Inst.addOperand(MCOperand::CreateImm(pos)); + Inst.addOperand(MCOperand::CreateImm(size)); + Inst.setOpcode(Opcode); + } else { // DEXTU/DINSU + Inst.addOperand(MCOperand::CreateImm(pos - 32)); + Inst.addOperand(MCOperand::CreateImm(size)); + Inst.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU); + } + } else { // DEXTM/DINSM + assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32"); Inst.addOperand(MCOperand::CreateImm(pos)); Inst.addOperand(MCOperand::CreateImm(size - 32)); Inst.setOpcode(Mips::DEXTM); + Inst.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM); } - return; } |
