summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDaniel Sanders <daniel.sanders@imgtec.com>2014-03-24 14:05:39 +0000
committerDaniel Sanders <daniel.sanders@imgtec.com>2014-03-24 14:05:39 +0000
commita771fefb72a052b2f15b3ef65ffc7a0b1a9a525b (patch)
treec8f5c944de9d437282f7a8ab610ee845129202ce /llvm/lib
parent227f5ed5473fcf076f664574ab69af9f07f9554b (diff)
downloadbcm5719-llvm-a771fefb72a052b2f15b3ef65ffc7a0b1a9a525b.tar.gz
bcm5719-llvm-a771fefb72a052b2f15b3ef65ffc7a0b1a9a525b.zip
[mips] Implement shorthand add / sub forms for MIPS.
Summary: - If only two registers are passed to a three-register operation, then the first argument is both source and destination register. - If a non-register is passed as the last argument, generate the immediate version of the instruction. Also mark DADD commutative and add scheduling information (to the generic scheduler), and implement DSUB. Patch by David Chisnall His work was sponsored by: DARPA, AFRL CC: theraven Differential Revision: http://llvm-reviews.chandlerc.com/D3148 llvm-svn: 204605
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp30
-rw-r--r--llvm/lib/Target/Mips/Mips64InstrInfo.td61
-rw-r--r--llvm/lib/Target/Mips/MipsSchedule.td4
3 files changed, 94 insertions, 1 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 8912243af09..8c0c181feca 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -16,6 +16,7 @@
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCStreamer.h"
@@ -589,6 +590,7 @@ static const MCInstrDesc &getInstDesc(unsigned Opcode) {
bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
SmallVectorImpl<MCInst> &Instructions) {
const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
+
Inst.setLoc(IDLoc);
if (MCID.isBranch() || MCID.isCall()) {
@@ -690,6 +692,10 @@ bool MipsAsmParser::needsExpansion(MCInst &Inst) {
case Mips::LoadImm32Reg:
case Mips::LoadAddr32Imm:
case Mips::LoadAddr32Reg:
+ case Mips::SUBi:
+ case Mips::SUBiu:
+ case Mips::DSUBi:
+ case Mips::DSUBiu:
return true;
default:
return false;
@@ -705,6 +711,30 @@ void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
return expandLoadAddressImm(Inst, IDLoc, Instructions);
case Mips::LoadAddr32Reg:
return expandLoadAddressReg(Inst, IDLoc, Instructions);
+ case Mips::SUBi:
+ Instructions.push_back(MCInstBuilder(Mips::ADDi)
+ .addReg(Inst.getOperand(0).getReg())
+ .addReg(Inst.getOperand(1).getReg())
+ .addImm(-Inst.getOperand(2).getImm()));
+ return;
+ case Mips::SUBiu:
+ Instructions.push_back(MCInstBuilder(Mips::ADDiu)
+ .addReg(Inst.getOperand(0).getReg())
+ .addReg(Inst.getOperand(1).getReg())
+ .addImm(-Inst.getOperand(2).getImm()));
+ return;
+ case Mips::DSUBi:
+ Instructions.push_back(MCInstBuilder(Mips::DADDi)
+ .addReg(Inst.getOperand(0).getReg())
+ .addReg(Inst.getOperand(1).getReg())
+ .addImm(-Inst.getOperand(2).getImm()));
+ return;
+ case Mips::DSUBiu:
+ Instructions.push_back(MCInstBuilder(Mips::DADDiu)
+ .addReg(Inst.getOperand(0).getReg())
+ .addReg(Inst.getOperand(1).getReg())
+ .addImm(-Inst.getOperand(2).getImm()));
+ return;
}
}
diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td
index 06a6c1ca521..74cafa8e415 100644
--- a/llvm/lib/Target/Mips/Mips64InstrInfo.td
+++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td
@@ -73,11 +73,12 @@ def LUi64 : LoadUpper<"lui", GPR64Opnd, uimm16_64>, LUI_FM;
}
/// Arithmetic Instructions (3-Operand, R-Type)
-def DADD : ArithLogicR<"dadd", GPR64Opnd>, ADD_FM<0, 0x2c>;
+def DADD : ArithLogicR<"dadd", GPR64Opnd, 1, II_DADD>, ADD_FM<0, 0x2c>;
def DADDu : ArithLogicR<"daddu", GPR64Opnd, 1, II_DADDU, add>,
ADD_FM<0, 0x2d>;
def DSUBu : ArithLogicR<"dsubu", GPR64Opnd, 0, II_DSUBU, sub>,
ADD_FM<0, 0x2f>;
+def DSUB : ArithLogicR<"dsub", GPR64Opnd, 0, II_DSUB, sub>, ADD_FM<0, 0x2e>;
let isCodeGenOnly = 1 in {
def SLT64 : SetCC_R<"slt", setlt, GPR64Opnd>, ADD_FM<0, 0x2a>;
@@ -356,6 +357,64 @@ def : InstAlias<"daddu $rs, $rt, $imm",
def : InstAlias<"dadd $rs, $rt, $imm",
(DADDi GPR64Opnd:$rs, GPR64Opnd:$rt, simm16_64:$imm),
0>;
+def : InstAlias<"daddu $rs, $imm",
+ (DADDiu GPR64Opnd:$rs, GPR64Opnd:$rs, simm16_64:$imm),
+ 0>;
+def : InstAlias<"dadd $rs, $imm",
+ (DADDi GPR64Opnd:$rs, GPR64Opnd:$rs, simm16_64:$imm),
+ 0>;
+def : InstAlias<"dadd $rs, $rt",
+ (DADD GPR64Opnd:$rs, GPR64Opnd:$rs, GPR64Opnd:$rt),
+ 0>;
+def : InstAlias<"daddu $rs, $rt",
+ (DADDu GPR64Opnd:$rs, GPR64Opnd:$rs, GPR64Opnd:$rt),
+ 0>;
+def : InstAlias<"dsub $rs, $rt",
+ (DSUB GPR64Opnd:$rs, GPR64Opnd:$rs, GPR64Opnd:$rt),
+ 0>;
+def : InstAlias<"dsubu $rs, $rt",
+ (DSUBu GPR64Opnd:$rs, GPR64Opnd:$rs, GPR64Opnd:$rt),
+ 0>;
+def : InstAlias<"add $rs, $imm",
+ (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm),
+ 0>;
+def : InstAlias<"addu $rs, $imm",
+ (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm),
+ 0>;
+def : InstAlias<"add $rs, $rt",
+ (ADD GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt),
+ 0>;
+def : InstAlias<"addu $rs, $rt",
+ (ADDu GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt),
+ 0>;
+def : InstAlias<"sub $rs, $rt",
+ (SUB GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt),
+ 0>;
+def : InstAlias<"subu $rs, $rt",
+ (SUBu GPR32Opnd:$rs, GPR32Opnd:$rs, GPR32Opnd:$rt),
+ 0>;
+let isPseudo=1, usesCustomInserter=1, isCodeGenOnly=1 in {
+def SUBi : MipsInst<(outs GPR32Opnd: $rt), (ins GPR32Opnd: $rs, simm16: $imm),
+ "sub\t$rt, $rs, $imm", [], II_DSUB, Pseudo>;
+def SUBiu : MipsInst<(outs GPR32Opnd: $rt), (ins GPR32Opnd: $rs, simm16: $imm),
+ "subu\t$rt, $rs, $imm", [], II_DSUB, Pseudo>;
+def DSUBi : MipsInst<(outs GPR64Opnd: $rt), (ins GPR64Opnd: $rs, simm16_64: $imm),
+ "ssub\t$rt, $rs, $imm", [], II_DSUB, Pseudo>;
+def DSUBiu : MipsInst<(outs GPR64Opnd: $rt), (ins GPR64Opnd: $rs, simm16_64: $imm),
+ "ssubu\t$rt, $rs, $imm", [], II_DSUB, Pseudo>;
+}
+def : InstAlias<"sub $rs, $imm",
+ (SUBi GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm),
+ 0>;
+def : InstAlias<"subu $rs, $imm",
+ (SUBiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm16:$imm),
+ 0>;
+def : InstAlias<"dsub $rs, $imm",
+ (DSUBi GPR64Opnd:$rs, GPR64Opnd:$rs, simm16_64:$imm),
+ 0>;
+def : InstAlias<"dsubu $rs, $imm",
+ (DSUBiu GPR64Opnd:$rs, GPR64Opnd:$rs, simm16_64:$imm),
+ 0>;
/// Move between CPU and coprocessor registers
let DecoderNamespace = "Mips64", Predicates = [HasMips64] in {
diff --git a/llvm/lib/Target/Mips/MipsSchedule.td b/llvm/lib/Target/Mips/MipsSchedule.td
index e2fef8f94c6..ea981996bf1 100644
--- a/llvm/lib/Target/Mips/MipsSchedule.td
+++ b/llvm/lib/Target/Mips/MipsSchedule.td
@@ -39,6 +39,7 @@ def II_C_CC_D : InstrItinClass; // Any c.<cc>.d instruction
def II_C_CC_S : InstrItinClass; // Any c.<cc>.s instruction
def II_DADDIU : InstrItinClass;
def II_DADDU : InstrItinClass;
+def II_DADD : InstrItinClass;
def II_DDIV : InstrItinClass;
def II_DDIVU : InstrItinClass;
def II_DIV : InstrItinClass;
@@ -63,6 +64,7 @@ def II_DSRL : InstrItinClass;
def II_DSRL32 : InstrItinClass;
def II_DSRLV : InstrItinClass;
def II_DSUBU : InstrItinClass;
+def II_DSUB : InstrItinClass;
def II_FLOOR : InstrItinClass;
def II_LB : InstrItinClass;
def II_LBU : InstrItinClass;
@@ -185,6 +187,7 @@ def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [
InstrItinData<II_CLZ , [InstrStage<1, [ALU]>]>,
InstrItinData<II_DADDIU , [InstrStage<1, [ALU]>]>,
InstrItinData<II_DADDU , [InstrStage<1, [ALU]>]>,
+ InstrItinData<II_DADD , [InstrStage<1, [ALU]>]>,
InstrItinData<II_DSLL , [InstrStage<1, [ALU]>]>,
InstrItinData<II_DSRL , [InstrStage<1, [ALU]>]>,
InstrItinData<II_DSRA , [InstrStage<1, [ALU]>]>,
@@ -192,6 +195,7 @@ def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [
InstrItinData<II_DSRLV , [InstrStage<1, [ALU]>]>,
InstrItinData<II_DSRAV , [InstrStage<1, [ALU]>]>,
InstrItinData<II_DSUBU , [InstrStage<1, [ALU]>]>,
+ InstrItinData<II_DSUB , [InstrStage<1, [ALU]>]>,
InstrItinData<II_DROTR , [InstrStage<1, [ALU]>]>,
InstrItinData<II_DROTRV , [InstrStage<1, [ALU]>]>,
InstrItinData<II_LUI , [InstrStage<1, [ALU]>]>,
OpenPOWER on IntegriCloud