Commit 377aca8d authored by Bill Wendling's avatar Bill Wendling
Browse files

Complete the missing parts of MIPS-JIT functionality. Patch by Petar Jovanovic.

llvm-svn: 143014
parent 2b2cfe2e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ set(LLVM_TARGET_DEFINITIONS Mips.td)

llvm_tablegen(MipsGenRegisterInfo.inc -gen-register-info)
llvm_tablegen(MipsGenInstrInfo.inc -gen-instr-info)
llvm_tablegen(MipsGenCodeEmitter.inc -gen-emitter)
llvm_tablegen(MipsGenAsmWriter.inc -gen-asm-writer)
llvm_tablegen(MipsGenDAGISel.inc -gen-dag-isel)
llvm_tablegen(MipsGenCallingConv.inc -gen-callingconv)
+1 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@ TARGET = Mips

# Make sure that tblgen is run, first thing.
BUILT_SOURCES = MipsGenRegisterInfo.inc MipsGenInstrInfo.inc \
                MipsGenAsmWriter.inc \
                MipsGenAsmWriter.inc MipsGenCodeEmitter.inc \
                MipsGenDAGISel.inc MipsGenCallingConv.inc \
                MipsGenSubtargetInfo.inc

+20 −20
Original line number Diff line number Diff line
@@ -39,51 +39,51 @@ def imm32_63 : ImmLeaf<i64,
// Shifts
class LogicR_shift_rotate_imm64<bits<6> func, bits<5> _rs, string instr_asm,
                                SDNode OpNode, PatFrag PF>:
  FR<0x00, func, (outs CPU64Regs:$dst), (ins CPU64Regs:$b, shamt_64:$c),
     !strconcat(instr_asm, "\t$dst, $b, $c"),
     [(set CPU64Regs:$dst, (OpNode CPU64Regs:$b, (i64 PF:$c)))],
  FR<0x00, func, (outs CPU64Regs:$rd), (ins CPU64Regs:$rt, shamt_64:$shamt),
     !strconcat(instr_asm, "\t$rd, $rt, $shamt"),
     [(set CPU64Regs:$rd, (OpNode CPU64Regs:$rt, (i64 PF:$shamt)))],
     IIAlu> {
  let rs = _rs;
}

class LogicR_shift_rotate_reg64<bits<6> func, bits<5> _shamt, string instr_asm,
                                SDNode OpNode>:
  FR<0x00, func, (outs CPU64Regs:$dst), (ins CPU64Regs:$c, CPU64Regs:$b),
     !strconcat(instr_asm, "\t$dst, $b, $c"),
     [(set CPU64Regs:$dst, (OpNode CPU64Regs:$b, CPU64Regs:$c))], IIAlu> {
  FR<0x00, func, (outs CPU64Regs:$rd), (ins CPU64Regs:$rs, CPU64Regs:$rt),
     !strconcat(instr_asm, "\t$rd, $rt, $rs"),
     [(set CPU64Regs:$rd, (OpNode CPU64Regs:$rt, CPU64Regs:$rs))], IIAlu> {
  let shamt = _shamt;
}

// Mul, Div
let Defs = [HI64, LO64] in {
let rd = 0, shamt = 0, Defs = [HI64, LO64] in {
  let isCommutable = 1 in
  class Mul64<bits<6> func, string instr_asm, InstrItinClass itin>:
    FR<0x00, func, (outs), (ins CPU64Regs:$a, CPU64Regs:$b),
       !strconcat(instr_asm, "\t$a, $b"), [], itin>;
    FR<0x00, func, (outs), (ins CPU64Regs:$rs, CPU64Regs:$rt),
       !strconcat(instr_asm, "\t$rs, $rt"), [], itin>;

  class Div64<SDNode op, bits<6> func, string instr_asm, InstrItinClass itin>:
              FR<0x00, func, (outs), (ins CPU64Regs:$a, CPU64Regs:$b),
              !strconcat(instr_asm, "\t$$zero, $a, $b"),
              [(op CPU64Regs:$a, CPU64Regs:$b)], itin>;
              FR<0x00, func, (outs), (ins CPU64Regs:$rs, CPU64Regs:$rt),
              !strconcat(instr_asm, "\t$$zero, $rs, $rt"),
              [(op CPU64Regs:$rs, CPU64Regs:$rt)], itin>;
}

// Move from Hi/Lo
let shamt = 0 in {
let rs = 0, rt = 0 in
class MoveFromLOHI64<bits<6> func, string instr_asm>:
  FR<0x00, func, (outs CPU64Regs:$dst), (ins),
     !strconcat(instr_asm, "\t$dst"), [], IIHiLo>;
  FR<0x00, func, (outs CPU64Regs:$rd), (ins),
     !strconcat(instr_asm, "\t$rd"), [], IIHiLo>;

let rt = 0, rd = 0 in
class MoveToLOHI64<bits<6> func, string instr_asm>:
  FR<0x00, func, (outs), (ins CPU64Regs:$src),
     !strconcat(instr_asm, "\t$src"), [], IIHiLo>;
  FR<0x00, func, (outs), (ins CPU64Regs:$rs),
     !strconcat(instr_asm, "\t$rs"), [], IIHiLo>;
}

// Count Leading Ones/Zeros in Word
class CountLeading64<bits<6> func, string instr_asm, list<dag> pattern>:
  FR<0x1c, func, (outs CPU64Regs:$dst), (ins CPU64Regs:$src),
     !strconcat(instr_asm, "\t$dst, $src"), pattern, IIAlu>,
  FR<0x1c, func, (outs CPU64Regs:$rd), (ins CPU64Regs:$rs),
     !strconcat(instr_asm, "\t$rd, $rs"), pattern, IIAlu>,
     Requires<[HasBitCount]> {
  let shamt = 0;
  let rt = rd;
@@ -180,9 +180,9 @@ let Uses = [LO64] in

/// Count Leading
def DCLZ : CountLeading64<0x24, "dclz",
                          [(set CPU64Regs:$dst, (ctlz CPU64Regs:$src))]>;
                          [(set CPU64Regs:$rd, (ctlz CPU64Regs:$rs))]>;
def DCLO : CountLeading64<0x25, "dclo",
                          [(set CPU64Regs:$dst, (ctlz (not CPU64Regs:$src)))]>;
                          [(set CPU64Regs:$rd, (ctlz (not CPU64Regs:$rs)))]>;

//===----------------------------------------------------------------------===//
//  Arbitrary patterns that map to one or more instructions
+26 −5
Original line number Diff line number Diff line
@@ -105,6 +105,9 @@ class MipsCodeEmitter : public MachineFunctionPass {
    unsigned getRelocation(const MachineInstr &MI,
                           const MachineOperand &MO) const;

    unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const;
    unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const;
    unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const;
  };
}

@@ -153,6 +156,28 @@ unsigned MipsCodeEmitter::getRelocation(const MachineInstr &MI,
  return Mips::reloc_mips_lo;
}

unsigned MipsCodeEmitter::getMemEncoding(const MachineInstr &MI,
                                          unsigned OpNo) const {
  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
  assert(MI.getOperand(OpNo).isReg());
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo)) << 16;
  return
    (getMachineOpValue(MI, MI.getOperand(OpNo+1)) & 0xFFFF) | RegBits;
}

