AIX has "millicode" routines, which are functions loaded at boot time into fixed addresses in kernel memory. This allows them to be customized for the processor. The __memccpy routine is a millicode implementation; we use millicode for the memccpy function instead of a library call to improve performance --------- Co-authored-by: Matt Arsenault <arsenm2@gmail.com>
120 lines
4.2 KiB
C++
120 lines
4.2 KiB
C++
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "PPCSelectionDAGInfo.h"
|
|
#include "llvm/CodeGen/SelectionDAG.h"
|
|
|
|
#define GET_SDNODE_DESC
|
|
#include "PPCGenSDNodeInfo.inc"
|
|
|
|
using namespace llvm;
|
|
|
|
PPCSelectionDAGInfo::PPCSelectionDAGInfo()
|
|
: SelectionDAGGenTargetInfo(PPCGenSDNodeInfo) {}
|
|
|
|
PPCSelectionDAGInfo::~PPCSelectionDAGInfo() = default;
|
|
|
|
const char *PPCSelectionDAGInfo::getTargetNodeName(unsigned Opcode) const {
|
|
switch (static_cast<PPCISD::NodeType>(Opcode)) {
|
|
case PPCISD::GlobalBaseReg:
|
|
return "PPCISD::GlobalBaseReg";
|
|
case PPCISD::SRA_ADDZE:
|
|
return "PPCISD::SRA_ADDZE";
|
|
case PPCISD::READ_TIME_BASE:
|
|
return "PPCISD::READ_TIME_BASE";
|
|
case PPCISD::MFOCRF:
|
|
return "PPCISD::MFOCRF";
|
|
case PPCISD::ANDI_rec_1_EQ_BIT:
|
|
return "PPCISD::ANDI_rec_1_EQ_BIT";
|
|
case PPCISD::ANDI_rec_1_GT_BIT:
|
|
return "PPCISD::ANDI_rec_1_GT_BIT";
|
|
case PPCISD::BDNZ:
|
|
return "PPCISD::BDNZ";
|
|
case PPCISD::BDZ:
|
|
return "PPCISD::BDZ";
|
|
case PPCISD::PPC32_PICGOT:
|
|
return "PPCISD::PPC32_PICGOT";
|
|
case PPCISD::VADD_SPLAT:
|
|
return "PPCISD::VADD_SPLAT";
|
|
}
|
|
|
|
return SelectionDAGGenTargetInfo::getTargetNodeName(Opcode);
|
|
}
|
|
|
|
void PPCSelectionDAGInfo::verifyTargetNode(const SelectionDAG &DAG,
|
|
const SDNode *N) const {
|
|
switch (N->getOpcode()) {
|
|
default:
|
|
break;
|
|
case PPCISD::DYNAREAOFFSET:
|
|
// invalid number of results; expected 2, got 1
|
|
case PPCISD::TOC_ENTRY:
|
|
// invalid number of results; expected 1, got 2
|
|
case PPCISD::STORE_COND:
|
|
// invalid number of results; expected 2, got 3
|
|
case PPCISD::LD_SPLAT:
|
|
case PPCISD::SEXT_LD_SPLAT:
|
|
case PPCISD::ZEXT_LD_SPLAT:
|
|
// invalid number of operands; expected 2, got 3
|
|
case PPCISD::ST_VSR_SCAL_INT:
|
|
// invalid number of operands; expected 4, got 5
|
|
case PPCISD::XXPERM:
|
|
// operand #1 must have type v2f64, but has type v16i8
|
|
case PPCISD::ACC_BUILD:
|
|
// operand #3 must have type v4i32, but has type v16i8
|
|
case PPCISD::PAIR_BUILD:
|
|
// operand #1 must have type v4i32, but has type v16i8
|
|
return;
|
|
}
|
|
|
|
SelectionDAGGenTargetInfo::verifyTargetNode(DAG, N);
|
|
}
|
|
|
|
std::pair<SDValue, SDValue> PPCSelectionDAGInfo::EmitTargetCodeForMemccpy(
|
|
SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Dst, SDValue Src,
|
|
SDValue C, SDValue Size, const CallInst *CI) const {
|
|
return DAG.getMemccpy(Chain, dl, Dst, Src, C, Size, CI);
|
|
;
|
|
}
|
|
|
|
std::pair<SDValue, SDValue> PPCSelectionDAGInfo::EmitTargetCodeForMemcmp(
|
|
SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Op1, SDValue Op2,
|
|
SDValue Op3, const CallInst *CI) const {
|
|
return DAG.getMemcmp(Chain, dl, Op1, Op2, Op3, CI);
|
|
}
|
|
|
|
std::pair<SDValue, SDValue> PPCSelectionDAGInfo::EmitTargetCodeForStrcmp(
|
|
SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Op1, SDValue Op2,
|
|
MachinePointerInfo Op1PtrInfo, MachinePointerInfo Op2PtrInfo,
|
|
const CallInst *CI) const {
|
|
return DAG.getStrcmp(Chain, DL, Op1, Op2, CI);
|
|
}
|
|
|
|
std::pair<SDValue, SDValue> PPCSelectionDAGInfo::EmitTargetCodeForStrcpy(
|
|
SelectionDAG &DAG, const SDLoc &DL, SDValue Chain, SDValue Dest,
|
|
SDValue Src, MachinePointerInfo DestPtrInfo, MachinePointerInfo SrcPtrInfo,
|
|
bool isStpcpy, const CallInst *CI) const {
|
|
if (isStpcpy)
|
|
return SelectionDAGTargetInfo::EmitTargetCodeForStrcpy(
|
|
DAG, DL, Chain, Dest, Src, DestPtrInfo, SrcPtrInfo, isStpcpy, CI);
|
|
return DAG.getStrcpy(Chain, DL, Dest, Src, CI);
|
|
}
|
|
|
|
std::pair<SDValue, SDValue>
|
|
PPCSelectionDAGInfo::EmitTargetCodeForStrlen(SelectionDAG &DAG, const SDLoc &DL,
|
|
SDValue Chain, SDValue Src,
|
|
const CallInst *CI) const {
|
|
return DAG.getStrlen(Chain, DL, Src, CI);
|
|
}
|
|
|
|
std::pair<SDValue, SDValue> PPCSelectionDAGInfo::EmitTargetCodeForStrstr(
|
|
SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Op1, SDValue Op2,
|
|
const CallInst *CI) const {
|
|
return DAG.getStrstr(Chain, dl, Op1, Op2, CI);
|
|
}
|