跳转至

ISD inst to PPC inst

td中定义的指令

中括号中PPCISD指令需要满足的pattern。

C++
2407 def ADDI   : DForm_2<14, (outs gprc:$rD), (ins gprc_nor0:$rA, s16imm:$imm),
2408                      "addi $rD, $rA, $imm", IIC_IntSimple,
2409                      [(set i32:$rD, (add i32:$rA, imm32SExt16:$imm))]>;

def Inst : Form <some number,
                 (outs type:$rD), (ints type:$rA, ...),
                 "asm_inst $rD, $rA, ...",
                 [PPCISD pattern]>;

1.自定义的PPCISD -> PPC指令

C++
 156 // Extract FPSCR (not modeled at the DAG level).
 157 def PPCmffs   : SDNode<"PPCISD::MFFS",
 158                        SDTypeProfile<1, 0, [SDTCisVT<0, f64>]>,
 159                        [SDNPHasChain]>;


2937   def MFFS   : XForm_42<63, 583, (outs f8rc:$rT), (ins),
2938                          "mffs $rT", IIC_IntMFFS,
2939                          [(set f64:$rT, (PPCmffs))]>,
2940                PPC970_DGroup_Single, PPC970_Unit_FPU;
2941

2. Target ISD -> PPC/TargetOp指令

3. 伪指令

如果选择的是一条PPCCustomInserterPseudo定义的PPC伪指令的话,需要在Lowering::EmitInstrWithCustomInserter中进一步处理成PPC支持的指令。如 setrnd

3.1 PPC::SETRND/PPC::SETRNDi

GAS
// Set the float rounding mode.
let Uses = [RM], Defs = [RM] in { 
def SETRNDi : PPCCustomInserterPseudo<(outs f8rc:$FRT), (ins u2imm:$RND),
                    "#SETRNDi", [(set f64:$FRT, (int_ppc_setrnd (i32 imm:$RND)))]>;

def SETRND : PPCCustomInserterPseudo<(outs f8rc:$FRT), (ins gprc:$in),
                    "#SETRND", [(set f64:$FRT, (int_ppc_setrnd gprc :$in))]>;
}


 // SELECT_* pseudo instructions, like SELECT_CC_* but taking condition
  // register bit directly.
  def SELECT_I4 : PPCCustomInserterPseudo<(outs gprc:$dst), (ins crbitrc:$cond,
                          gprc_nor0:$T, gprc_nor0:$F), "#SELECT_I4",
                          [(set i32:$dst, (select i1:$cond, i32:$T, i32:$F))]>;
  def SELECT_I8 : PPCCustomInserterPseudo<(outs g8rc:$dst), (ins crbitrc:$cond,
                          g8rc_nox0:$T, g8rc_nox0:$F), "#SELECT_I8",
                          [(set i64:$dst, (select i1:$cond, i64:$T, i64:$F))]>;

./PPCISelLowering.cppPPCCustomInserterPseudo定义的伪指令,必须在EmitInstrWithCustomInserter中进行Lowering,未处理的伪指令会报错。

C++
MachineBasicBlock *
PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
                                               MachineBasicBlock *BB) const {
     } else if (MI.getOpcode() == PPC::SETRNDi) {
    DebugLoc dl = MI.getDebugLoc();
    Register OldFPSCRReg = MI.getOperand(0).getReg();

    // Save FPSCR value.
    BuildMI(*BB, MI, dl, TII->get(PPC::MFFS), OldFPSCRReg);

    // The floating point rounding mode is in the bits 62:63 of FPCSR, and has
    // the following settings:
    //   00 Round to nearest
    //   01 Round to 0
    //   10 Round to +inf
    //   11 Round to -inf

    // When the operand is immediate, using the two least significant bits of
    // the immediate to set the bits 62:63 of FPSCR.
    unsigned Mode = MI.getOperand(1).getImm();
    BuildMI(*BB, MI, dl, TII->get((Mode & 1) ? PPC::MTFSB1 : PPC::MTFSB0))
      .addImm(31);

    BuildMI(*BB, MI, dl, TII->get((Mode & 2) ? PPC::MTFSB1 : PPC::MTFSB0))
      .addImm(30);
  } else if (MI.getOpcode() == PPC::SETRND) {

  }
}

3.2 PPC::SELECT_I4

ISD::SELECT会在指令选择中被匹配成PPC::SELECT_I4系列伪指令,然后对PPC::SELECT_I4进行Lowering,使用实际所支持的PPC指令。

中括号是匹配规则,其中的select是指的ISD::SELECT。(中括号表明如何从ISD/PPCISD::->PPC::)

GAS
  // SELECT_* pseudo instructions, like SELECT_CC_* but taking condition
  // register bit directly.
  def SELECT_I4 : PPCCustomInserterPseudo<(outs gprc:$dst), (ins crbitrc:$cond,
                          gprc_nor0:$T, gprc_nor0:$F), "#SELECT_I4",
                          [(set i32:$dst, (select i1:$cond, i32:$T, i32:$F))]>;
  def SELECT_I8 : PPCCustomInserterPseudo<(outs g8rc:$dst), (ins crbitrc:$cond,
                          g8rc_nox0:$T, g8rc_nox0:$F), "#SELECT_I8",
                          [(set i64:$dst, (select i1:$cond, i64:$T, i64:$F))]>;