summaryrefslogtreecommitdiff
path: root/lib/Target
diff options
context:
space:
mode:
authorReed Kotler <rkotler@mips.com>2012-10-05 18:27:54 +0000
committerReed Kotler <rkotler@mips.com>2012-10-05 18:27:54 +0000
commitdfb8dbb4fd97140aa9bf6b9dadbca25665144c09 (patch)
tree350252ce20358062ff81809484bc66cf93ccec76 /lib/Target
parentebd7eabca4c090175b71f221e880f8bd937a4523 (diff)
downloadllvm-dfb8dbb4fd97140aa9bf6b9dadbca25665144c09.tar.gz
llvm-dfb8dbb4fd97140aa9bf6b9dadbca25665144c09.tar.bz2
llvm-dfb8dbb4fd97140aa9bf6b9dadbca25665144c09.tar.xz
Patch for integer multiply, signed/unsigned, long/long long.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165322 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/Mips/Mips16InstrInfo.td83
-rw-r--r--lib/Target/Mips/MipsISelDAGToDAG.cpp32
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp6
3 files changed, 104 insertions, 17 deletions
diff --git a/lib/Target/Mips/Mips16InstrInfo.td b/lib/Target/Mips/Mips16InstrInfo.td
index b866a5d225..77126bb652 100644
--- a/lib/Target/Mips/Mips16InstrInfo.td
+++ b/lib/Target/Mips/Mips16InstrInfo.td
@@ -10,7 +10,19 @@
// This file describes Mips16 instructions.
//
//===----------------------------------------------------------------------===//
-
+//
+// This are pseudo formats for multiply
+// This first one can be changed to non pseudo now.
+//fmul
+class FMULT16_ins<string asmstr, InstrItinClass itin> :
+ MipsPseudo16<(outs), (ins CPU16Regs:$rx, CPU16Regs:$ry),
+ !strconcat(asmstr, "\t$rx, $ry"), []>;
+
+class FMULT16_LO_ins<string asmstr, InstrItinClass itin> :
+ MipsPseudo16<(outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
+ !strconcat(asmstr, "\t$rx, $ry\n\tmflo\t$rz"), []> {
+ let isCodeGenOnly=1;
+}
//
// RRR-type instruction format
//
@@ -43,7 +55,11 @@ class FRR16_ins<bits<5> f, string asmstr, InstrItinClass itin> :
FRR16<f, (outs CPU16Regs:$rx), (ins CPU16Regs:$ry),
!strconcat(asmstr, "\t$rx, $ry"), [], itin> {
}
-
+class FRR16_M_ins<bits<5> f, string asmstr,
+ InstrItinClass itin> :
+ FRR16<f, (outs CPU16Regs:$rx), (ins),
+ !strconcat(asmstr, "\t$rx"), [], itin>;
+
class FRxRxRy16_ins<bits<5> f, string asmstr,
InstrItinClass itin> :
FRR16<f, (outs CPU16Regs:$rz), (ins CPU16Regs:$rx, CPU16Regs:$ry),
@@ -81,14 +97,13 @@ class FEXT_2RI16_ins<bits<5> _op, string asmstr,
!strconcat(asmstr, "\t$rx, $imm"), [], itin> {
let Constraints = "$rx_ = $rx";
}
+
// this has an explicit sp argument that we ignore to work around a problem
// in the compiler
class FEXT_RI16_SP_explicit_ins<bits<5> _op, string asmstr,
InstrItinClass itin>:
FEXT_RI16<_op, (outs CPU16Regs:$rx), (ins CPUSPReg:$ry, simm16:$imm),
- !strconcat(asmstr, "\t$rx, $imm ( $ry ); "), [], itin> {
-}
-
+ !strconcat(asmstr, "\t$rx, $imm ( $ry ); "), [], itin>;
//
// EXT-RRI instruction format
@@ -245,6 +260,63 @@ def Move32R16: FI8_MOV32R16_ins<"move", IIAlu>;
def MoveR3216: FI8_MOVR3216_ins<"move", IIAlu>;
//
+// Format: MFHI rx MIPS16e
+// Purpose: Move From HI Register
+// To copy the special purpose HI register to a GPR.
+//
+def Mfhi16: FRR16_M_ins<0b10000, "mfhi", IIAlu> {
+ let Uses = [HI];
+ let neverHasSideEffects = 1;
+}
+
+//
+// Format: MFLO rx MIPS16e
+// Purpose: Move From LO Register
+// To copy the special purpose LO register to a GPR.
+//
+def Mflo16: FRR16_M_ins<0b10010, "mflo", IIAlu> {
+ let Uses = [LO];
+ let neverHasSideEffects = 1;
+}
+
+//
+// Pseudo Instruction for mult
+//
+def MultRxRy16: FMULT16_ins<"mult", IIAlu> {
+ let isCommutable = 1;
+ let neverHasSideEffects = 1;
+ let Defs = [HI, LO];
+}
+
+def MultuRxRy16: FMULT16_ins<"multu", IIAlu> {
+ let isCommutable = 1;
+ let neverHasSideEffects = 1;
+ let Defs = [HI, LO];
+}
+
+//
+// Format: MULT rx, ry MIPS16e
+// Purpose: Multiply Word
+// To multiply 32-bit signed integers.
+//
+def MultRxRyRz16: FMULT16_LO_ins<"mult", IIAlu> {
+ let isCommutable = 1;
+ let neverHasSideEffects = 1;
+ let Defs = [HI, LO];
+}
+
+//
+// Format: MULTU rx, ry MIPS16e
+// Purpose: Multiply Unsigned Word
+// To multiply 32-bit unsigned integers.
+//
+def MultuRxRyRz16: FMULT16_LO_ins<"multu", IIAlu> {
+ let isCommutable = 1;
+ let neverHasSideEffects = 1;
+ let Defs = [HI, LO];
+}
+
+//
// Format: NEG rx, ry MIPS16e
// Purpose: Negate
// To negate an integer value.
@@ -413,6 +485,7 @@ class ArithLogic16_pat<SDNode OpNode, Instruction I> :
def: ArithLogic16_pat<add, AdduRxRyRz16>;
def: ArithLogic16_pat<and, AndRxRxRy16>;
+def: ArithLogic16_pat<mul, MultRxRyRz16>;
def: ArithLogic16_pat<or, OrRxRxRy16>;
def: ArithLogic16_pat<sub, SubuRxRyRz16>;
def: ArithLogic16_pat<xor, XorRxRxRy16>;
diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp
index ceff6dd9b9..fceb63a1bc 100644
--- a/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -372,14 +372,16 @@ MipsDAGToDAGISel::SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl, EVT Ty,
SDValue InFlag = SDValue(Mul, 0);
if (HasLo) {
- Lo = CurDAG->getMachineNode(Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64, dl,
- Ty, MVT::Glue, InFlag);
+ unsigned Opcode = Subtarget.inMips16Mode() ? Mips::Mflo16 :
+ (Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64);
+ Lo = CurDAG->getMachineNode(Opcode, dl, Ty, MVT::Glue, InFlag);
InFlag = SDValue(Lo, 1);
}
- if (HasHi)
- Hi = CurDAG->getMachineNode(Ty == MVT::i32 ? Mips::MFHI : Mips::MFHI64, dl,
- Ty, InFlag);
-
+ if (HasHi) {
+ unsigned Opcode = Subtarget.inMips16Mode() ? Mips::Mfhi16 :
+ (Ty == MVT::i32 ? Mips::MFHI : Mips::MFHI64);
+ Hi = CurDAG->getMachineNode(Opcode, dl, Ty, InFlag);
+ }
return std::make_pair(Lo, Hi);
}
@@ -443,8 +445,13 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
/// Mul with two results
case ISD::SMUL_LOHI:
case ISD::UMUL_LOHI: {
- if (NodeTy == MVT::i32)
- MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT);
+ if (NodeTy == MVT::i32) {
+ if (Subtarget.inMips16Mode())
+ MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MultuRxRy16 :
+ Mips::MultRxRy16);
+ else
+ MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT);
+ }
else
MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::DMULTu : Mips::DMULT);
@@ -470,8 +477,13 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
}
case ISD::MULHS:
case ISD::MULHU: {
- if (NodeTy == MVT::i32)
- MultOpc = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT);
+ if (NodeTy == MVT::i32) {
+ if (Subtarget.inMips16Mode())
+ MultOpc = (Opcode == ISD::MULHU ?
+ Mips::MultuRxRy16 : Mips::MultRxRy16);
+ else
+ MultOpc = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT);
+ }
else
MultOpc = (Opcode == ISD::MULHU ? Mips::DMULTu : Mips::DMULT);
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index d8097032ca..362317b282 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -1746,8 +1746,10 @@ SDValue MipsTargetLowering::LowerBlockAddress(SDValue Op,
if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) {
// %hi/%lo relocation
- SDValue BAHi = DAG.getTargetBlockAddress(BA, MVT::i32, 0, MipsII::MO_ABS_HI);
- SDValue BALo = DAG.getTargetBlockAddress(BA, MVT::i32, 0, MipsII::MO_ABS_LO);
+ SDValue BAHi =
+ DAG.getTargetBlockAddress(BA, MVT::i32, 0, MipsII::MO_ABS_HI);
+ SDValue BALo =
+ DAG.getTargetBlockAddress(BA, MVT::i32, 0, MipsII::MO_ABS_LO);
SDValue Hi = DAG.getNode(MipsISD::Hi, dl, MVT::i32, BAHi);
SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, BALo);
return DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, Lo);