aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/SparcV9/SparcV9InstrInfo.h
blob: ac8fdc018fca88a301428c29c2d47aa8de8fc320 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//===-- SparcV9InstrInfo.h - Define TargetInstrInfo for SparcV9 -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class contains information about individual instructions.
// Also see the SparcV9MachineInstrDesc array, which can be found in
// SparcV9TargetMachine.cpp.
// Other information is computed on demand, and most such functions
// default to member functions in base class TargetInstrInfo.
//
//===----------------------------------------------------------------------===//

#ifndef SPARCV9INSTRINFO_H
#define SPARCV9INSTRINFO_H

#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "SparcV9Internals.h"
#include "SparcV9RegisterInfo.h"

namespace llvm {

/// SparcV9InstrInfo - TargetInstrInfo specialized for the SparcV9 target.
///
struct SparcV9InstrInfo : public TargetInstrInfo {
  const SparcV9RegisterInfo RI;
public:
  SparcV9InstrInfo()
    : TargetInstrInfo(SparcV9MachineInstrDesc, V9::NUM_TOTAL_OPCODES) { }

  /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
  /// such, whenever a client has an instance of instruction info, it should
  /// always be able to get register info as well (through this method).
  ///
  virtual const MRegisterInfo &getRegisterInfo() const { return RI; }

  // All immediate constants are in position 1 except the
  // store instructions and SETxx.
  //
  virtual int getImmedConstantPos(MachineOpCode opCode) const {
    bool ignore;
    if (this->maxImmedConstant(opCode, ignore) != 0) {
      // 1st store opcode
      assert(! this->isStore((MachineOpCode) V9::STBr - 1));
      // last store opcode
      assert(! this->isStore((MachineOpCode) V9::STXFSRi + 1));

      if (opCode == V9::SETHI)
        return 0;
      if (opCode >= V9::STBr && opCode <= V9::STXFSRi)
        return 2;
      return 1;
    }
    else
      return -1;
  }

  virtual bool hasResultInterlock(MachineOpCode opCode) const
  {
    // All UltraSPARC instructions have interlocks (note that delay slots
    // are not considered here).
    // However, instructions that use the result of an FCMP produce a
    // 9-cycle stall if they are issued less than 3 cycles after the FCMP.
    // Force the compiler to insert a software interlock (i.e., gap of
    // 2 other groups, including NOPs if necessary).
    return (opCode == V9::FCMPS || opCode == V9::FCMPD || opCode == V9::FCMPQ);
  }
};

} // End llvm namespace

#endif