unsigned MipsCodeEmitter::getSizeExtEncoding(const MachineInstr &MI,
                                          unsigned OpNo) const {
  // size is encoded as size-1.
  return getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
}

unsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI,
                                          unsigned OpNo) const {
  // size is encoded as pos+size-1.
  return getMachineOpValue(MI, MI.getOperand(OpNo-1)) +
         getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
}

/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
@@ -238,8 +263,4 @@ FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
  return new MipsCodeEmitter(TM, JCE);
}

unsigned MipsCodeEmitter::getBinaryCodeForInstr(const MachineInstr &MI) const {
 // this function will be automatically generated by the CodeEmitterGenerator
 // using TableGen
 return 0;
}
#include "MipsGenCodeEmitter.inc"
+35 −21
Original line number Diff line number Diff line
@@ -76,14 +76,16 @@ def IsNotSingleFloat : Predicate<"!Subtarget.isSingleFloat()">;
// FP load.
class FPLoad<bits<6> op, string opstr, PatFrag FOp, RegisterClass RC,
             Operand MemOpnd>:
  FFI<op, (outs RC:$ft), (ins MemOpnd:$base),
      !strconcat(opstr, "\t$ft, $base"), [(set RC:$ft, (FOp addr:$base))]>;
  FMem<op, (outs RC:$ft), (ins MemOpnd:$addr),
      !strconcat(opstr, "\t$ft, $addr"), [(set RC:$ft, (FOp addr:$addr))],
      IILoad>;

// FP store.
class FPStore<bits<6> op, string opstr, PatFrag FOp, RegisterClass RC,
              Operand MemOpnd>:
  FFI<op, (outs), (ins RC:$ft, MemOpnd:$base),
      !strconcat(opstr, "\t$ft, $base"), [(store RC:$ft, addr:$base)]>;
  FMem<op, (outs), (ins RC:$ft, MemOpnd:$addr),
      !strconcat(opstr, "\t$ft, $addr"), [(store RC:$ft, addr:$addr)],
      IIStore>;

