Skip to content
ARMInstrVFP.td 40.5 KiB
Newer Older
//===- ARMInstrVFP.td - VFP support for ARM ----------------*- tablegen -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file describes the ARM VFP instruction set.
//
//===----------------------------------------------------------------------===//

def SDT_FTOI    : SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>;
def SDT_ITOF    : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>;
def SDT_CMPFP0  : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
def SDT_VMOVDRR : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>,
                                       SDTCisSameAs<1, 2>]>;
def arm_ftoui  : SDNode<"ARMISD::FTOUI",   SDT_FTOI>;
def arm_ftosi  : SDNode<"ARMISD::FTOSI",   SDT_FTOI>;
def arm_sitof  : SDNode<"ARMISD::SITOF",   SDT_ITOF>;
def arm_uitof  : SDNode<"ARMISD::UITOF",   SDT_ITOF>;
def arm_fmstat : SDNode<"ARMISD::FMSTAT",  SDTNone, [SDNPInFlag, SDNPOutFlag]>;
def arm_cmpfp  : SDNode<"ARMISD::CMPFP",   SDT_ARMCmp, [SDNPOutFlag]>;
def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0", SDT_CMPFP0, [SDNPOutFlag]>;
def arm_fmdrr  : SDNode<"ARMISD::VMOVDRR", SDT_VMOVDRR>;
//===----------------------------------------------------------------------===//
// Operand Definitions.
//

def vfp_f32imm : Operand<f32>,
                 PatLeaf<(f32 fpimm), [{
      return ARM::getVFPf32Imm(N->getValueAPF()) != -1;
    }]> {
  let PrintMethod = "printVFPf32ImmOperand";
}

def vfp_f64imm : Operand<f64>,
                 PatLeaf<(f64 fpimm), [{
      return ARM::getVFPf64Imm(N->getValueAPF()) != -1;
    }]> {
  let PrintMethod = "printVFPf64ImmOperand";
}


//===----------------------------------------------------------------------===//
//  Load / store Instructions.
//

let canFoldAsLoad = 1, isReMaterializable = 1 in {
def VLDRD : ADI5<0b1101, 0b01, (outs DPR:$Dd), (ins addrmode5:$addr),
                 IIC_fpLoad64, "vldr", ".64\t$Dd, $addr",
                 [(set DPR:$Dd, (f64 (load addrmode5:$addr)))]>;
def VLDRS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr),
                 IIC_fpLoad32, "vldr", ".32\t$dst, $addr",
                 [(set SPR:$dst, (load addrmode5:$addr))]>;
def VSTRD  : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr),
                 IIC_fpStore64, "vstr", ".64\t$src, $addr",
                 [(store (f64 DPR:$src), addrmode5:$addr)]>;
def VSTRS  : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr),
                 IIC_fpStore32, "vstr", ".32\t$src, $addr",
                 [(store SPR:$src, addrmode5:$addr)]>;

//===----------------------------------------------------------------------===//
//  Load / store multiple Instructions.
//

let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
def VLDMD : AXDI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$dsts,
                  "vldm${addr:submode}${p}\t$addr, $dsts", "", []> {
  let Inst{20} = 1;
}
def VLDMS : AXSI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$dsts,
                  "vldm${addr:submode}${p}\t$addr, $dsts", "", []> {
def VLDMD_UPD : AXDI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
                      "vldm${addr:submode}${p}\t$addr!, $dsts",
                      "$addr.addr = $wb", []> {
def VLDMS_UPD : AXSI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
                      "vldm${addr:submode}${p}\t$addr!, $dsts",
                      "$addr.addr = $wb", []> {
  let Inst{20} = 1;
}
} // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
def VSTMD : AXDI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$srcs,
                  "vstm${addr:submode}${p}\t$addr, $srcs", "", []> {
  let Inst{20} = 0;
}
def VSTMS : AXSI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$srcs,
                  "vstm${addr:submode}${p}\t$addr, $srcs", "", []> {
def VSTMD_UPD : AXDI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
                      "vstm${addr:submode}${p}\t$addr!, $srcs",
                      "$addr.addr = $wb", []> {
def VSTMS_UPD : AXSI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
                      "vstm${addr:submode}${p}\t$addr!, $srcs",
                      "$addr.addr = $wb", []> {
  let Inst{20} = 0;
}
} // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq

// FLDMX, FSTMX - mixing S/D registers for pre-armv6 cores


// FIXME: Can these be placed into the base class?
class ADbI_Encode<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
                  dag iops, InstrItinClass itin, string opc, string asm,
                  list<dag> pattern>
  : ADbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
  // Instruction operands.
  // Encode instruction operands.
  let Inst{3-0}   = Dm{3-0};
  let Inst{5}     = Dm{4};
  let Inst{19-16} = Dn{3-0};
  let Inst{7}     = Dn{4};
  let Inst{15-12} = Dd{3-0};
  let Inst{22}    = Dd{4};
}
class ADuI_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
                  bits<2> opcod4, bit opcod5, dag oops, dag iops,
                  InstrItinClass itin, string opc, string asm,
                  list<dag> pattern>
  : ADuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc,
         asm, pattern> {
  // Instruction operands.
  bits<5> Dd;
  bits<5> Dm;

  // Encode instruction operands.
  let Inst{3-0}   = Dm{3-0};
  let Inst{5}     = Dm{4};
  let Inst{15-12} = Dd{3-0};
  let Inst{22}    = Dd{4};
}

Bill Wendling's avatar
Bill Wendling committed
class ASbI_Encode<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
                  dag iops, InstrItinClass itin, string opc, string asm,
                  list<dag> pattern>
Bill Wendling's avatar
Bill Wendling committed
  : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
  // Instruction operands.
  bits<5> Sd;
Bill Wendling's avatar
Bill Wendling committed
  bits<5> Sn;
  bits<5> Sm;

  // Encode instruction operands.
  let Inst{3-0}   = Sm{4-1};
  let Inst{5}     = Sm{0};
Bill Wendling's avatar
Bill Wendling committed
  let Inst{19-16} = Sn{4-1};
  let Inst{7}     = Sn{0};
  let Inst{15-12} = Sd{4-1};
  let Inst{22}    = Sd{0};
}

Bill Wendling's avatar
Bill Wendling committed
class ASbIn_Encode<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
                   dag iops, InstrItinClass itin, string opc, string asm,
                   list<dag> pattern>
  : ASbIn<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
  // Instruction operands.
  bits<5> Sd;
  bits<5> Sn;
  bits<5> Sm;

Loading
Loading full blame...