blob: 0926c072f9e183dafeca4fa82126797ab31e258c [file] [log] [blame]
Misha Brukmanb01a80a2003-12-17 22:04:00 +00001//===-- SparcInstrInfo.h - Define TargetInstrInfo for Sparc -----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This class contains information about individual instructions.
11// Most information is stored in the SparcMachineInstrDesc array above.
12// Other information is computed on demand, and most such functions
13// default to member functions in base class TargetInstrInfo.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef SPARC_INSTRINFO_H
18#define SPARC_INSTRINFO_H
19
20#include "llvm/Target/TargetInstrInfo.h"
21#include "llvm/CodeGen/MachineInstr.h"
22#include "SparcInternals.h"
23
24namespace llvm {
25
26struct SparcInstrInfo : public TargetInstrInfo {
27 SparcInstrInfo();
28
29 // All immediate constants are in position 1 except the
30 // store instructions and SETxx.
31 //
32 virtual int getImmedConstantPos(MachineOpCode opCode) const {
33 bool ignore;
34 if (this->maxImmedConstant(opCode, ignore) != 0) {
35 // 1st store opcode
36 assert(! this->isStore((MachineOpCode) V9::STBr - 1));
37 // last store opcode
38 assert(! this->isStore((MachineOpCode) V9::STXFSRi + 1));
39
40 if (opCode == V9::SETSW || opCode == V9::SETUW ||
41 opCode == V9::SETX || opCode == V9::SETHI)
42 return 0;
43 if (opCode >= V9::STBr && opCode <= V9::STXFSRi)
44 return 2;
45 return 1;
46 }
47 else
48 return -1;
49 }
50
51 /// createNOPinstr - returns the target's implementation of NOP, which is
52 /// usually a pseudo-instruction, implemented by a degenerate version of
53 /// another instruction, e.g. X86: xchg ax, ax; SparcV9: sethi 0, g0
54 ///
55 MachineInstr* createNOPinstr() const {
56 return BuildMI(V9::SETHI, 2).addZImm(0).addReg(SparcIntRegClass::g0);
57 }
58
59 /// isNOPinstr - not having a special NOP opcode, we need to know if a given
60 /// instruction is interpreted as an `official' NOP instr, i.e., there may be
61 /// more than one way to `do nothing' but only one canonical way to slack off.
62 ///
63 bool isNOPinstr(const MachineInstr &MI) const {
64 // Make sure the instruction is EXACTLY `sethi g0, 0'
65 if (MI.getOpcode() == V9::SETHI && MI.getNumOperands() == 2) {
66 const MachineOperand &op0 = MI.getOperand(0), &op1 = MI.getOperand(1);
67 if (op0.isImmediate() && op0.getImmedValue() == 0 &&
68 op1.isMachineRegister() &&
69 op1.getMachineRegNum() == SparcIntRegClass::g0)
70 {
71 return true;
72 }
73 }
74 return false;
75 }
76
77 virtual bool hasResultInterlock(MachineOpCode opCode) const
78 {
79 // All UltraSPARC instructions have interlocks (note that delay slots
80 // are not considered here).
81 // However, instructions that use the result of an FCMP produce a
82 // 9-cycle stall if they are issued less than 3 cycles after the FCMP.
83 // Force the compiler to insert a software interlock (i.e., gap of
84 // 2 other groups, including NOPs if necessary).
85 return (opCode == V9::FCMPS || opCode == V9::FCMPD || opCode == V9::FCMPQ);
86 }
87
88 //-------------------------------------------------------------------------
89 // Queries about representation of LLVM quantities (e.g., constants)
90 //-------------------------------------------------------------------------
91
92 virtual bool ConstantMayNotFitInImmedField(const Constant* CV,
93 const Instruction* I) const;
94
95 //-------------------------------------------------------------------------
96 // Code generation support for creating individual machine instructions
97 //-------------------------------------------------------------------------
98
99 // Get certain common op codes for the current target. This and all the
100 // Create* methods below should be moved to a machine code generation class
101 //
102 virtual MachineOpCode getNOPOpCode() const { return V9::NOP; }
103
104 // Get the value of an integral constant in the form that must
105 // be put into the machine register. The specified constant is interpreted
106 // as (i.e., converted if necessary to) the specified destination type. The
107 // result is always returned as an uint64_t, since the representation of
108 // int64_t and uint64_t are identical. The argument can be any known const.
109 //
110 // isValidConstant is set to true if a valid constant was found.
111 //
112 virtual uint64_t ConvertConstantToIntType(const TargetMachine &target,
113 const Value *V,
114 const Type *destType,
115 bool &isValidConstant) const;
116
117 // Create an instruction sequence to put the constant `val' into
118 // the virtual register `dest'. `val' may be a Constant or a
119 // GlobalValue, viz., the constant address of a global variable or function.
120 // The generated instructions are returned in `mvec'.
121 // Any temp. registers (TmpInstruction) created are recorded in mcfi.
122 // Any stack space required is allocated via mcff.
123 //
124 virtual void CreateCodeToLoadConst(const TargetMachine& target,
125 Function* F,
126 Value* val,
127 Instruction* dest,
128 std::vector<MachineInstr*>& mvec,
129 MachineCodeForInstruction& mcfi) const;
130
131 // Create an instruction sequence to copy an integer value `val'
132 // to a floating point value `dest' by copying to memory and back.
133 // val must be an integral type. dest must be a Float or Double.
134 // The generated instructions are returned in `mvec'.
135 // Any temp. registers (TmpInstruction) created are recorded in mcfi.
136 // Any stack space required is allocated via mcff.
137 //
138 virtual void CreateCodeToCopyIntToFloat(const TargetMachine& target,
139 Function* F,
140 Value* val,
141 Instruction* dest,
142 std::vector<MachineInstr*>& mvec,
143 MachineCodeForInstruction& mcfi) const;
144
145 // Similarly, create an instruction sequence to copy an FP value
146 // `val' to an integer value `dest' by copying to memory and back.
147 // The generated instructions are returned in `mvec'.
148 // Any temp. registers (TmpInstruction) created are recorded in mcfi.
149 // Any stack space required is allocated via mcff.
150 //
151 virtual void CreateCodeToCopyFloatToInt(const TargetMachine& target,
152 Function* F,
153 Value* val,
154 Instruction* dest,
155 std::vector<MachineInstr*>& mvec,
156 MachineCodeForInstruction& mcfi) const;
157
158 // Create instruction(s) to copy src to dest, for arbitrary types
159 // The generated instructions are returned in `mvec'.
160 // Any temp. registers (TmpInstruction) created are recorded in mcfi.
161 // Any stack space required is allocated via mcff.
162 //
163 virtual void CreateCopyInstructionsByType(const TargetMachine& target,
164 Function* F,
165 Value* src,
166 Instruction* dest,
167 std::vector<MachineInstr*>& mvec,
168 MachineCodeForInstruction& mcfi) const;
169
170 // Create instruction sequence to produce a sign-extended register value
171 // from an arbitrary sized value (sized in bits, not bytes).
172 // The generated instructions are appended to `mvec'.
173 // Any temp. registers (TmpInstruction) created are recorded in mcfi.
174 // Any stack space required is allocated via mcff.
175 //
176 virtual void CreateSignExtensionInstructions(const TargetMachine& target,
177 Function* F,
178 Value* srcVal,
179 Value* destVal,
180 unsigned int numLowBits,
181 std::vector<MachineInstr*>& mvec,
182 MachineCodeForInstruction& mcfi) const;
183
184 // Create instruction sequence to produce a zero-extended register value
185 // from an arbitrary sized value (sized in bits, not bytes).
186 // The generated instructions are appended to `mvec'.
187 // Any temp. registers (TmpInstruction) created are recorded in mcfi.
188 // Any stack space required is allocated via mcff.
189 //
190 virtual void CreateZeroExtensionInstructions(const TargetMachine& target,
191 Function* F,
192 Value* srcVal,
193 Value* destVal,
194 unsigned int numLowBits,
195 std::vector<MachineInstr*>& mvec,
196 MachineCodeForInstruction& mcfi) const;
197};
198
199} // End llvm namespace
200
201#endif