// Instructions that convert an FP value to 32-bit fixed point.
multiclass FFR1_W_M<bits<6> funct, string opstr> {
@@ -158,22 +160,28 @@ defm FSQRT : FFR1P_M<0x4, "sqrt", fsqrt>;
// stores, and moves between floating-point and integer registers.
// When defining instructions, we reference all 32-bit registers,
// regardless of register aliasing.
let fd = 0 in {

class FFRGPR<bits<5> _fmt, dag outs, dag ins, string asmstr, list<dag> pattern>:
             FFR<0x11, 0x0, _fmt, outs, ins, asmstr, pattern> {
  bits<5> rt;
  let ft = rt;
  let fd = 0;
}

/// Move Control Registers From/To CPU Registers
  def CFC1  : FFR<0x11, 0x0, 0x2, (outs CPURegs:$rt), (ins CCR:$fs),
def CFC1  : FFRGPR<0x2, (outs CPURegs:$rt), (ins CCR:$fs),
                  "cfc1\t$rt, $fs", []>;

  def CTC1  : FFR<0x11, 0x0, 0x6, (outs CCR:$rt), (ins CPURegs:$fs),
                  "ctc1\t$fs, $rt", []>;
def CTC1  : FFRGPR<0x6, (outs CCR:$fs), (ins CPURegs:$rt),
                  "ctc1\t$rt, $fs", []>;

  def MFC1  : FFR<0x11, 0x00, 0x00, (outs CPURegs:$rt), (ins FGR32:$fs),
def MFC1  : FFRGPR<0x00, (outs CPURegs:$rt), (ins FGR32:$fs),
                  "mfc1\t$rt, $fs",
                  [(set CPURegs:$rt, (bitconvert FGR32:$fs))]>;

  def MTC1  : FFR<0x11, 0x00, 0x04, (outs FGR32:$fs), (ins CPURegs:$rt),
def MTC1  : FFRGPR<0x04, (outs FGR32:$fs), (ins CPURegs:$rt),
                  "mtc1\t$rt, $fs",
                  [(set FGR32:$fs, (bitconvert CPURegs:$rt))]>;
}

def FMOV_S   : FFR1<0x6, 16, "mov", "s", FGR32, FGR32>;
def FMOV_D32 : FFR1<0x6, 17, "mov", "d", AFGR64, AFGR64>,
@@ -203,7 +211,7 @@ let Predicates = [NotN64] in {
}

/// Floating-point Aritmetic
defm FADD : FFR2P_M<0x10, "add", fadd, 1>;
defm FADD : FFR2P_M<0x00, "add", fadd, 1>;
defm FDIV : FFR2P_M<0x03, "div", fdiv>;
defm FMUL : FFR2P_M<0x02, "mul", fmul, 1>;
defm FSUB : FFR2P_M<0x01, "sub", fsub>;
@@ -218,12 +226,16 @@ def MIPS_BRANCH_T : PatLeaf<(i32 1)>;

/// Floating Point Branch of False/True (Likely)
let isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in
  class FBRANCH<PatLeaf op, string asmstr> : FFI<0x11, (outs),
        (ins brtarget:$dst), !strconcat(asmstr, "\t$dst"),
        [(MipsFPBrcond op, bb:$dst)]>;
  class FBRANCH<bits<1> nd, bits<1> tf, PatLeaf op, string asmstr> :
      FFI<0x11, (outs), (ins brtarget:$dst), !strconcat(asmstr, "\t$dst"),
        [(MipsFPBrcond op, bb:$dst)]> {
  let Inst{20-18} = 0;
  let Inst{17} = nd;
  let Inst{16} = tf;
}

def BC1F  : FBRANCH<MIPS_BRANCH_F,  "bc1f">;
def BC1T  : FBRANCH<MIPS_BRANCH_T,  "bc1t">;
def BC1F  : FBRANCH<0, 0, MIPS_BRANCH_F,  "bc1f">;
def BC1T  : FBRANCH<0, 1, MIPS_BRANCH_T,  "bc1t">;

//===----------------------------------------------------------------------===//
// Floating Point Flag Conditions
@@ -249,11 +261,11 @@ def MIPS_FCOND_NGT : PatLeaf<(i32 15)>;

/// Floating Point Compare
let Defs=[FCR31] in {
  def FCMP_S32 : FCC<0x0, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc),
  def FCMP_S32 : FCC<0x10, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc),
                     "c.$cc.s\t$fs, $ft",
                     [(MipsFPCmp FGR32:$fs, FGR32:$ft, imm:$cc)]>;

  def FCMP_D32 : FCC<0x1, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc),
  def FCMP_D32 : FCC<0x11, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc),
                     "c.$cc.d\t$fs, $ft",
                     [(MipsFPCmp AFGR64:$fs, AFGR64:$ft, imm:$cc)]>,
                     Requires<[NotFP64bit]>;
@@ -287,7 +299,8 @@ let Predicates = [NotFP64bit] in {
  defm : MovnPats<AFGR64, MOVN_D>;
}

let usesCustomInserter = 1, Uses = [FCR31], Constraints = "$F = $dst" in {
let cc = 0, usesCustomInserter = 1, Uses = [FCR31],
    Constraints = "$F = $dst" in {
// flag:float, data:int
class CondMovFPInt<SDNode cmov, bits<1> tf, string instr_asm> :
  FCMOV<tf, (outs CPURegs:$dst), (ins CPURegs:$T, CPURegs:$F),
@@ -295,6 +308,7 @@ class CondMovFPInt<SDNode cmov, bits<1> tf, string instr_asm> :
        [(set CPURegs:$dst, (cmov CPURegs:$T, CPURegs:$F))]>;

// flag:float, data:float
let cc = 0 in
class CondMovFPFP<RegisterClass RC, SDNode cmov, bits<5> fmt, bits<1> tf,
                  string instr_asm> :
  FFCMOV<fmt, tf, (outs RC:$dst), (ins RC:$T, RC:$F),
Loading