0be2544c6079c360e3f93b894249cdf1cce27f24
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9InstrInfo.h
1 //===-- 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
24 namespace llvm {
25
26 struct 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.getType() == MachineOperand::MO_MachineRegister &&
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