SDNode *SelectLIBM(SDNode *N);
- SDNode *SelectReadRegister(SDNode *N);
- SDNode *SelectWriteRegister(SDNode *N);
-
// Include the pieces autogenerated from the target description.
#include "AArch64GenDAGISel.inc"
return true;
}
-// Inspects a register string of the form o0:op1:CRn:CRm:op2 gets the fields
-// of the string and obtains the integer values from them and combines these
-// into a single value to be used in the MRS/MSR instruction.
-static int getIntOperandFromRegisterString(StringRef RegString) {
- SmallVector<StringRef, 5> Fields;
- RegString.split(Fields, ":");
-
- if (Fields.size() == 1)
- return -1;
-
- assert(Fields.size() == 5
- && "Invalid number of fields in read register string");
-
- SmallVector<int, 5> Ops;
- bool AllIntFields = true;
-
- for (StringRef Field : Fields) {
- unsigned IntField;
- AllIntFields &= !Field.getAsInteger(10, IntField);
- Ops.push_back(IntField);
- }
-
- assert(AllIntFields &&
- "Unexpected non-integer value in special register string.");
-
- // Need to combine the integer fields of the string into a single value
- // based on the bit encoding of MRS/MSR instruction.
- return (Ops[0] << 14) | (Ops[1] << 11) | (Ops[2] << 7) |
- (Ops[3] << 3) | (Ops[4]);
-}
-
-// Lower the read_register intrinsic to an MRS instruction node if the special
-// register string argument is either of the form detailed in the ALCE (the
-// form described in getIntOperandsFromRegsterString) or is a named register
-// known by the MRS SysReg mapper.
-SDNode *AArch64DAGToDAGISel::SelectReadRegister(SDNode *N) {
- const MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(N->getOperand(1));
- const MDString *RegString = dyn_cast<MDString>(MD->getMD()->getOperand(0));
- SDLoc DL(N);
-
- int Reg = getIntOperandFromRegisterString(RegString->getString());
- if (Reg != -1)
- return CurDAG->getMachineNode(AArch64::MRS, DL, N->getSimpleValueType(0),
- MVT::Other,
- CurDAG->getTargetConstant(Reg, DL, MVT::i32),
- N->getOperand(0));
-
- // Use the sysreg mapper to map the remaining possible strings to the
- // value for the register to be used for the instruction operand.
- AArch64SysReg::MRSMapper mapper;
- bool IsValidSpecialReg;
- Reg = mapper.fromString(RegString->getString(),
- Subtarget->getFeatureBits(),
- IsValidSpecialReg);
- if (IsValidSpecialReg)
- return CurDAG->getMachineNode(AArch64::MRS, DL, N->getSimpleValueType(0),
- MVT::Other,
- CurDAG->getTargetConstant(Reg, DL, MVT::i32),
- N->getOperand(0));
-
- return nullptr;
-}
-
-// Lower the write_register intrinsic to an MSR instruction node if the special
-// register string argument is either of the form detailed in the ALCE (the
-// form described in getIntOperandsFromRegsterString) or is a named register
-// known by the MSR SysReg mapper.
-SDNode *AArch64DAGToDAGISel::SelectWriteRegister(SDNode *N) {
- const MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(N->getOperand(1));
- const MDString *RegString = dyn_cast<MDString>(MD->getMD()->getOperand(0));
- SDLoc DL(N);
-
- int Reg = getIntOperandFromRegisterString(RegString->getString());
- if (Reg != -1)
- return CurDAG->getMachineNode(AArch64::MSR, DL, MVT::Other,
- CurDAG->getTargetConstant(Reg, DL, MVT::i32),
- N->getOperand(2), N->getOperand(0));
-
- // Check if the register was one of those allowed as the pstatefield value in
- // the MSR (immediate) instruction. To accept the values allowed in the
- // pstatefield for the MSR (immediate) instruction, we also require that an
- // immediate value has been provided as an argument, we know that this is
- // the case as it has been ensured by semantic checking.
- AArch64PState::PStateMapper PMapper;
- bool IsValidSpecialReg;
- Reg = PMapper.fromString(RegString->getString(),
- Subtarget->getFeatureBits(),
- IsValidSpecialReg);
- if (IsValidSpecialReg) {
- assert (isa<ConstantSDNode>(N->getOperand(2))
- && "Expected a constant integer expression.");
- uint64_t Immed = cast<ConstantSDNode>(N->getOperand(2))->getZExtValue();
- return CurDAG->getMachineNode(AArch64::MSRpstate, DL, MVT::Other,
- CurDAG->getTargetConstant(Reg, DL, MVT::i32),
- CurDAG->getTargetConstant(Immed, DL, MVT::i16),
- N->getOperand(0));
- }
-
- // Use the sysreg mapper to attempt to map the remaining possible strings
- // to the value for the register to be used for the MSR (register)
- // instruction operand.
- AArch64SysReg::MSRMapper Mapper;
- Reg = Mapper.fromString(RegString->getString(),
- Subtarget->getFeatureBits(),
- IsValidSpecialReg);
-
- if (IsValidSpecialReg)
- return CurDAG->getMachineNode(AArch64::MSR, DL, MVT::Other,
- CurDAG->getTargetConstant(Reg, DL, MVT::i32),
- N->getOperand(2), N->getOperand(0));
-
- return nullptr;
-}
-
SDNode *AArch64DAGToDAGISel::Select(SDNode *Node) {
// Dump information about the Node being selected
DEBUG(errs() << "Selecting: ");
default:
break;
- case ISD::READ_REGISTER:
- if (SDNode *Res = SelectReadRegister(Node))
- return Res;
- break;
-
- case ISD::WRITE_REGISTER:
- if (SDNode *Res = SelectWriteRegister(Node))
- return Res;
- break;
-
case ISD::ADD:
if (SDNode *I = SelectMLAV64LaneV128(Node))
return I;