From 714313b4828cec98b086b54b356407540aa775c4 Mon Sep 17 00:00:00 2001 From: Jack Carter Date: Tue, 28 Aug 2012 20:07:41 +0000 Subject: The instruction DEXT may be transformed into DEXTU 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@162782 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsMCInstLower.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'lib/Target/Mips/MipsMCInstLower.cpp') diff --git a/lib/Target/Mips/MipsMCInstLower.cpp b/lib/Target/Mips/MipsMCInstLower.cpp index d4c5e6d..d65e74d 100644 --- a/lib/Target/Mips/MipsMCInstLower.cpp +++ b/lib/Target/Mips/MipsMCInstLower.cpp @@ -189,3 +189,38 @@ void MipsMCInstLower::LowerLargeShift(const MachineInstr *MI, break; } } + +// Pick a DEXT instruction variant based on the pos and size operands +void MipsMCInstLower::LowerDEXT(const MachineInstr *MI, MCInst& Inst) { + + 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()); + int64_t size = MI->getOperand(3).getImm(); + + // rt + Inst.addOperand(LowerOperand(MI->getOperand(0))); + // 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 { + Inst.addOperand(MCOperand::CreateImm(pos)); + Inst.addOperand(MCOperand::CreateImm(size - 32)); + Inst.setOpcode(Mips::DEXTM); + } + return; +} -- cgit v1.1 From 3185f9a2ea80afec30064b7cd095f82c31dc154e Mon Sep 17 00:00:00 2001 From: Jack Carter Date: Fri, 31 Aug 2012 18:06:48 +0000 Subject: 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 --- lib/Target/Mips/MipsMCInstLower.cpp | 42 ++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'lib/Target/Mips/MipsMCInstLower.cpp') diff --git a/lib/Target/Mips/MipsMCInstLower.cpp b/lib/Target/Mips/MipsMCInstLower.cpp index d65e74d..674bce3 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; } -- cgit v1.1 From a7570a3d8686a1fe2075b5bee01650490fa52b26 Mon Sep 17 00:00:00 2001 From: Jack Carter Date: Thu, 6 Sep 2012 02:31:34 +0000 Subject: There are some Mips instructions that are lowered by the assembler such as shifts greater than 32. In the case of direct object, the code gen needs to do this lowering since the assembler is not involved. With the advent of the llvm-mc assembler, it also needs to do the same lowering. This patch makes that specific lowering code accessible to both the direct object output and the assembler. This patch does not affect generated output. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163287 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsMCInstLower.cpp | 68 ------------------------------------- 1 file changed, 68 deletions(-) (limited to 'lib/Target/Mips/MipsMCInstLower.cpp') diff --git a/lib/Target/Mips/MipsMCInstLower.cpp b/lib/Target/Mips/MipsMCInstLower.cpp index 674bce3..5fa6339 100644 --- a/lib/Target/Mips/MipsMCInstLower.cpp +++ b/lib/Target/Mips/MipsMCInstLower.cpp @@ -160,71 +160,3 @@ void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { } } -// If the D instruction has a shift amount that is greater -// than 31 (checked in calling routine), lower it to a D32 instruction -void MipsMCInstLower::LowerLargeShift(const MachineInstr *MI, - MCInst& Inst, - int64_t Shift) { - // rt - Inst.addOperand(LowerOperand(MI->getOperand(0))); - // rd - Inst.addOperand(LowerOperand(MI->getOperand(1))); - // saminus32 - Inst.addOperand(MCOperand::CreateImm(Shift)); - - switch (MI->getOpcode()) { - default: - // Calling function is not synchronized - llvm_unreachable("Unexpected shift instruction"); - break; - case Mips::DSLL: - Inst.setOpcode(Mips::DSLL32); - break; - case Mips::DSRL: - Inst.setOpcode(Mips::DSRL32); - break; - case Mips::DSRA: - Inst.setOpcode(Mips::DSRA32); - break; - } -} - -// 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->getOperand(2).isImm()); - int64_t pos = MI->getOperand(2).getImm(); - assert(MI->getOperand(3).isImm()); - int64_t size = MI->getOperand(3).getImm(); - - // rt - Inst.addOperand(LowerOperand(MI->getOperand(0))); - // rs - Inst.addOperand(LowerOperand(MI->getOperand(1))); - - 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); - } -} -- cgit v1.1