summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Sparc/LeonPasses.h
blob: e3b1ed9409dfca2a483fcdb06c64a58ff9adc0b0 (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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
//===------- LeonPasses.h - Define passes specific to LEON ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_SPARC_LEON_PASSES_H
#define LLVM_LIB_TARGET_SPARC_LEON_PASSES_H

#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Passes.h"

#include "Sparc.h"
#include "SparcSubtarget.h"

namespace llvm {
class LLVM_LIBRARY_VISIBILITY LEONMachineFunctionPass
    : public MachineFunctionPass {
protected:
  const SparcSubtarget *Subtarget;
  const int LAST_OPERAND = -1;

  // this vector holds free registers that we allocate in groups for some of the
  // LEON passes
  std::vector<int> UsedRegisters;

protected:
  LEONMachineFunctionPass(TargetMachine &tm, char &ID);
  LEONMachineFunctionPass(char &ID);

  int GetRegIndexForOperand(MachineInstr &MI, int OperandIndex);
  void clearUsedRegisterList() { UsedRegisters.clear(); }

  void markRegisterUsed(int registerIndex) {
    UsedRegisters.push_back(registerIndex);
  }
  int getUnusedFPRegister(MachineRegisterInfo &MRI);
};

class LLVM_LIBRARY_VISIBILITY ReplaceSDIV : public LEONMachineFunctionPass {
public:
  static char ID;

  ReplaceSDIV();
  ReplaceSDIV(TargetMachine &tm);
  bool runOnMachineFunction(MachineFunction &MF) override;

  const char *getPassName() const override {
    return "ReplaceSDIV: Leon erratum fix:  do not emit SDIV, but emit SDIVCC "
           "instead";
  }
};

class LLVM_LIBRARY_VISIBILITY FixCALL : public LEONMachineFunctionPass {
public:
  static char ID;

  FixCALL(TargetMachine &tm);
  bool runOnMachineFunction(MachineFunction &MF) override;

  const char *getPassName() const override {
    return "FixCALL: Leon erratum fix: restrict the size of the immediate "
           "operand of the CALL instruction to 20 bits";
  }
};

class LLVM_LIBRARY_VISIBILITY RestoreExecAddress : public LEONMachineFunctionPass {
public:
  static char ID;

  RestoreExecAddress(TargetMachine &tm);
  bool runOnMachineFunction(MachineFunction& MF) override;

  const char *getPassName() const override {
    return "RestoreExecAddress: Leon erratum fix: ensure execution "
           "address is restored for bad floating point trap handlers.";
  }
};

class LLVM_LIBRARY_VISIBILITY IgnoreZeroFlag : public LEONMachineFunctionPass {
public:
  static char ID;

  IgnoreZeroFlag(TargetMachine &tm);
  bool runOnMachineFunction(MachineFunction &MF) override;

  const char *getPassName() const override {
    return "IgnoreZeroFlag: Leon erratum fix: do not rely on the zero bit "
           "flag on a divide overflow for SDIVCC and UDIVCC";
  }
};

class LLVM_LIBRARY_VISIBILITY FillDataCache : public LEONMachineFunctionPass {
public:
  static char ID;
  static bool CacheFilled;

  FillDataCache(TargetMachine &tm);
  bool runOnMachineFunction(MachineFunction& MF) override;

  const char *getPassName() const override {
    return "FillDataCache: Leon erratum fix: fill data cache with values at application startup";
  }
};

class LLVM_LIBRARY_VISIBILITY InsertNOPDoublePrecision
    : public LEONMachineFunctionPass {
public:
  static char ID;

  InsertNOPDoublePrecision(TargetMachine &tm);
  bool runOnMachineFunction(MachineFunction &MF) override;

  const char *getPassName() const override {
    return "InsertNOPDoublePrecision: Leon erratum fix: insert a NOP before "
           "the double precision floating point instruction";
  }
};

class LLVM_LIBRARY_VISIBILITY FixFSMULD : public LEONMachineFunctionPass {
public:
  static char ID;

  FixFSMULD(TargetMachine &tm);
  bool runOnMachineFunction(MachineFunction &MF) override;

  const char *getPassName() const override {
    return "FixFSMULD: Leon erratum fix: do not utilize FSMULD";
  }
};

class LLVM_LIBRARY_VISIBILITY ReplaceFMULS : public LEONMachineFunctionPass {
public:
  static char ID;

  ReplaceFMULS(TargetMachine &tm);
  bool runOnMachineFunction(MachineFunction &MF) override;

  const char *getPassName() const override {
    return "ReplaceFMULS: Leon erratum fix: Replace FMULS instruction with a "
           "routine using conversions/double precision operations to replace "
           "FMULS";
  }
};

class LLVM_LIBRARY_VISIBILITY PreventRoundChange
    : public LEONMachineFunctionPass {
public:
  static char ID;

  PreventRoundChange(TargetMachine &tm);
  bool runOnMachineFunction(MachineFunction &MF) override;

  const char *getPassName() const override {
    return "PreventRoundChange: Leon erratum fix: prevent any rounding mode "
           "change request: use only the round-to-nearest rounding mode";
  }
};

class LLVM_LIBRARY_VISIBILITY FixAllFDIVSQRT : public LEONMachineFunctionPass {
public:
  static char ID;

  FixAllFDIVSQRT(TargetMachine &tm);
  bool runOnMachineFunction(MachineFunction &MF) override;

  const char *getPassName() const override {
    return "FixAllFDIVSQRT: Leon erratum fix: Fix FDIVS/FDIVD/FSQRTS/FSQRTD "
           "instructions with NOPs and floating-point store";
  }
};

class LLVM_LIBRARY_VISIBILITY InsertNOPLoad : public LEONMachineFunctionPass {
public:
  static char ID;

  InsertNOPLoad(TargetMachine &tm);
  bool runOnMachineFunction(MachineFunction &MF) override;

  const char *getPassName() const override {
    return "InsertNOPLoad: Leon erratum fix: Insert a NOP instruction after "
           "every single-cycle load instruction when the next instruction is "
           "another load/store instruction";
  }
};

class LLVM_LIBRARY_VISIBILITY InsertNOPsLoadStore
    : public LEONMachineFunctionPass {
public:
  static char ID;

  InsertNOPsLoadStore(TargetMachine &tm);
  bool runOnMachineFunction(MachineFunction &MF) override;

  const char *getPassName() const override {
    return "InsertNOPsLoadStore: Leon Erratum Fix: Insert NOPs between "
           "single-precision loads and the store, so the number of "
           "instructions between is 4";
  }
};
} // namespace lllvm

#endif // LLVM_LIB_TARGET_SPARC_LEON_PASSES_H
OpenPOWER on IntegriCloud