Skip to content

Commit

Permalink
Hexagon V5 (Floating Point) Support.
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154829 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Sirish Pande committed Apr 16, 2012
1 parent 57ca13e commit 87eb92d
Show file tree
Hide file tree
Showing 20 changed files with 4,917 additions and 1,814 deletions.
1,898 changes: 1,552 additions & 346 deletions include/llvm/IntrinsicsHexagon.td

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions lib/Target/Hexagon/HexagonCallingConv.td
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

// Hexagon 32-bit C return-value convention.
def RetCC_Hexagon32 : CallingConv<[
CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3, R4, R5]>>,
CCIfType<[i64], CCAssignToReg<[D0, D1, D2]>>,
CCIfType<[i32, f32], CCAssignToReg<[R0, R1, R2, R3, R4, R5]>>,
CCIfType<[i64, f64], CCAssignToReg<[D0, D1, D2]>>,

// Alternatively, they are assigned to the stack in 4-byte aligned units.
CCAssignToStack<4, 4>
Expand All @@ -27,8 +27,8 @@ def RetCC_Hexagon32 : CallingConv<[
// Hexagon 32-bit C Calling convention.
def CC_Hexagon32 : CallingConv<[
// All arguments get passed in integer registers if there is space.
CCIfType<[i32, i16, i8], CCAssignToReg<[R0, R1, R2, R3, R4, R5]>>,
CCIfType<[i64], CCAssignToReg<[D0, D1, D2]>>,
CCIfType<[f32, i32, i16, i8], CCAssignToReg<[R0, R1, R2, R3, R4, R5]>>,
CCIfType<[f64, i64], CCAssignToReg<[D0, D1, D2]>>,

// Alternatively, they are assigned to the stack in 4-byte aligned units.
CCAssignToStack<4, 4>
Expand Down
14 changes: 7 additions & 7 deletions lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
//
//===----------------------------------------------------------------------===//
// The Hexagon processor has no instructions that load or store predicate
// registers directly. So, when these registers must be spilled a general
// purpose register must be found and the value copied to/from it from/to
// the predicate register. This code currently does not use the register
// registers directly. So, when these registers must be spilled a general
// purpose register must be found and the value copied to/from it from/to
// the predicate register. This code currently does not use the register
// scavenger mechanism available in the allocator. There are two registers
// reserved to allow spilling/restoring predicate registers. One is used to
// hold the predicate value. The other is used when stack frame offsets are
Expand Down Expand Up @@ -84,7 +84,7 @@ bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) {
int SrcReg = MI->getOperand(2).getReg();
assert(Hexagon::PredRegsRegClass.contains(SrcReg) &&
"Not a predicate register");
if (!TII->isValidOffset(Hexagon::STriw, Offset)) {
if (!TII->isValidOffset(Hexagon::STriw_indexed, Offset)) {
if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) {
BuildMI(*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::CONST32_Int_Real),
Expand All @@ -95,23 +95,23 @@ bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) {
BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
HEXAGON_RESERVED_REG_2).addReg(SrcReg);
BuildMI(*MBB, MII, MI->getDebugLoc(),
TII->get(Hexagon::STriw))
TII->get(Hexagon::STriw_indexed))
.addReg(HEXAGON_RESERVED_REG_1)
.addImm(0).addReg(HEXAGON_RESERVED_REG_2);
} else {
BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri),
HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset);
BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
HEXAGON_RESERVED_REG_2).addReg(SrcReg);
BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::STriw))
BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::STriw_indexed))
.addReg(HEXAGON_RESERVED_REG_1)
.addImm(0)
.addReg(HEXAGON_RESERVED_REG_2);
}
} else {
BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd),
HEXAGON_RESERVED_REG_2).addReg(SrcReg);
BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::STriw)).
BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::STriw_indexed)).
addReg(FP).addImm(Offset).addReg(HEXAGON_RESERVED_REG_2);
}
MII = MBB->erase(MI);
Expand Down
38 changes: 33 additions & 5 deletions lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ class HexagonDAGToDAGISel : public SelectionDAGISel {
SDNode *SelectMul(SDNode *N);
SDNode *SelectZeroExtend(SDNode *N);
SDNode *SelectIntrinsicWOChain(SDNode *N);
SDNode *SelectIntrinsicWChain(SDNode *N);
SDNode *SelectConstant(SDNode *N);
SDNode *SelectConstantFP(SDNode *N);
SDNode *SelectAdd(SDNode *N);

// Include the pieces autogenerated from the target description.
Expand Down Expand Up @@ -318,6 +320,8 @@ SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) {
else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed;
else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed;
else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed;
else if (LoadedVT == MVT::f32) Opcode = Hexagon::LDriw_indexed_f;
else if (LoadedVT == MVT::f64) Opcode = Hexagon::LDrid_indexed_f;
else assert (0 && "unknown memory type");

// Build indexed load.
Expand Down Expand Up @@ -375,7 +379,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
};
ReplaceUses(Froms, Tos, 3);
return Result_2;
}
}
SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
Expand Down Expand Up @@ -636,7 +640,7 @@ SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {

// Figure out the opcode.
if (StoredVT == MVT::i64) Opcode = Hexagon::STrid;
else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw;
else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih;
else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib;
else assert (0 && "unknown memory type");
Expand Down Expand Up @@ -693,6 +697,8 @@ SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed;
else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed;
else if (StoredVT == MVT::f32) Opcode = Hexagon::STriw_indexed_f;
else if (StoredVT == MVT::f64) Opcode = Hexagon::STrid_indexed_f;
else assert (0 && "unknown memory type");

SDValue Ops[] = {SDValue(NewBase,0),
Expand Down Expand Up @@ -723,7 +729,7 @@ SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
if (AM != ISD::UNINDEXED) {
return SelectIndexedStore(ST, dl);
}

return SelectBaseOffsetStore(ST, dl);
}

Expand Down Expand Up @@ -752,7 +758,7 @@ SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
SDValue Sext0 = MulOp0.getOperand(0);
if (Sext0.getNode()->getValueType(0) != MVT::i32) {
SelectCode(N);
return SelectCode(N);
}

OP0 = Sext0;
Expand All @@ -761,7 +767,7 @@ SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
if (LD->getMemoryVT() != MVT::i32 ||
LD->getExtensionType() != ISD::SEXTLOAD ||
LD->getAddressingMode() != ISD::UNINDEXED) {
SelectCode(N);
return SelectCode(N);
}

SDValue Chain = LD->getChain();
Expand Down Expand Up @@ -1158,6 +1164,25 @@ SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
return SelectCode(N);
}

//
// Map floating point constant values.
//
SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
DebugLoc dl = N->getDebugLoc();
ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
APFloat APF = CN->getValueAPF();
if (N->getValueType(0) == MVT::f32) {
return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
}
else if (N->getValueType(0) == MVT::f64) {
return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
}

return SelectCode(N);
}


//
// Map predicate true (encoded as -1 in LLVM) to a XOR.
Expand Down Expand Up @@ -1234,6 +1259,9 @@ SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
case ISD::Constant:
return SelectConstant(N);

case ISD::ConstantFP:
return SelectConstantFP(N);

case ISD::ADD:
return SelectAdd(N);

Expand Down
Loading

0 comments on commit 87eb92d

Please sign in to comment.