File: | lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp |
Warning: | line 259, column 7 Value stored to 'Opcode' is never read |
1 | //===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | // |
10 | // This file implements the MipsMCCodeEmitter class. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "MipsMCCodeEmitter.h" |
15 | #include "MCTargetDesc/MipsFixupKinds.h" |
16 | #include "MCTargetDesc/MipsMCExpr.h" |
17 | #include "MCTargetDesc/MipsMCTargetDesc.h" |
18 | #include "llvm/ADT/APFloat.h" |
19 | #include "llvm/ADT/APInt.h" |
20 | #include "llvm/ADT/SmallVector.h" |
21 | #include "llvm/MC/MCContext.h" |
22 | #include "llvm/MC/MCExpr.h" |
23 | #include "llvm/MC/MCFixup.h" |
24 | #include "llvm/MC/MCInst.h" |
25 | #include "llvm/MC/MCInstrDesc.h" |
26 | #include "llvm/MC/MCInstrInfo.h" |
27 | #include "llvm/MC/MCRegisterInfo.h" |
28 | #include "llvm/MC/MCSubtargetInfo.h" |
29 | #include "llvm/Support/Casting.h" |
30 | #include "llvm/Support/ErrorHandling.h" |
31 | #include "llvm/Support/raw_ostream.h" |
32 | #include <cassert> |
33 | #include <cstdint> |
34 | |
35 | using namespace llvm; |
36 | |
37 | #define DEBUG_TYPE"mccodeemitter" "mccodeemitter" |
38 | |
39 | #define GET_INSTRMAP_INFO |
40 | #include "MipsGenInstrInfo.inc" |
41 | #undef GET_INSTRMAP_INFO |
42 | |
43 | namespace llvm { |
44 | |
45 | MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, |
46 | const MCRegisterInfo &MRI, |
47 | MCContext &Ctx) { |
48 | return new MipsMCCodeEmitter(MCII, Ctx, false); |
49 | } |
50 | |
51 | MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, |
52 | const MCRegisterInfo &MRI, |
53 | MCContext &Ctx) { |
54 | return new MipsMCCodeEmitter(MCII, Ctx, true); |
55 | } |
56 | |
57 | } // end namespace llvm |
58 | |
59 | // If the D<shift> instruction has a shift amount that is greater |
60 | // than 31 (checked in calling routine), lower it to a D<shift>32 instruction |
61 | static void LowerLargeShift(MCInst& Inst) { |
62 | assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!")((Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!" ) ? static_cast<void> (0) : __assert_fail ("Inst.getNumOperands() == 3 && \"Invalid no. of operands for shift!\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 62, __PRETTY_FUNCTION__)); |
63 | assert(Inst.getOperand(2).isImm())((Inst.getOperand(2).isImm()) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isImm()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 63, __PRETTY_FUNCTION__)); |
64 | |
65 | int64_t Shift = Inst.getOperand(2).getImm(); |
66 | if (Shift <= 31) |
67 | return; // Do nothing |
68 | Shift -= 32; |
69 | |
70 | // saminus32 |
71 | Inst.getOperand(2).setImm(Shift); |
72 | |
73 | switch (Inst.getOpcode()) { |
74 | default: |
75 | // Calling function is not synchronized |
76 | llvm_unreachable("Unexpected shift instruction")::llvm::llvm_unreachable_internal("Unexpected shift instruction" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 76); |
77 | case Mips::DSLL: |
78 | Inst.setOpcode(Mips::DSLL32); |
79 | return; |
80 | case Mips::DSRL: |
81 | Inst.setOpcode(Mips::DSRL32); |
82 | return; |
83 | case Mips::DSRA: |
84 | Inst.setOpcode(Mips::DSRA32); |
85 | return; |
86 | case Mips::DROTR: |
87 | Inst.setOpcode(Mips::DROTR32); |
88 | return; |
89 | case Mips::DSLL_MM64R6: |
90 | Inst.setOpcode(Mips::DSLL32_MM64R6); |
91 | return; |
92 | case Mips::DSRL_MM64R6: |
93 | Inst.setOpcode(Mips::DSRL32_MM64R6); |
94 | return; |
95 | case Mips::DSRA_MM64R6: |
96 | Inst.setOpcode(Mips::DSRA32_MM64R6); |
97 | return; |
98 | case Mips::DROTR_MM64R6: |
99 | Inst.setOpcode(Mips::DROTR32_MM64R6); |
100 | return; |
101 | } |
102 | } |
103 | |
104 | // Pick a DINS instruction variant based on the pos and size operands |
105 | static void LowerDins(MCInst& InstIn) { |
106 | assert(InstIn.getNumOperands() == 5 &&((InstIn.getNumOperands() == 5 && "Invalid no. of machine operands for DINS!" ) ? static_cast<void> (0) : __assert_fail ("InstIn.getNumOperands() == 5 && \"Invalid no. of machine operands for DINS!\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 107, __PRETTY_FUNCTION__)) |
107 | "Invalid no. of machine operands for DINS!")((InstIn.getNumOperands() == 5 && "Invalid no. of machine operands for DINS!" ) ? static_cast<void> (0) : __assert_fail ("InstIn.getNumOperands() == 5 && \"Invalid no. of machine operands for DINS!\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 107, __PRETTY_FUNCTION__)); |
108 | |
109 | assert(InstIn.getOperand(2).isImm())((InstIn.getOperand(2).isImm()) ? static_cast<void> (0) : __assert_fail ("InstIn.getOperand(2).isImm()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 109, __PRETTY_FUNCTION__)); |
110 | int64_t pos = InstIn.getOperand(2).getImm(); |
111 | assert(InstIn.getOperand(3).isImm())((InstIn.getOperand(3).isImm()) ? static_cast<void> (0) : __assert_fail ("InstIn.getOperand(3).isImm()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 111, __PRETTY_FUNCTION__)); |
112 | int64_t size = InstIn.getOperand(3).getImm(); |
113 | |
114 | assert((pos + size) <= 64 &&(((pos + size) <= 64 && "DINS cannot have position plus size over 64" ) ? static_cast<void> (0) : __assert_fail ("(pos + size) <= 64 && \"DINS cannot have position plus size over 64\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 115, __PRETTY_FUNCTION__)) |
115 | "DINS cannot have position plus size over 64")(((pos + size) <= 64 && "DINS cannot have position plus size over 64" ) ? static_cast<void> (0) : __assert_fail ("(pos + size) <= 64 && \"DINS cannot have position plus size over 64\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 115, __PRETTY_FUNCTION__)); |
116 | if (pos < 32) { |
117 | if ((pos + size) > 0 && (pos + size) <= 32) |
118 | return; // DINS, do nothing |
119 | else if ((pos + size) > 32) { |
120 | //DINSM |
121 | InstIn.getOperand(3).setImm(size - 32); |
122 | InstIn.setOpcode(Mips::DINSM); |
123 | } |
124 | } else if ((pos + size) > 32 && (pos + size) <= 64) { |
125 | // DINSU |
126 | InstIn.getOperand(2).setImm(pos - 32); |
127 | InstIn.setOpcode(Mips::DINSU); |
128 | } |
129 | } |
130 | |
131 | // Fix a bad compact branch encoding for beqc/bnec. |
132 | void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const { |
133 | // Encoding may be illegal !(rs < rt), but this situation is |
134 | // easily fixed. |
135 | unsigned RegOp0 = Inst.getOperand(0).getReg(); |
136 | unsigned RegOp1 = Inst.getOperand(1).getReg(); |
137 | |
138 | unsigned Reg0 = Ctx.getRegisterInfo()->getEncodingValue(RegOp0); |
139 | unsigned Reg1 = Ctx.getRegisterInfo()->getEncodingValue(RegOp1); |
140 | |
141 | if (Inst.getOpcode() == Mips::BNEC || Inst.getOpcode() == Mips::BEQC || |
142 | Inst.getOpcode() == Mips::BNEC64 || Inst.getOpcode() == Mips::BEQC64) { |
143 | assert(Reg0 != Reg1 && "Instruction has bad operands ($rs == $rt)!")((Reg0 != Reg1 && "Instruction has bad operands ($rs == $rt)!" ) ? static_cast<void> (0) : __assert_fail ("Reg0 != Reg1 && \"Instruction has bad operands ($rs == $rt)!\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 143, __PRETTY_FUNCTION__)); |
144 | if (Reg0 < Reg1) |
145 | return; |
146 | } else if (Inst.getOpcode() == Mips::BNVC || Inst.getOpcode() == Mips::BOVC) { |
147 | if (Reg0 >= Reg1) |
148 | return; |
149 | } else if (Inst.getOpcode() == Mips::BNVC_MMR6 || |
150 | Inst.getOpcode() == Mips::BOVC_MMR6) { |
151 | if (Reg1 >= Reg0) |
152 | return; |
153 | } else |
154 | llvm_unreachable("Cannot rewrite unknown branch!")::llvm::llvm_unreachable_internal("Cannot rewrite unknown branch!" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 154); |
155 | |
156 | Inst.getOperand(0).setReg(RegOp1); |
157 | Inst.getOperand(1).setReg(RegOp0); |
158 | } |
159 | |
160 | bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { |
161 | return STI.getFeatureBits()[Mips::FeatureMicroMips]; |
162 | } |
163 | |
164 | bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const { |
165 | return STI.getFeatureBits()[Mips::FeatureMips32r6]; |
166 | } |
167 | |
168 | void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { |
169 | OS << (char)C; |
170 | } |
171 | |
172 | void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, |
173 | const MCSubtargetInfo &STI, |
174 | raw_ostream &OS) const { |
175 | // Output the instruction encoding in little endian byte order. |
176 | // Little-endian byte ordering: |
177 | // mips32r2: 4 | 3 | 2 | 1 |
178 | // microMIPS: 2 | 1 | 4 | 3 |
179 | if (IsLittleEndian && Size == 4 && isMicroMips(STI)) { |
180 | EmitInstruction(Val >> 16, 2, STI, OS); |
181 | EmitInstruction(Val, 2, STI, OS); |
182 | } else { |
183 | for (unsigned i = 0; i < Size; ++i) { |
184 | unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; |
185 | EmitByte((Val >> Shift) & 0xff, OS); |
186 | } |
187 | } |
188 | } |
189 | |
190 | /// encodeInstruction - Emit the instruction. |
191 | /// Size the instruction with Desc.getSize(). |
192 | void MipsMCCodeEmitter:: |
193 | encodeInstruction(const MCInst &MI, raw_ostream &OS, |
194 | SmallVectorImpl<MCFixup> &Fixups, |
195 | const MCSubtargetInfo &STI) const |
196 | { |
197 | // Non-pseudo instructions that get changed for direct object |
198 | // only based on operand values. |
199 | // If this list of instructions get much longer we will move |
200 | // the check to a function call. Until then, this is more efficient. |
201 | MCInst TmpInst = MI; |
202 | switch (MI.getOpcode()) { |
203 | // If shift amount is >= 32 it the inst needs to be lowered further |
204 | case Mips::DSLL: |
205 | case Mips::DSRL: |
206 | case Mips::DSRA: |
207 | case Mips::DROTR: |
208 | case Mips::DSLL_MM64R6: |
209 | case Mips::DSRL_MM64R6: |
210 | case Mips::DSRA_MM64R6: |
211 | case Mips::DROTR_MM64R6: |
212 | LowerLargeShift(TmpInst); |
213 | break; |
214 | // Double extract instruction is chosen by pos and size operands |
215 | case Mips::DINS: |
216 | LowerDins(TmpInst); |
217 | break; |
218 | // Compact branches, enforce encoding restrictions. |
219 | case Mips::BEQC: |
220 | case Mips::BNEC: |
221 | case Mips::BEQC64: |
222 | case Mips::BNEC64: |
223 | case Mips::BOVC: |
224 | case Mips::BOVC_MMR6: |
225 | case Mips::BNVC: |
226 | case Mips::BNVC_MMR6: |
227 | LowerCompactBranch(TmpInst); |
228 | } |
229 | |
230 | unsigned long N = Fixups.size(); |
231 | uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); |
232 | |
233 | // Check for unimplemented opcodes. |
234 | // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0 |
235 | // so we have to special check for them. |
236 | unsigned Opcode = TmpInst.getOpcode(); |
237 | if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && |
238 | (Opcode != Mips::SLL_MM) && !Binary) |
239 | llvm_unreachable("unimplemented opcode in encodeInstruction()")::llvm::llvm_unreachable_internal("unimplemented opcode in encodeInstruction()" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 239); |
240 | |
241 | int NewOpcode = -1; |
242 | if (isMicroMips(STI)) { |
243 | if (isMips32r6(STI)) { |
244 | NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6); |
245 | if (NewOpcode == -1) |
246 | NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6); |
247 | } |
248 | else |
249 | NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips); |
250 | |
251 | // Check whether it is Dsp instruction. |
252 | if (NewOpcode == -1) |
253 | NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp); |
254 | |
255 | if (NewOpcode != -1) { |
256 | if (Fixups.size() > N) |
257 | Fixups.pop_back(); |
258 | |
259 | Opcode = NewOpcode; |
Value stored to 'Opcode' is never read | |
260 | TmpInst.setOpcode (NewOpcode); |
261 | Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); |
262 | } |
263 | } |
264 | |
265 | const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); |
266 | |
267 | // Get byte count of instruction |
268 | unsigned Size = Desc.getSize(); |
269 | if (!Size) |
270 | llvm_unreachable("Desc.getSize() returns 0")::llvm::llvm_unreachable_internal("Desc.getSize() returns 0", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 270); |
271 | |
272 | EmitInstruction(Binary, Size, STI, OS); |
273 | } |
274 | |
275 | /// getBranchTargetOpValue - Return binary encoding of the branch |
276 | /// target operand. If the machine operand requires relocation, |
277 | /// record the relocation and return zero. |
278 | unsigned MipsMCCodeEmitter:: |
279 | getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, |
280 | SmallVectorImpl<MCFixup> &Fixups, |
281 | const MCSubtargetInfo &STI) const { |
282 | const MCOperand &MO = MI.getOperand(OpNo); |
283 | |
284 | // If the destination is an immediate, divide by 4. |
285 | if (MO.isImm()) return MO.getImm() >> 2; |
286 | |
287 | assert(MO.isExpr() &&((MO.isExpr() && "getBranchTargetOpValue expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTargetOpValue expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 288, __PRETTY_FUNCTION__)) |
288 | "getBranchTargetOpValue expects only expressions or immediates")((MO.isExpr() && "getBranchTargetOpValue expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTargetOpValue expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 288, __PRETTY_FUNCTION__)); |
289 | |
290 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
291 | MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); |
292 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
293 | MCFixupKind(Mips::fixup_Mips_PC16))); |
294 | return 0; |
295 | } |
296 | |
297 | /// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch |
298 | /// target operand. If the machine operand requires relocation, |
299 | /// record the relocation and return zero. |
300 | unsigned MipsMCCodeEmitter:: |
301 | getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo, |
302 | SmallVectorImpl<MCFixup> &Fixups, |
303 | const MCSubtargetInfo &STI) const { |
304 | const MCOperand &MO = MI.getOperand(OpNo); |
305 | |
306 | // If the destination is an immediate, divide by 2. |
307 | if (MO.isImm()) return MO.getImm() >> 1; |
308 | |
309 | assert(MO.isExpr() &&((MO.isExpr() && "getBranchTargetOpValue expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTargetOpValue expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 310, __PRETTY_FUNCTION__)) |
310 | "getBranchTargetOpValue expects only expressions or immediates")((MO.isExpr() && "getBranchTargetOpValue expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTargetOpValue expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 310, __PRETTY_FUNCTION__)); |
311 | |
312 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
313 | MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); |
314 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
315 | MCFixupKind(Mips::fixup_Mips_PC16))); |
316 | return 0; |
317 | } |
318 | |
319 | /// getBranchTargetOpValueMMR6 - Return binary encoding of the branch |
320 | /// target operand. If the machine operand requires relocation, |
321 | /// record the relocation and return zero. |
322 | unsigned MipsMCCodeEmitter:: |
323 | getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo, |
324 | SmallVectorImpl<MCFixup> &Fixups, |
325 | const MCSubtargetInfo &STI) const { |
326 | const MCOperand &MO = MI.getOperand(OpNo); |
327 | |
328 | // If the destination is an immediate, divide by 2. |
329 | if (MO.isImm()) |
330 | return MO.getImm() >> 1; |
331 | |
332 | assert(MO.isExpr() &&((MO.isExpr() && "getBranchTargetOpValueMMR6 expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTargetOpValueMMR6 expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 333, __PRETTY_FUNCTION__)) |
333 | "getBranchTargetOpValueMMR6 expects only expressions or immediates")((MO.isExpr() && "getBranchTargetOpValueMMR6 expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTargetOpValueMMR6 expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 333, __PRETTY_FUNCTION__)); |
334 | |
335 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
336 | MO.getExpr(), MCConstantExpr::create(-2, Ctx), Ctx); |
337 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
338 | MCFixupKind(Mips::fixup_Mips_PC16))); |
339 | return 0; |
340 | } |
341 | |
342 | /// getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch |
343 | /// target operand. If the machine operand requires relocation, |
344 | /// record the relocation and return zero. |
345 | unsigned MipsMCCodeEmitter:: |
346 | getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo, |
347 | SmallVectorImpl<MCFixup> &Fixups, |
348 | const MCSubtargetInfo &STI) const { |
349 | const MCOperand &MO = MI.getOperand(OpNo); |
350 | |
351 | // If the destination is an immediate, divide by 4. |
352 | if (MO.isImm()) |
353 | return MO.getImm() >> 2; |
354 | |
355 | assert(MO.isExpr() &&((MO.isExpr() && "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 356, __PRETTY_FUNCTION__)) |
356 | "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates")((MO.isExpr() && "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 356, __PRETTY_FUNCTION__)); |
357 | |
358 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
359 | MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); |
360 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
361 | MCFixupKind(Mips::fixup_Mips_PC16))); |
362 | return 0; |
363 | } |
364 | |
365 | /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch |
366 | /// target operand. If the machine operand requires relocation, |
367 | /// record the relocation and return zero. |
368 | unsigned MipsMCCodeEmitter:: |
369 | getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, |
370 | SmallVectorImpl<MCFixup> &Fixups, |
371 | const MCSubtargetInfo &STI) const { |
372 | const MCOperand &MO = MI.getOperand(OpNo); |
373 | |
374 | // If the destination is an immediate, divide by 2. |
375 | if (MO.isImm()) return MO.getImm() >> 1; |
376 | |
377 | assert(MO.isExpr() &&((MO.isExpr() && "getBranchTargetOpValueMM expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTargetOpValueMM expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 378, __PRETTY_FUNCTION__)) |
378 | "getBranchTargetOpValueMM expects only expressions or immediates")((MO.isExpr() && "getBranchTargetOpValueMM expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTargetOpValueMM expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 378, __PRETTY_FUNCTION__)); |
379 | |
380 | const MCExpr *Expr = MO.getExpr(); |
381 | Fixups.push_back(MCFixup::create(0, Expr, |
382 | MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1))); |
383 | return 0; |
384 | } |
385 | |
386 | /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS |
387 | /// 10-bit branch target operand. If the machine operand requires relocation, |
388 | /// record the relocation and return zero. |
389 | unsigned MipsMCCodeEmitter:: |
390 | getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo, |
391 | SmallVectorImpl<MCFixup> &Fixups, |
392 | const MCSubtargetInfo &STI) const { |
393 | const MCOperand &MO = MI.getOperand(OpNo); |
394 | |
395 | // If the destination is an immediate, divide by 2. |
396 | if (MO.isImm()) return MO.getImm() >> 1; |
397 | |
398 | assert(MO.isExpr() &&((MO.isExpr() && "getBranchTargetOpValuePC10 expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTargetOpValuePC10 expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 399, __PRETTY_FUNCTION__)) |
399 | "getBranchTargetOpValuePC10 expects only expressions or immediates")((MO.isExpr() && "getBranchTargetOpValuePC10 expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTargetOpValuePC10 expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 399, __PRETTY_FUNCTION__)); |
400 | |
401 | const MCExpr *Expr = MO.getExpr(); |
402 | Fixups.push_back(MCFixup::create(0, Expr, |
403 | MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1))); |
404 | return 0; |
405 | } |
406 | |
407 | /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch |
408 | /// target operand. If the machine operand requires relocation, |
409 | /// record the relocation and return zero. |
410 | unsigned MipsMCCodeEmitter:: |
411 | getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, |
412 | SmallVectorImpl<MCFixup> &Fixups, |
413 | const MCSubtargetInfo &STI) const { |
414 | const MCOperand &MO = MI.getOperand(OpNo); |
415 | |
416 | // If the destination is an immediate, divide by 2. |
417 | if (MO.isImm()) return MO.getImm() >> 1; |
418 | |
419 | assert(MO.isExpr() &&((MO.isExpr() && "getBranchTargetOpValueMM expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTargetOpValueMM expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 420, __PRETTY_FUNCTION__)) |
420 | "getBranchTargetOpValueMM expects only expressions or immediates")((MO.isExpr() && "getBranchTargetOpValueMM expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTargetOpValueMM expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 420, __PRETTY_FUNCTION__)); |
421 | |
422 | const MCExpr *Expr = MO.getExpr(); |
423 | Fixups.push_back(MCFixup::create(0, Expr, |
424 | MCFixupKind(Mips:: |
425 | fixup_MICROMIPS_PC16_S1))); |
426 | return 0; |
427 | } |
428 | |
429 | /// getBranchTarget21OpValue - Return binary encoding of the branch |
430 | /// target operand. If the machine operand requires relocation, |
431 | /// record the relocation and return zero. |
432 | unsigned MipsMCCodeEmitter:: |
433 | getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, |
434 | SmallVectorImpl<MCFixup> &Fixups, |
435 | const MCSubtargetInfo &STI) const { |
436 | const MCOperand &MO = MI.getOperand(OpNo); |
437 | |
438 | // If the destination is an immediate, divide by 4. |
439 | if (MO.isImm()) return MO.getImm() >> 2; |
440 | |
441 | assert(MO.isExpr() &&((MO.isExpr() && "getBranchTarget21OpValue expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTarget21OpValue expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 442, __PRETTY_FUNCTION__)) |
442 | "getBranchTarget21OpValue expects only expressions or immediates")((MO.isExpr() && "getBranchTarget21OpValue expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTarget21OpValue expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 442, __PRETTY_FUNCTION__)); |
443 | |
444 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
445 | MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); |
446 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
447 | MCFixupKind(Mips::fixup_MIPS_PC21_S2))); |
448 | return 0; |
449 | } |
450 | |
451 | /// getBranchTarget21OpValueMM - Return binary encoding of the branch |
452 | /// target operand for microMIPS. If the machine operand requires |
453 | /// relocation, record the relocation and return zero. |
454 | unsigned MipsMCCodeEmitter:: |
455 | getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo, |
456 | SmallVectorImpl<MCFixup> &Fixups, |
457 | const MCSubtargetInfo &STI) const { |
458 | const MCOperand &MO = MI.getOperand(OpNo); |
459 | |
460 | // If the destination is an immediate, divide by 4. |
461 | if (MO.isImm()) return MO.getImm() >> 2; |
462 | |
463 | assert(MO.isExpr() &&((MO.isExpr() && "getBranchTarget21OpValueMM expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTarget21OpValueMM expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 464, __PRETTY_FUNCTION__)) |
464 | "getBranchTarget21OpValueMM expects only expressions or immediates")((MO.isExpr() && "getBranchTarget21OpValueMM expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTarget21OpValueMM expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 464, __PRETTY_FUNCTION__)); |
465 | |
466 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
467 | MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); |
468 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
469 | MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1))); |
470 | return 0; |
471 | } |
472 | |
473 | /// getBranchTarget26OpValue - Return binary encoding of the branch |
474 | /// target operand. If the machine operand requires relocation, |
475 | /// record the relocation and return zero. |
476 | unsigned MipsMCCodeEmitter:: |
477 | getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, |
478 | SmallVectorImpl<MCFixup> &Fixups, |
479 | const MCSubtargetInfo &STI) const { |
480 | const MCOperand &MO = MI.getOperand(OpNo); |
481 | |
482 | // If the destination is an immediate, divide by 4. |
483 | if (MO.isImm()) return MO.getImm() >> 2; |
484 | |
485 | assert(MO.isExpr() &&((MO.isExpr() && "getBranchTarget26OpValue expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTarget26OpValue expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 486, __PRETTY_FUNCTION__)) |
486 | "getBranchTarget26OpValue expects only expressions or immediates")((MO.isExpr() && "getBranchTarget26OpValue expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTarget26OpValue expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 486, __PRETTY_FUNCTION__)); |
487 | |
488 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
489 | MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); |
490 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
491 | MCFixupKind(Mips::fixup_MIPS_PC26_S2))); |
492 | return 0; |
493 | } |
494 | |
495 | /// getBranchTarget26OpValueMM - Return binary encoding of the branch |
496 | /// target operand. If the machine operand requires relocation, |
497 | /// record the relocation and return zero. |
498 | unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM( |
499 | const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, |
500 | const MCSubtargetInfo &STI) const { |
501 | const MCOperand &MO = MI.getOperand(OpNo); |
502 | |
503 | // If the destination is an immediate, divide by 2. |
504 | if (MO.isImm()) |
505 | return MO.getImm() >> 1; |
506 | |
507 | assert(MO.isExpr() &&((MO.isExpr() && "getBranchTarget26OpValueMM expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTarget26OpValueMM expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 508, __PRETTY_FUNCTION__)) |
508 | "getBranchTarget26OpValueMM expects only expressions or immediates")((MO.isExpr() && "getBranchTarget26OpValueMM expects only expressions or immediates" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getBranchTarget26OpValueMM expects only expressions or immediates\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 508, __PRETTY_FUNCTION__)); |
509 | |
510 | const MCExpr *FixupExpression = MCBinaryExpr::createAdd( |
511 | MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); |
512 | Fixups.push_back(MCFixup::create(0, FixupExpression, |
513 | MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1))); |
514 | return 0; |
515 | } |
516 | |
517 | /// getJumpOffset16OpValue - Return binary encoding of the jump |
518 | /// target operand. If the machine operand requires relocation, |
519 | /// record the relocation and return zero. |
520 | unsigned MipsMCCodeEmitter:: |
521 | getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, |
522 | SmallVectorImpl<MCFixup> &Fixups, |
523 | const MCSubtargetInfo &STI) const { |
524 | const MCOperand &MO = MI.getOperand(OpNo); |
525 | |
526 | if (MO.isImm()) return MO.getImm(); |
527 | |
528 | assert(MO.isExpr() &&((MO.isExpr() && "getJumpOffset16OpValue expects only expressions or an immediate" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getJumpOffset16OpValue expects only expressions or an immediate\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 529, __PRETTY_FUNCTION__)) |
529 | "getJumpOffset16OpValue expects only expressions or an immediate")((MO.isExpr() && "getJumpOffset16OpValue expects only expressions or an immediate" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getJumpOffset16OpValue expects only expressions or an immediate\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 529, __PRETTY_FUNCTION__)); |
530 | |
531 | // TODO: Push fixup. |
532 | return 0; |
533 | } |
534 | |
535 | /// getJumpTargetOpValue - Return binary encoding of the jump |
536 | /// target operand. If the machine operand requires relocation, |
537 | /// record the relocation and return zero. |
538 | unsigned MipsMCCodeEmitter:: |
539 | getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, |
540 | SmallVectorImpl<MCFixup> &Fixups, |
541 | const MCSubtargetInfo &STI) const { |
542 | const MCOperand &MO = MI.getOperand(OpNo); |
543 | // If the destination is an immediate, divide by 4. |
544 | if (MO.isImm()) return MO.getImm()>>2; |
545 | |
546 | assert(MO.isExpr() &&((MO.isExpr() && "getJumpTargetOpValue expects only expressions or an immediate" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getJumpTargetOpValue expects only expressions or an immediate\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 547, __PRETTY_FUNCTION__)) |
547 | "getJumpTargetOpValue expects only expressions or an immediate")((MO.isExpr() && "getJumpTargetOpValue expects only expressions or an immediate" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getJumpTargetOpValue expects only expressions or an immediate\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 547, __PRETTY_FUNCTION__)); |
548 | |
549 | const MCExpr *Expr = MO.getExpr(); |
550 | Fixups.push_back(MCFixup::create(0, Expr, |
551 | MCFixupKind(Mips::fixup_Mips_26))); |
552 | return 0; |
553 | } |
554 | |
555 | unsigned MipsMCCodeEmitter:: |
556 | getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, |
557 | SmallVectorImpl<MCFixup> &Fixups, |
558 | const MCSubtargetInfo &STI) const { |
559 | const MCOperand &MO = MI.getOperand(OpNo); |
560 | // If the destination is an immediate, divide by 2. |
561 | if (MO.isImm()) return MO.getImm() >> 1; |
562 | |
563 | assert(MO.isExpr() &&((MO.isExpr() && "getJumpTargetOpValueMM expects only expressions or an immediate" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getJumpTargetOpValueMM expects only expressions or an immediate\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 564, __PRETTY_FUNCTION__)) |
564 | "getJumpTargetOpValueMM expects only expressions or an immediate")((MO.isExpr() && "getJumpTargetOpValueMM expects only expressions or an immediate" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getJumpTargetOpValueMM expects only expressions or an immediate\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 564, __PRETTY_FUNCTION__)); |
565 | |
566 | const MCExpr *Expr = MO.getExpr(); |
567 | Fixups.push_back(MCFixup::create(0, Expr, |
568 | MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); |
569 | return 0; |
570 | } |
571 | |
572 | unsigned MipsMCCodeEmitter:: |
573 | getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, |
574 | SmallVectorImpl<MCFixup> &Fixups, |
575 | const MCSubtargetInfo &STI) const { |
576 | const MCOperand &MO = MI.getOperand(OpNo); |
577 | if (MO.isImm()) { |
578 | // The immediate is encoded as 'immediate << 2'. |
579 | unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); |
580 | assert((Res & 3) == 0)(((Res & 3) == 0) ? static_cast<void> (0) : __assert_fail ("(Res & 3) == 0", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 580, __PRETTY_FUNCTION__)); |
581 | return Res >> 2; |
582 | } |
583 | |
584 | assert(MO.isExpr() &&((MO.isExpr() && "getUImm5Lsl2Encoding expects only expressions or an immediate" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getUImm5Lsl2Encoding expects only expressions or an immediate\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 585, __PRETTY_FUNCTION__)) |
585 | "getUImm5Lsl2Encoding expects only expressions or an immediate")((MO.isExpr() && "getUImm5Lsl2Encoding expects only expressions or an immediate" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getUImm5Lsl2Encoding expects only expressions or an immediate\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 585, __PRETTY_FUNCTION__)); |
586 | |
587 | return 0; |
588 | } |
589 | |
590 | unsigned MipsMCCodeEmitter:: |
591 | getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, |
592 | SmallVectorImpl<MCFixup> &Fixups, |
593 | const MCSubtargetInfo &STI) const { |
594 | const MCOperand &MO = MI.getOperand(OpNo); |
595 | if (MO.isImm()) { |
596 | int Value = MO.getImm(); |
597 | return Value >> 2; |
598 | } |
599 | |
600 | return 0; |
601 | } |
602 | |
603 | unsigned MipsMCCodeEmitter:: |
604 | getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, |
605 | SmallVectorImpl<MCFixup> &Fixups, |
606 | const MCSubtargetInfo &STI) const { |
607 | const MCOperand &MO = MI.getOperand(OpNo); |
608 | if (MO.isImm()) { |
609 | unsigned Value = MO.getImm(); |
610 | return Value >> 2; |
611 | } |
612 | |
613 | return 0; |
614 | } |
615 | |
616 | unsigned MipsMCCodeEmitter:: |
617 | getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, |
618 | SmallVectorImpl<MCFixup> &Fixups, |
619 | const MCSubtargetInfo &STI) const { |
620 | const MCOperand &MO = MI.getOperand(OpNo); |
621 | if (MO.isImm()) { |
622 | unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff; |
623 | return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff)); |
624 | } |
625 | |
626 | return 0; |
627 | } |
628 | |
629 | unsigned MipsMCCodeEmitter:: |
630 | getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, |
631 | const MCSubtargetInfo &STI) const { |
632 | int64_t Res; |
633 | |
634 | if (Expr->evaluateAsAbsolute(Res)) |
635 | return Res; |
636 | |
637 | MCExpr::ExprKind Kind = Expr->getKind(); |
638 | if (Kind == MCExpr::Constant) { |
639 | return cast<MCConstantExpr>(Expr)->getValue(); |
640 | } |
641 | |
642 | if (Kind == MCExpr::Binary) { |
643 | unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); |
644 | Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); |
645 | return Res; |
646 | } |
647 | |
648 | if (Kind == MCExpr::Target) { |
649 | const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); |
650 | |
651 | Mips::Fixups FixupKind = Mips::Fixups(0); |
652 | switch (MipsExpr->getKind()) { |
653 | case MipsMCExpr::MEK_None: |
654 | case MipsMCExpr::MEK_Special: |
655 | llvm_unreachable("Unhandled fixup kind!")::llvm::llvm_unreachable_internal("Unhandled fixup kind!", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 655); |
656 | break; |
657 | case MipsMCExpr::MEK_CALL_HI16: |
658 | FixupKind = Mips::fixup_Mips_CALL_HI16; |
659 | break; |
660 | case MipsMCExpr::MEK_CALL_LO16: |
661 | FixupKind = Mips::fixup_Mips_CALL_LO16; |
662 | break; |
663 | case MipsMCExpr::MEK_DTPREL_HI: |
664 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 |
665 | : Mips::fixup_Mips_DTPREL_HI; |
666 | break; |
667 | case MipsMCExpr::MEK_DTPREL_LO: |
668 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 |
669 | : Mips::fixup_Mips_DTPREL_LO; |
670 | break; |
671 | case MipsMCExpr::MEK_GOTTPREL: |
672 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOTTPREL |
673 | : Mips::fixup_Mips_GOTTPREL; |
674 | break; |
675 | case MipsMCExpr::MEK_GOT: |
676 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 |
677 | : Mips::fixup_Mips_GOT; |
678 | break; |
679 | case MipsMCExpr::MEK_GOT_CALL: |
680 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 |
681 | : Mips::fixup_Mips_CALL16; |
682 | break; |
683 | case MipsMCExpr::MEK_GOT_DISP: |
684 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP |
685 | : Mips::fixup_Mips_GOT_DISP; |
686 | break; |
687 | case MipsMCExpr::MEK_GOT_HI16: |
688 | FixupKind = Mips::fixup_Mips_GOT_HI16; |
689 | break; |
690 | case MipsMCExpr::MEK_GOT_LO16: |
691 | FixupKind = Mips::fixup_Mips_GOT_LO16; |
692 | break; |
693 | case MipsMCExpr::MEK_GOT_PAGE: |
694 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE |
695 | : Mips::fixup_Mips_GOT_PAGE; |
696 | break; |
697 | case MipsMCExpr::MEK_GOT_OFST: |
698 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST |
699 | : Mips::fixup_Mips_GOT_OFST; |
700 | break; |
701 | case MipsMCExpr::MEK_GPREL: |
702 | FixupKind = Mips::fixup_Mips_GPREL16; |
703 | break; |
704 | case MipsMCExpr::MEK_LO: |
705 | // Check for %lo(%neg(%gp_rel(X))) |
706 | if (MipsExpr->isGpOff()) { |
707 | FixupKind = Mips::fixup_Mips_GPOFF_LO; |
708 | break; |
709 | } |
710 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 |
711 | : Mips::fixup_Mips_LO16; |
712 | break; |
713 | case MipsMCExpr::MEK_HIGHEST: |
714 | FixupKind = Mips::fixup_Mips_HIGHEST; |
715 | break; |
716 | case MipsMCExpr::MEK_HIGHER: |
717 | FixupKind = Mips::fixup_Mips_HIGHER; |
718 | break; |
719 | case MipsMCExpr::MEK_HI: |
720 | // Check for %hi(%neg(%gp_rel(X))) |
721 | if (MipsExpr->isGpOff()) { |
722 | FixupKind = Mips::fixup_Mips_GPOFF_HI; |
723 | break; |
724 | } |
725 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 |
726 | : Mips::fixup_Mips_HI16; |
727 | break; |
728 | case MipsMCExpr::MEK_PCREL_HI16: |
729 | FixupKind = Mips::fixup_MIPS_PCHI16; |
730 | break; |
731 | case MipsMCExpr::MEK_PCREL_LO16: |
732 | FixupKind = Mips::fixup_MIPS_PCLO16; |
733 | break; |
734 | case MipsMCExpr::MEK_TLSGD: |
735 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD |
736 | : Mips::fixup_Mips_TLSGD; |
737 | break; |
738 | case MipsMCExpr::MEK_TLSLDM: |
739 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM |
740 | : Mips::fixup_Mips_TLSLDM; |
741 | break; |
742 | case MipsMCExpr::MEK_TPREL_HI: |
743 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 |
744 | : Mips::fixup_Mips_TPREL_HI; |
745 | break; |
746 | case MipsMCExpr::MEK_TPREL_LO: |
747 | FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 |
748 | : Mips::fixup_Mips_TPREL_LO; |
749 | break; |
750 | case MipsMCExpr::MEK_NEG: |
751 | FixupKind = |
752 | isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB; |
753 | break; |
754 | } |
755 | Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); |
756 | return 0; |
757 | } |
758 | |
759 | if (Kind == MCExpr::SymbolRef) { |
760 | Mips::Fixups FixupKind = Mips::Fixups(0); |
761 | |
762 | switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { |
763 | default: llvm_unreachable("Unknown fixup kind!")::llvm::llvm_unreachable_internal("Unknown fixup kind!", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 763); |
764 | break; |
765 | case MCSymbolRefExpr::VK_None: |
766 | FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. |
767 | break; |
768 | } // switch |
769 | |
770 | Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); |
771 | return 0; |
772 | } |
773 | return 0; |
774 | } |
775 | |
776 | /// getMachineOpValue - Return binary encoding of operand. If the machine |
777 | /// operand requires relocation, record the relocation and return zero. |
778 | unsigned MipsMCCodeEmitter:: |
779 | getMachineOpValue(const MCInst &MI, const MCOperand &MO, |
780 | SmallVectorImpl<MCFixup> &Fixups, |
781 | const MCSubtargetInfo &STI) const { |
782 | if (MO.isReg()) { |
783 | unsigned Reg = MO.getReg(); |
784 | unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); |
785 | return RegNo; |
786 | } else if (MO.isImm()) { |
787 | return static_cast<unsigned>(MO.getImm()); |
788 | } else if (MO.isFPImm()) { |
789 | return static_cast<unsigned>(APFloat(MO.getFPImm()) |
790 | .bitcastToAPInt().getHiBits(32).getLimitedValue()); |
791 | } |
792 | // MO must be an Expr. |
793 | assert(MO.isExpr())((MO.isExpr()) ? static_cast<void> (0) : __assert_fail ( "MO.isExpr()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 793, __PRETTY_FUNCTION__)); |
794 | return getExprOpValue(MO.getExpr(),Fixups, STI); |
795 | } |
796 | |
797 | /// Return binary encoding of memory related operand. |
798 | /// If the offset operand requires relocation, record the relocation. |
799 | template <unsigned ShiftAmount> |
800 | unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, |
801 | SmallVectorImpl<MCFixup> &Fixups, |
802 | const MCSubtargetInfo &STI) const { |
803 | // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. |
804 | assert(MI.getOperand(OpNo).isReg())((MI.getOperand(OpNo).isReg()) ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 804, __PRETTY_FUNCTION__)); |
805 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; |
806 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); |
807 | |
808 | // Apply the scale factor if there is one. |
809 | OffBits >>= ShiftAmount; |
810 | |
811 | return (OffBits & 0xFFFF) | RegBits; |
812 | } |
813 | |
814 | unsigned MipsMCCodeEmitter:: |
815 | getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, |
816 | SmallVectorImpl<MCFixup> &Fixups, |
817 | const MCSubtargetInfo &STI) const { |
818 | // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. |
819 | assert(MI.getOperand(OpNo).isReg())((MI.getOperand(OpNo).isReg()) ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 819, __PRETTY_FUNCTION__)); |
820 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), |
821 | Fixups, STI) << 4; |
822 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), |
823 | Fixups, STI); |
824 | |
825 | return (OffBits & 0xF) | RegBits; |
826 | } |
827 | |
828 | unsigned MipsMCCodeEmitter:: |
829 | getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, |
830 | SmallVectorImpl<MCFixup> &Fixups, |
831 | const MCSubtargetInfo &STI) const { |
832 | // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. |
833 | assert(MI.getOperand(OpNo).isReg())((MI.getOperand(OpNo).isReg()) ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 833, __PRETTY_FUNCTION__)); |
834 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), |
835 | Fixups, STI) << 4; |
836 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), |
837 | Fixups, STI) >> 1; |
838 | |
839 | return (OffBits & 0xF) | RegBits; |
840 | } |
841 | |
842 | unsigned MipsMCCodeEmitter:: |
843 | getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, |
844 | SmallVectorImpl<MCFixup> &Fixups, |
845 | const MCSubtargetInfo &STI) const { |
846 | // Base register is encoded in bits 6-4, offset is encoded in bits 3-0. |
847 | assert(MI.getOperand(OpNo).isReg())((MI.getOperand(OpNo).isReg()) ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 847, __PRETTY_FUNCTION__)); |
848 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), |
849 | Fixups, STI) << 4; |
850 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), |
851 | Fixups, STI) >> 2; |
852 | |
853 | return (OffBits & 0xF) | RegBits; |
854 | } |
855 | |
856 | unsigned MipsMCCodeEmitter:: |
857 | getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, |
858 | SmallVectorImpl<MCFixup> &Fixups, |
859 | const MCSubtargetInfo &STI) const { |
860 | // Register is encoded in bits 9-5, offset is encoded in bits 4-0. |
861 | assert(MI.getOperand(OpNo).isReg() &&((MI.getOperand(OpNo).isReg() && (MI.getOperand(OpNo) .getReg() == Mips::SP || MI.getOperand(OpNo).getReg() == Mips ::SP_64) && "Unexpected base register!") ? static_cast <void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg() && (MI.getOperand(OpNo).getReg() == Mips::SP || MI.getOperand(OpNo).getReg() == Mips::SP_64) && \"Unexpected base register!\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 864, __PRETTY_FUNCTION__)) |
862 | (MI.getOperand(OpNo).getReg() == Mips::SP ||((MI.getOperand(OpNo).isReg() && (MI.getOperand(OpNo) .getReg() == Mips::SP || MI.getOperand(OpNo).getReg() == Mips ::SP_64) && "Unexpected base register!") ? static_cast <void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg() && (MI.getOperand(OpNo).getReg() == Mips::SP || MI.getOperand(OpNo).getReg() == Mips::SP_64) && \"Unexpected base register!\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 864, __PRETTY_FUNCTION__)) |
863 | MI.getOperand(OpNo).getReg() == Mips::SP_64) &&((MI.getOperand(OpNo).isReg() && (MI.getOperand(OpNo) .getReg() == Mips::SP || MI.getOperand(OpNo).getReg() == Mips ::SP_64) && "Unexpected base register!") ? static_cast <void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg() && (MI.getOperand(OpNo).getReg() == Mips::SP || MI.getOperand(OpNo).getReg() == Mips::SP_64) && \"Unexpected base register!\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 864, __PRETTY_FUNCTION__)) |
864 | "Unexpected base register!")((MI.getOperand(OpNo).isReg() && (MI.getOperand(OpNo) .getReg() == Mips::SP || MI.getOperand(OpNo).getReg() == Mips ::SP_64) && "Unexpected base register!") ? static_cast <void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg() && (MI.getOperand(OpNo).getReg() == Mips::SP || MI.getOperand(OpNo).getReg() == Mips::SP_64) && \"Unexpected base register!\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 864, __PRETTY_FUNCTION__)); |
865 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), |
866 | Fixups, STI) >> 2; |
867 | |
868 | return OffBits & 0x1F; |
869 | } |
870 | |
871 | unsigned MipsMCCodeEmitter:: |
872 | getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, |
873 | SmallVectorImpl<MCFixup> &Fixups, |
874 | const MCSubtargetInfo &STI) const { |
875 | // Register is encoded in bits 9-7, offset is encoded in bits 6-0. |
876 | assert(MI.getOperand(OpNo).isReg() &&((MI.getOperand(OpNo).isReg() && MI.getOperand(OpNo). getReg() == Mips::GP && "Unexpected base register!") ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg() && MI.getOperand(OpNo).getReg() == Mips::GP && \"Unexpected base register!\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 878, __PRETTY_FUNCTION__)) |
877 | MI.getOperand(OpNo).getReg() == Mips::GP &&((MI.getOperand(OpNo).isReg() && MI.getOperand(OpNo). getReg() == Mips::GP && "Unexpected base register!") ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg() && MI.getOperand(OpNo).getReg() == Mips::GP && \"Unexpected base register!\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 878, __PRETTY_FUNCTION__)) |
878 | "Unexpected base register!")((MI.getOperand(OpNo).isReg() && MI.getOperand(OpNo). getReg() == Mips::GP && "Unexpected base register!") ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg() && MI.getOperand(OpNo).getReg() == Mips::GP && \"Unexpected base register!\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 878, __PRETTY_FUNCTION__)); |
879 | |
880 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), |
881 | Fixups, STI) >> 2; |
882 | |
883 | return OffBits & 0x7F; |
884 | } |
885 | |
886 | unsigned MipsMCCodeEmitter:: |
887 | getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, |
888 | SmallVectorImpl<MCFixup> &Fixups, |
889 | const MCSubtargetInfo &STI) const { |
890 | // Base register is encoded in bits 20-16, offset is encoded in bits 8-0. |
891 | assert(MI.getOperand(OpNo).isReg())((MI.getOperand(OpNo).isReg()) ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 891, __PRETTY_FUNCTION__)); |
892 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, |
893 | STI) << 16; |
894 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI); |
895 | |
896 | return (OffBits & 0x1FF) | RegBits; |
897 | } |
898 | |
899 | unsigned MipsMCCodeEmitter:: |
900 | getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo, |
901 | SmallVectorImpl<MCFixup> &Fixups, |
902 | const MCSubtargetInfo &STI) const { |
903 | // Base register is encoded in bits 20-16, offset is encoded in bits 10-0. |
904 | assert(MI.getOperand(OpNo).isReg())((MI.getOperand(OpNo).isReg()) ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 904, __PRETTY_FUNCTION__)); |
905 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, |
906 | STI) << 16; |
907 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); |
908 | |
909 | return (OffBits & 0x07FF) | RegBits; |
910 | } |
911 | |
912 | unsigned MipsMCCodeEmitter:: |
913 | getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, |
914 | SmallVectorImpl<MCFixup> &Fixups, |
915 | const MCSubtargetInfo &STI) const { |
916 | // opNum can be invalid if instruction had reglist as operand. |
917 | // MemOperand is always last operand of instruction (base + offset). |
918 | switch (MI.getOpcode()) { |
919 | default: |
920 | break; |
921 | case Mips::SWM32_MM: |
922 | case Mips::LWM32_MM: |
923 | OpNo = MI.getNumOperands() - 2; |
924 | break; |
925 | } |
926 | |
927 | // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. |
928 | assert(MI.getOperand(OpNo).isReg())((MI.getOperand(OpNo).isReg()) ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 928, __PRETTY_FUNCTION__)); |
929 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; |
930 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); |
931 | |
932 | return (OffBits & 0x0FFF) | RegBits; |
933 | } |
934 | |
935 | unsigned MipsMCCodeEmitter:: |
936 | getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, |
937 | SmallVectorImpl<MCFixup> &Fixups, |
938 | const MCSubtargetInfo &STI) const { |
939 | // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. |
940 | assert(MI.getOperand(OpNo).isReg())((MI.getOperand(OpNo).isReg()) ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 940, __PRETTY_FUNCTION__)); |
941 | unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, |
942 | STI) << 16; |
943 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); |
944 | |
945 | return (OffBits & 0xFFFF) | RegBits; |
946 | } |
947 | |
948 | unsigned MipsMCCodeEmitter:: |
949 | getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, |
950 | SmallVectorImpl<MCFixup> &Fixups, |
951 | const MCSubtargetInfo &STI) const { |
952 | // opNum can be invalid if instruction had reglist as operand |
953 | // MemOperand is always last operand of instruction (base + offset) |
954 | switch (MI.getOpcode()) { |
955 | default: |
956 | break; |
957 | case Mips::SWM16_MM: |
958 | case Mips::SWM16_MMR6: |
959 | case Mips::LWM16_MM: |
960 | case Mips::LWM16_MMR6: |
961 | OpNo = MI.getNumOperands() - 2; |
962 | break; |
963 | } |
964 | |
965 | // Offset is encoded in bits 4-0. |
966 | assert(MI.getOperand(OpNo).isReg())((MI.getOperand(OpNo).isReg()) ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isReg()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 966, __PRETTY_FUNCTION__)); |
967 | // Base register is always SP - thus it is not encoded. |
968 | assert(MI.getOperand(OpNo+1).isImm())((MI.getOperand(OpNo+1).isImm()) ? static_cast<void> (0 ) : __assert_fail ("MI.getOperand(OpNo+1).isImm()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 968, __PRETTY_FUNCTION__)); |
969 | unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); |
970 | |
971 | return ((OffBits >> 2) & 0x0F); |
972 | } |
973 | |
974 | // FIXME: should be called getMSBEncoding |
975 | // |
976 | unsigned |
977 | MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, |
978 | SmallVectorImpl<MCFixup> &Fixups, |
979 | const MCSubtargetInfo &STI) const { |
980 | assert(MI.getOperand(OpNo-1).isImm())((MI.getOperand(OpNo-1).isImm()) ? static_cast<void> (0 ) : __assert_fail ("MI.getOperand(OpNo-1).isImm()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 980, __PRETTY_FUNCTION__)); |
981 | assert(MI.getOperand(OpNo).isImm())((MI.getOperand(OpNo).isImm()) ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isImm()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 981, __PRETTY_FUNCTION__)); |
982 | unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); |
983 | unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); |
984 | |
985 | return Position + Size - 1; |
986 | } |
987 | |
988 | template <unsigned Bits, int Offset> |
989 | unsigned |
990 | MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, |
991 | SmallVectorImpl<MCFixup> &Fixups, |
992 | const MCSubtargetInfo &STI) const { |
993 | assert(MI.getOperand(OpNo).isImm())((MI.getOperand(OpNo).isImm()) ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isImm()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 993, __PRETTY_FUNCTION__)); |
994 | unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); |
995 | Value -= Offset; |
996 | return Value; |
997 | } |
998 | |
999 | unsigned |
1000 | MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, |
1001 | SmallVectorImpl<MCFixup> &Fixups, |
1002 | const MCSubtargetInfo &STI) const { |
1003 | const MCOperand &MO = MI.getOperand(OpNo); |
1004 | if (MO.isImm()) { |
1005 | // The immediate is encoded as 'immediate << 2'. |
1006 | unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); |
1007 | assert((Res & 3) == 0)(((Res & 3) == 0) ? static_cast<void> (0) : __assert_fail ("(Res & 3) == 0", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 1007, __PRETTY_FUNCTION__)); |
1008 | return Res >> 2; |
1009 | } |
1010 | |
1011 | assert(MO.isExpr() &&((MO.isExpr() && "getSimm19Lsl2Encoding expects only expressions or an immediate" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getSimm19Lsl2Encoding expects only expressions or an immediate\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 1012, __PRETTY_FUNCTION__)) |
1012 | "getSimm19Lsl2Encoding expects only expressions or an immediate")((MO.isExpr() && "getSimm19Lsl2Encoding expects only expressions or an immediate" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getSimm19Lsl2Encoding expects only expressions or an immediate\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 1012, __PRETTY_FUNCTION__)); |
1013 | |
1014 | const MCExpr *Expr = MO.getExpr(); |
1015 | Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2 |
1016 | : Mips::fixup_MIPS_PC19_S2; |
1017 | Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); |
1018 | return 0; |
1019 | } |
1020 | |
1021 | unsigned |
1022 | MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, |
1023 | SmallVectorImpl<MCFixup> &Fixups, |
1024 | const MCSubtargetInfo &STI) const { |
1025 | const MCOperand &MO = MI.getOperand(OpNo); |
1026 | if (MO.isImm()) { |
1027 | // The immediate is encoded as 'immediate << 3'. |
1028 | unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); |
1029 | assert((Res & 7) == 0)(((Res & 7) == 0) ? static_cast<void> (0) : __assert_fail ("(Res & 7) == 0", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 1029, __PRETTY_FUNCTION__)); |
1030 | return Res >> 3; |
1031 | } |
1032 | |
1033 | assert(MO.isExpr() &&((MO.isExpr() && "getSimm18Lsl2Encoding expects only expressions or an immediate" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getSimm18Lsl2Encoding expects only expressions or an immediate\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 1034, __PRETTY_FUNCTION__)) |
1034 | "getSimm18Lsl2Encoding expects only expressions or an immediate")((MO.isExpr() && "getSimm18Lsl2Encoding expects only expressions or an immediate" ) ? static_cast<void> (0) : __assert_fail ("MO.isExpr() && \"getSimm18Lsl2Encoding expects only expressions or an immediate\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 1034, __PRETTY_FUNCTION__)); |
1035 | |
1036 | const MCExpr *Expr = MO.getExpr(); |
1037 | Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3 |
1038 | : Mips::fixup_MIPS_PC18_S3; |
1039 | Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); |
1040 | return 0; |
1041 | } |
1042 | |
1043 | unsigned |
1044 | MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, |
1045 | SmallVectorImpl<MCFixup> &Fixups, |
1046 | const MCSubtargetInfo &STI) const { |
1047 | assert(MI.getOperand(OpNo).isImm())((MI.getOperand(OpNo).isImm()) ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isImm()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 1047, __PRETTY_FUNCTION__)); |
1048 | const MCOperand &MO = MI.getOperand(OpNo); |
1049 | return MO.getImm() % 8; |
1050 | } |
1051 | |
1052 | unsigned |
1053 | MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo, |
1054 | SmallVectorImpl<MCFixup> &Fixups, |
1055 | const MCSubtargetInfo &STI) const { |
1056 | assert(MI.getOperand(OpNo).isImm())((MI.getOperand(OpNo).isImm()) ? static_cast<void> (0) : __assert_fail ("MI.getOperand(OpNo).isImm()", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 1056, __PRETTY_FUNCTION__)); |
1057 | const MCOperand &MO = MI.getOperand(OpNo); |
1058 | unsigned Value = MO.getImm(); |
1059 | switch (Value) { |
1060 | case 128: return 0x0; |
1061 | case 1: return 0x1; |
1062 | case 2: return 0x2; |
1063 | case 3: return 0x3; |
1064 | case 4: return 0x4; |
1065 | case 7: return 0x5; |
1066 | case 8: return 0x6; |
1067 | case 15: return 0x7; |
1068 | case 16: return 0x8; |
1069 | case 31: return 0x9; |
1070 | case 32: return 0xa; |
1071 | case 63: return 0xb; |
1072 | case 64: return 0xc; |
1073 | case 255: return 0xd; |
1074 | case 32768: return 0xe; |
1075 | case 65535: return 0xf; |
1076 | } |
1077 | llvm_unreachable("Unexpected value")::llvm::llvm_unreachable_internal("Unexpected value", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 1077); |
1078 | } |
1079 | |
1080 | unsigned |
1081 | MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo, |
1082 | SmallVectorImpl<MCFixup> &Fixups, |
1083 | const MCSubtargetInfo &STI) const { |
1084 | unsigned res = 0; |
1085 | |
1086 | // Register list operand is always first operand of instruction and it is |
1087 | // placed before memory operand (register + imm). |
1088 | |
1089 | for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) { |
1090 | unsigned Reg = MI.getOperand(I).getReg(); |
1091 | unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); |
1092 | if (RegNo != 31) |
1093 | res++; |
1094 | else |
1095 | res |= 0x10; |
1096 | } |
1097 | return res; |
1098 | } |
1099 | |
1100 | unsigned |
1101 | MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, |
1102 | SmallVectorImpl<MCFixup> &Fixups, |
1103 | const MCSubtargetInfo &STI) const { |
1104 | return (MI.getNumOperands() - 4); |
1105 | } |
1106 | |
1107 | unsigned |
1108 | MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo, |
1109 | SmallVectorImpl<MCFixup> &Fixups, |
1110 | const MCSubtargetInfo &STI) const { |
1111 | return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); |
1112 | } |
1113 | |
1114 | unsigned |
1115 | MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, |
1116 | SmallVectorImpl<MCFixup> &Fixups, |
1117 | const MCSubtargetInfo &STI) const { |
1118 | unsigned res = 0; |
1119 | |
1120 | if (MI.getOperand(0).getReg() == Mips::A1 && |
1121 | MI.getOperand(1).getReg() == Mips::A2) |
1122 | res = 0; |
1123 | else if (MI.getOperand(0).getReg() == Mips::A1 && |
1124 | MI.getOperand(1).getReg() == Mips::A3) |
1125 | res = 1; |
1126 | else if (MI.getOperand(0).getReg() == Mips::A2 && |
1127 | MI.getOperand(1).getReg() == Mips::A3) |
1128 | res = 2; |
1129 | else if (MI.getOperand(0).getReg() == Mips::A0 && |
1130 | MI.getOperand(1).getReg() == Mips::S5) |
1131 | res = 3; |
1132 | else if (MI.getOperand(0).getReg() == Mips::A0 && |
1133 | MI.getOperand(1).getReg() == Mips::S6) |
1134 | res = 4; |
1135 | else if (MI.getOperand(0).getReg() == Mips::A0 && |
1136 | MI.getOperand(1).getReg() == Mips::A1) |
1137 | res = 5; |
1138 | else if (MI.getOperand(0).getReg() == Mips::A0 && |
1139 | MI.getOperand(1).getReg() == Mips::A2) |
1140 | res = 6; |
1141 | else if (MI.getOperand(0).getReg() == Mips::A0 && |
1142 | MI.getOperand(1).getReg() == Mips::A3) |
1143 | res = 7; |
1144 | |
1145 | return res; |
1146 | } |
1147 | |
1148 | unsigned |
1149 | MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, |
1150 | SmallVectorImpl<MCFixup> &Fixups, |
1151 | const MCSubtargetInfo &STI) const { |
1152 | const MCOperand &MO = MI.getOperand(OpNo); |
1153 | assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate")((MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate" ) ? static_cast<void> (0) : __assert_fail ("MO.isImm() && \"getSimm23Lsl2Encoding expects only an immediate\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 1153, __PRETTY_FUNCTION__)); |
1154 | // The immediate is encoded as 'immediate >> 2'. |
1155 | unsigned Res = static_cast<unsigned>(MO.getImm()); |
1156 | assert((Res & 3) == 0)(((Res & 3) == 0) ? static_cast<void> (0) : __assert_fail ("(Res & 3) == 0", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn306458/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp" , 1156, __PRETTY_FUNCTION__)); |
1157 | return Res >> 2; |
1158 | } |
1159 | |
1160 | #include "MipsGenMCCodeEmitter.inc" |