summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDylan McKay <me@dylanmckay.io>2017-05-01 09:48:55 +0000
committerDylan McKay <me@dylanmckay.io>2017-05-01 09:48:55 +0000
commit59e7fe3da8092e7dfb13376b959418bb507eaf87 (patch)
tree7ecf9a6b8d7e46e71aef2aeff38e869e13781590 /llvm/lib
parent4064dc76c52d9eefcf8026f2c8b91d67f470e86d (diff)
downloadbcm5719-llvm-59e7fe3da8092e7dfb13376b959418bb507eaf87.tar.gz
bcm5719-llvm-59e7fe3da8092e7dfb13376b959418bb507eaf87.zip
[AVR] Implement non-constant bit rotations
This lets us do bit rotations of variable amount. llvm-svn: 301794
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AVR/AVRISelLowering.cpp31
-rw-r--r--llvm/lib/Target/AVR/AVRISelLowering.h2
-rw-r--r--llvm/lib/Target/AVR/AVRInstrInfo.td31
3 files changed, 63 insertions, 1 deletions
diff --git a/llvm/lib/Target/AVR/AVRISelLowering.cpp b/llvm/lib/Target/AVR/AVRISelLowering.cpp
index 0b95d381939..f0ab6acedad 100644
--- a/llvm/lib/Target/AVR/AVRISelLowering.cpp
+++ b/llvm/lib/Target/AVR/AVRISelLowering.cpp
@@ -79,6 +79,11 @@ AVRTargetLowering::AVRTargetLowering(AVRTargetMachine &tm)
setOperationAction(ISD::SRA_PARTS, MVT::i16, Expand);
setOperationAction(ISD::SRL_PARTS, MVT::i16, Expand);
+ setOperationAction(ISD::ROTL, MVT::i8, Custom);
+ setOperationAction(ISD::ROTL, MVT::i16, Custom);
+ setOperationAction(ISD::ROTR, MVT::i8, Custom);
+ setOperationAction(ISD::ROTR, MVT::i16, Custom);
+
setOperationAction(ISD::BR_CC, MVT::i8, Custom);
setOperationAction(ISD::BR_CC, MVT::i16, Custom);
setOperationAction(ISD::BR_CC, MVT::i32, Custom);
@@ -273,6 +278,12 @@ SDValue AVRTargetLowering::LowerShifts(SDValue Op, SelectionDAG &DAG) const {
case ISD::SRL:
return DAG.getNode(AVRISD::LSRLOOP, dl, VT, N->getOperand(0),
N->getOperand(1));
+ case ISD::ROTL:
+ return DAG.getNode(AVRISD::ROLLOOP, dl, VT, N->getOperand(0),
+ N->getOperand(1));
+ case ISD::ROTR:
+ return DAG.getNode(AVRISD::RORLOOP, dl, VT, N->getOperand(0),
+ N->getOperand(1));
case ISD::SRA:
return DAG.getNode(AVRISD::ASRLOOP, dl, VT, N->getOperand(0),
N->getOperand(1));
@@ -1440,6 +1451,22 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI,
Opc = AVR::LSRWRd;
RC = &AVR::DREGSRegClass;
break;
+ case AVR::Rol8:
+ Opc = AVR::ROLRd;
+ RC = &AVR::GPR8RegClass;
+ break;
+ case AVR::Rol16:
+ Opc = AVR::ROLWRd;
+ RC = &AVR::DREGSRegClass;
+ break;
+ case AVR::Ror8:
+ Opc = AVR::RORRd;
+ RC = &AVR::GPR8RegClass;
+ break;
+ case AVR::Ror16:
+ Opc = AVR::RORWRd;
+ RC = &AVR::DREGSRegClass;
+ break;
}
const BasicBlock *LLVM_BB = BB->getBasicBlock();
@@ -1552,6 +1579,10 @@ AVRTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
case AVR::Lsl16:
case AVR::Lsr8:
case AVR::Lsr16:
+ case AVR::Rol8:
+ case AVR::Rol16:
+ case AVR::Ror8:
+ case AVR::Ror16:
case AVR::Asr8:
case AVR::Asr16:
return insertShift(MI, MBB);
diff --git a/llvm/lib/Target/AVR/AVRISelLowering.h b/llvm/lib/Target/AVR/AVRISelLowering.h
index a8cdc4e7ae2..b44c62a21ac 100644
--- a/llvm/lib/Target/AVR/AVRISelLowering.h
+++ b/llvm/lib/Target/AVR/AVRISelLowering.h
@@ -43,6 +43,8 @@ enum NodeType {
ROL, ///< Bit rotate left.
LSLLOOP, ///< A loop of single logical shift left instructions.
LSRLOOP, ///< A loop of single logical shift right instructions.
+ ROLLOOP, ///< A loop of single left bit rotate instructions.
+ RORLOOP, ///< A loop of single right bit rotate instructions.
ASRLOOP, ///< A loop of single arithmetic shift right instructions.
/// AVR conditional branches. Operand 0 is the chain operand, operand 1
/// is the block to branch if condition is true, operand 2 is the
diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.td b/llvm/lib/Target/AVR/AVRInstrInfo.td
index 09104669366..1b6547ef779 100644
--- a/llvm/lib/Target/AVR/AVRInstrInfo.td
+++ b/llvm/lib/Target/AVR/AVRInstrInfo.td
@@ -64,6 +64,8 @@ def AVRasr : SDNode<"AVRISD::ASR", SDTIntUnaryOp>;
// Pseudo shift nodes for non-constant shift amounts.
def AVRlslLoop : SDNode<"AVRISD::LSLLOOP", SDTIntShiftOp>;
def AVRlsrLoop : SDNode<"AVRISD::LSRLOOP", SDTIntShiftOp>;
+def AVRrolLoop : SDNode<"AVRISD::ROLLOOP", SDTIntShiftOp>;
+def AVRrorLoop : SDNode<"AVRISD::RORLOOP", SDTIntShiftOp>;
def AVRasrLoop : SDNode<"AVRISD::ASRLOOP", SDTIntShiftOp>;
//===----------------------------------------------------------------------===//
@@ -1932,7 +1934,6 @@ def Lsr8 : ShiftPseudo<
[(set i8:$dst, (AVRlsrLoop i8:$src, i8:$cnt))]
>;
-
def Lsr16 : ShiftPseudo<
(outs DREGS:$dst),
(ins DREGS:$src, GPR8:$cnt),
@@ -1940,6 +1941,34 @@ def Lsr16 : ShiftPseudo<
[(set i16:$dst, (AVRlsrLoop i16:$src, i8:$cnt))]
>;
+def Rol8 : ShiftPseudo<
+ (outs GPR8:$dst),
+ (ins GPR8:$src, GPR8:$cnt),
+ "# Rol8 PSEUDO",
+ [(set i8:$dst, (AVRrolLoop i8:$src, i8:$cnt))]
+>;
+
+def Rol16 : ShiftPseudo<
+ (outs DREGS:$dst),
+ (ins DREGS:$src, GPR8:$cnt),
+ "# Rol16 PSEUDO",
+ [(set i16:$dst, (AVRrolLoop i16:$src, i8:$cnt))]
+>;
+
+def Ror8 : ShiftPseudo<
+ (outs GPR8:$dst),
+ (ins GPR8:$src, GPR8:$cnt),
+ "# Ror8 PSEUDO",
+ [(set i8:$dst, (AVRrorLoop i8:$src, i8:$cnt))]
+>;
+
+def Ror16 : ShiftPseudo<
+ (outs DREGS:$dst),
+ (ins DREGS:$src, GPR8:$cnt),
+ "# Ror16 PSEUDO",
+ [(set i16:$dst, (AVRrorLoop i16:$src, i8:$cnt))]
+>;
+
def Asr8 : ShiftPseudo<
(outs GPR8:$dst),
(ins GPR8:$src, GPR8:$cnt),
OpenPOWER on IntegriCloud